Skip to content
Autumn 2026 Mesh Release and Design Tokens v2 now available! Read the announcement

Spacing

Mesh uses a tokenised 10-step spacing scale to create a consistent visual rhythm across products, pages and experiences. The scale is integrated deeply in our layout, content and interactive components, and offers a number of spacing "modes" to suit different visual densities in various contexts.

Overview

To maintain visual consistency across Mesh experiences, every padding, margin and gap should come from the same shared scale. This ensures interfaces feel predictable, cohesive and easier to maintain.

To achieve this, we encourage use of Layout Components first and foremost, then application of density (spacing) modes deliberately, to avoid the need for one-off spacing values.

Our approach to spacing

  • Use the Mesh spacing scale for all spacing decisions, rather than one-off custom values.
  • Prefer Stack and Inline over manual sibling margins.
  • Choose density at the product or section level, then let components inherit it.
  • Use smaller steps inside components and larger steps between sections.
  • Reach for Box props, mixins or tokens only when layout components are not enough.

All spacing across Mesh is based on a 10-step scale. The values are common across all brands, sourced from design tokens and defined in rem.

Different spacing scales

Use default for most interfaces. compact and condensed suit dense UIs, while relaxed and spacious create more breathing room. Set density at the top level with the space prop on ModeProvider, or scope it to a section with data-space.

The table below shows the equivalent pixel values with a root font size of 16px.

012345678910
compact0px2px4px6px8px12px16px24px32px48px64px
condensed0px3px6px9px12px18px24px36px48px72px96px
default0px4px8px12px16px24px32px48px64px96px128px
relaxed0px5px10px15px20px30px40px60px80px120px160px
spacious0px6px12px18px24px36px48px72px96px144px192px
Choose scale

Default spacing scale

Lorem ipsum dolor sit amet consectetur adipiscing elit. Nulla porta, eros nec convallis commodo, tellus nunc gravida tortor, vitae laoreet felis ligula sed lectus. Vestibulum et feugiat lorem. Donec fermentum accumsan lacinia.

Sed porttitor auctor ipsum eu sodales. Ut at efficitur dolor. Sed orci justo, aliquam sit amet viverra a, placerat ac mauris. Quisque convallis nisl at purus auctor, euismod vehicula ante elementum. Duis pretium magna nec odio hendrerit, non consequat enim iaculis. Fusce quis augue velit. Nullam aliquet libero libero, vitae rhoncus mi sagittis eu. Cras laoreet pellentesque pulvinar.

Etiam pulvinar urna et odio sollicitudin, ac condimentum sem ornare. Sed nibh nunc, aliquet quis eros ac, aliquam tempus ex. Cras non elit tortor. Integer vel massa in leo interdum posuere at non nisl. Fusce tristique lacinia sollicitudin. Nunc sed vehicula lectus, sit amet posuere est. Maecenas turpis nunc, vulputate eu magna et, aliquam mollis nunc. Aenean elementum posuere felis, sit amet congue magna egestas id. Nulla porta, eros nec convallis commodo, tellus nunc gravida tortor, vitae laoreet felis ligula sed lectus. Vestibulum et feugiat lorem. Donec fermentum accumsan lacinia.

Changing the spacing scale does not change the typography scale

The spacing scale is separate from the typography scale used for font sizes and line heights.

At the most compact and spacious extremes, that fixed typography scale may not always feel perfectly balanced. If that is affecting your product, please raise an issue with the design system team.

Which spacing scale should I use?

  • Use default for most products and flows.
  • Use compact or condensed when people need to scan dense information quickly, such as tables or admin-style interfaces.
  • Use relaxed or spacious when you want more breathing room, such as marketing surfaces, guided forms or content-heavy layouts.

You can combine scales in the same app, but do so deliberately. In most cases, density should be a product-level or section-level decision.

jsx
<ModeProvider space="relaxed">
<Box>
<Copy>Relaxed spacing scale</Copy>
<aside data-space="compact">
<Copy>Compact spacing scale</Copy>
</aside>
</Box>
</ModeProvider>

Choosing a spacing step

  • 1-3: tight spacing within small controls or compact UI
  • 4-6: standard spacing within most components and between closely related elements
  • 7-8: separation between distinct groups or sections within a view
  • 9-10: major layout separation used sparingly

Using the spacing scale

  1. Layout components for spacing between elements
  2. Box spacing props for padding and margin on a container
  3. Mixins, space() or tokens for advanced layouts or custom styling needs

Layout components

Layout components are the preferred way to manage spacing between elements. For more detail, see our Layout docs.

Stack and Inline components

Stack and Inline provide consistent space between direct children and cover most common layout needs.

