Skip to content

Demos

Spacing method #1

Space component. The RedBox is only to visualize the result.

<RedBox>
  <Space top="large x-small">
    <Input label="Input" />
  </Space>
</RedBox>

Spacing method #2

Define the space directly.

<Input label="Input A" bottom="small" />
<Input label="Input B" />

Spacing method #3

Using the useSpacing hook.

Space A
Space B
Inner Space
Has space when breakpoint is large
const Component = ({ className = null, style = null, ...props }) => {
  const params = useSpacing(props, {
    ...props,
    className: `my-component dnb-space ${className || ''}`.trim(),
    style,
  })
  return <div {...params} />
}
render(
  <>
    <RedBox>
      <Component top="small medium large">Space A</Component>
    </RedBox>
    <RedBox>
      <Component top>Space B</Component>
    </RedBox>
    <RedBox>
      <Component innerSpace="large">Inner Space</Component>
    </RedBox>
    <RedBox>
      <Component
        innerSpace={{
          large: true,
        }}
      >
        Has space when breakpoint is large
      </Component>
    </RedBox>
  </>
)

Responsive space

The space property supports media query breakpoints (small, medium, large) for responsive spacing. Provide an object with breakpoint keys to apply different values at each screen size.

Content

<RedBox>
  <Space
    space={{
      small: 'large x-small',
      medium: {
        top: '2rem',
        left: '16px',
        bottom: 'large',
        right: '5rem',
      },
      large: true,
    }}
  >
    <P>Content</P>
  </Space>
</RedBox>

Responsive innerSpace

The innerSpace property controls padding inside the Space component. It shares the same API as space.

Content

<RedBox>
  <Space
    innerSpace={{
      small: 'large x-small',
      medium: true,
      large: {
        top: '2rem',
        left: '16px',
        bottom: 'large',
        right: '5rem',
      },
    }}
  >
    <P>Content</P>
  </Space>
</RedBox>

inline and block shorthand

Both space and innerSpace properties support inline and block shorthand properties for more semantic spacing control.

  • inline applies spacing to left and right (horizontal)
  • block applies spacing to top and bottom (vertical)
space: inline=small (left/right), block=large (top/bottom)
innerSpace: inline=medium (left/right), block=x-small (top/bottom)
Combined: space block=large + innerSpace inline=medium, block=small
Responsive inline/block for both space and innerSpace
Different combinations per breakpoint
Mixed: space inline + top override, innerSpace block
{/* Basic inline/block usage for space (margin) */}
<Space
  space={{
    inline: 'small',
    block: 'large',
  }}
>
  <RedBox>
    space: inline=small (left/right), block=large (top/bottom)
  </RedBox>
</Space>
{/* Basic inline/block usage for innerSpace (padding) */}
<Space
  innerSpace={{
    inline: 'medium',
    block: 'x-small',
  }}
>
  <RedBox>
    innerSpace: inline=medium (left/right), block=x-small (top/bottom)
  </RedBox>
</Space>
{/* Combining both space and innerSpace with inline/block */}
<Space
  space={{
    block: 'large',
  }}
  innerSpace={{
    inline: 'medium',
    block: 'small',
  }}
>
  <RedBox>
    Combined: space block=large + innerSpace inline=medium, block=small
  </RedBox>
</Space>
{/* Media queries with inline/block for both properties */}
<Space
  space={{
    small: {
      inline: 'x-small',
    },
    medium: {
      block: 'medium',
    },
    large: {
      inline: 'large',
      block: 'small',
    },
  }}
  innerSpace={{
    small: {
      block: 'x-small',
    },
    medium: {
      inline: 'small',
    },
    large: {
      inline: 'medium',
      block: 'large',
    },
  }}
>
  <RedBox>
    <div>Responsive inline/block for both space and innerSpace</div>
    <div>Different combinations per breakpoint</div>
  </RedBox>
</Space>
{/* Mixing inline/block with traditional directional props */}
<Space
  space={{
    inline: 'small',
  }}
  top="x-large"
  innerSpace={{
    block: 'medium',
  }}
>
  <RedBox>Mixed: space inline + top override, innerSpace block</RedBox>
</Space>

Responsive layout gap

NB: This feature is in beta and may be subject to change.

Use Space.ResponsiveContext to preview responsive spacing in practice. The default basis density follows viewport breakpoints.

See the responsive spacing table for the specific values.

In this example, gap and space values adjust automatically based on the viewport size (applies also to inline, block, top, right, bottom, and left).

Heading

My spacing adjusts responsively

My spacing stays fixed

<Space.ResponsiveContext>
  <Section
    innerSpace={{
      block: 'medium',
    }}
    breakout={false}
    surface="dark"
  >
    <Flex.Stack
      space={{
        inline: 'large',
      }}
      gap="small"
    >
      <Heading size="x-large">Heading</Heading>
      <P>My spacing adjusts responsively</P>

      <Space.ResponsiveContext off>
        <P>My spacing stays fixed</P>
      </Space.ResponsiveContext>
    </Flex.Stack>
  </Section>
</Space.ResponsiveContext>

Spacing with no margin collapse, due to the flex usage

I have bottom="small"
I have top="large"

All four values will result in an equivalent margin

I have four 2.5rem margins!And this are my CSS classes: dnb-space dnb-space__top--large dnb-space__top--x-small dnb-space__right--large dnb-space__right--x-small dnb-space__bottom--large dnb-space__bottom--x-small dnb-space__left--large dnb-space__left--x-small

Visual space testing

With dnb-core-style

Without