jsx
<Stack space={{xs: 4, md: 6}}>
  <div>
    <Stack space={2}>
      <Heading size={3}>Heading</Heading>
      <Copy>Lorem ipsum dolor sit amet.</Copy>
    </Stack>
  </div>
  <Divider />
  <div>
    <Inline space={4}>
      <SmallPlaceholder>Item 1</SmallPlaceholder>
      <SmallPlaceholder>Item 2</SmallPlaceholder>
    </Inline>
  </div>
</Stack>

Box component

Use Box when you need padding or margin on a container. Spacing between siblings is usually better handled by layout components.

jsx
<>
  <Box prominence="gentle" background="default" display="inline-block" padding={8} marginRight={4}>
    Box 1
  </Box>
  <Box prominence="gentle" background="default" display="inline-block" paddingVertical={6}>
    Box 2
  </Box>
</>

Mixins

Use mixins when you need more intricate control or are styling outside the standard component APIs.

Padding mixins

jsx
import {p, pt, pr, pb, pl, px, py, pbs, pie, pbe, pis, pbl, pi} from '@nib-group/mesh-layout';
const Example1 = styled.div`
${p(4)}; /* Padding on all sides */
`;
const Example2 = styled.div`
${pt(1)}; /* Padding top */
${pr(6)}; /* Padding right */
${pb(3)}; /* Padding bottom */
${pl(5)}; /* Padding left */
`;
const Example3 = styled.div`
${px(6)}; /* Padding left and right */
${py(4)}; /* Padding top and bottom */
`;
const Example4 = styled.div`
${pbl(6)}; /* Padding block start and end */
${pi(4)}; /* Padding inline start and end */
`;
const Example5 = styled.div`
${pbs(1)}; /* Padding block start */
${pie(6)}; /* Padding inline end */
${pbe(3)}; /* Padding block end */
${pis(5)}; /* Padding inline start */
`;

Margin mixins

jsx
import {m, mt, mr, mb, ml, mx, my, mbs, mie, mbe, mis, mbl, mi} from '@nib-group/mesh-layout';
const Example1 = styled.div`
${m(4)}; /* Margin on all sides */
`;
const Example2 = styled.div`
${mt(1)}; /* Margin top */
${mr(6)}; /* Margin right */
${mb(3)}; /* Margin bottom */
${ml(5)}; /* Margin left */
`;
const Example3 = styled.div`
${mx(6)}; /* Margin left and right */
${my(4)}; /* Margin top and bottom */
`;
const Example4 = styled.div`
${mbs(1)}; /* Margin block start */
${mie(6)}; /* Margin inline end */
${mbe(3)}; /* Margin block end */
${mis(5)}; /* Margin inline start */
`;
const Example5 = styled.div`
${mbl(6)}; /* Margin block start and end */
${mi(4)}; /* Margin inline start and end */
`;

Space mixin

Use space() for advanced layout needs such as CSS Grid gaps or absolute positioning offsets.

jsx
import {space} from '@nib-group/mesh-layout';
const Example1 = styled.div`
display: grid;
grid-template-columns: 1fr 2fr 1fr;
gap: ${space(5)};
`;
const Example2 = styled.div`
position: absolute;
top: ${space(6)};
left: ${space(6)};
`;

token function and CSS variables

Since v7.0.0 of the theme, spacing values are sourced from design tokens. You can access them through the token function or raw CSS variables.

jsx
import {token} from '@nib-group/mesh-theme';
const Example1 = styled.div`
/* These two lines are equivalent */
padding: ${token('common.dimension.spacing.4')};
padding: var(--commonDimensionSpacing4);
`;

What to avoid

Avoid these common spacing pitfalls:

  • using arbitrary pixel values when a scale step would work
  • manually adding sibling margins when a layout component expresses the relationship more clearly
  • mixing density scales in an unstructured way
  • using very large spacing steps repeatedly when a clearer layout structure would solve the problem better

Logical Properties

Logical properties are more flexible and internationalisation-friendly than physical properties such as margin-top or padding-left.

Along with the existing options for margin and padding, we have added mixins and props to Box that are explicitly logical:

  • Mixins: mbs, mie, mbe, mis, mbl, mi, pbs, pie, pbe, pis, pbl and pi
  • Props: marginBlockStart, marginInlineEnd, marginBlockEnd, marginInlineStart, marginBlock, marginInline, paddingBlockStart, paddingInlineEnd, paddingBlockEnd, paddingInlineStart, paddingBlock and paddingInline

Since theme v7, the existing mixins and spacing props already use logical property equivalents under the hood. Prefer the explicit logical versions where possible.