Description
The Space component provides margins
within the provided spacing patterns.
The reason why this exists is to make your syntax as clean as possible. This way you see directly in words what the spacing is for every affected component
Spacing Table
Pixel | Type | Rem | Custom Property |
---|---|---|---|
8 | x-small | 0.5 | --spacing-x-small |
16 | small | 1 | --spacing-small |
24 | medium | 1.5 | --spacing-medium |
32 | large | 2 | --spacing-large |
48 | x-large | 3 | --spacing-x-large |
56 | xx-large | 3.5 | --spacing-xx-large |
NB: In some circumstances you may be in need of using 0.25rem (4px) - therefore xx-small
also exists, but as a single type. So, combining xx-small
and small
would not result in 0.25rem, but still remain 1rem.
Value Format
There are a couple of different ways you can define the spacing types and values:
- Types:
small small x-small
(combine types up to 10rem) - number:
2.5
(equivalent torem
) - string(rem):
2.5rem
- string(px):
40px
(gets converted torem
) - boolean:
true
(equivalent tosmall
),false
(equivalent tozero
)
To get a spacing of e.g. 2.5rem (40px)- you may combine types large
and x-small
.
{/* All of these methods will result in the same spacing */} <Space top="large x-small" right="2.5" bottom="2.5rem" left="40px" />
With React, you can also use an object with the different directions:
{/* All of these methods will result in the same spacing */} <Space space={{ top: 'large x-small', right: '2.5', bottom: '2.5rem', left: '40px', }} />
Components and Spacing
Every component supports the spacing patterns, so it's possible to send in the top
, right
, bottom
, left
and space
properties directly, like:
<Button top="large x-small medium" /> <Button space={{ top: 'large x-small medium', }} />
Spacing shorthands
A shorthand for getting 1rem (most used) is to simply send in a boolean, set as true. No given value in JSX means true, so you only need the property key:
{/* Equivalent to top="small" */} <Button top /> {/* Equivalent to top="small" right="small" bottom="small" left="small" */} <Button space />
In order to set all four directions at once, you can provide a string as the space
value:
<Button space="large x-small medium" />
Does it not work as expected?
Is margin
not giving the expected spacing? That may be the reason due to Margin Collapsing. Margins collapse in the following situations:
- Adjacent siblings
- Completely empty boxes
- Parent and first or last child element
The best solution is to only use one direction of margins e.g. bottom
. Or you can set the collapse property to false
.
Margin collapsing
In order to help out to handle unwanted margin collapsing in typography elements, se this example
Conditional Rest
For resetting spacing (margin: 0
) only when no spacing is defined, you can make use of dnb-space__reset
.
The following example will result in margin: 0.5rem 0 0 0
:
<ul class="my-list dnb-space__reset dnb-space__top--small"><!-- some content --></ul>
More details:
- Because of the browser default styles, our list has some margin.
- If we would want to "reset" these styles to a margin of 0 directly on
.my-list
, we would not be able to usednb-space__top--small
because of the CSS specificity is lower.
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" right="small" /> <Input label="Input B" />
Spacing method #3
Using createSpacingClasses
or createSpacingProperties
.
const Component = ({ className = null, style = null, ...props }) => { const spacingClasses = createSpacingClasses(props) const spacingProperties = createSpacingProperties(props) const cn = classnames( 'my-component', 'dnb-space', spacingClasses, className, ) const st = { ...style, ...spacingProperties, } return <div className={cn} style={st} {...removeSpaceProps(props)} /> } 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> </>, )
innerSpace
Responsive For "padding" inside the space component, you can use the property innerSpace
.
It supports the same API as the space
prop.
But in addition it supports media query breakpoints, such as small
, medium
and large
.
Content
<RedBox> <Space innerSpace={{ small: 'large x-small', medium: true, large: { top: '2rem', left: '16px', bottom: 'large', right: '5rem', }, }} > <P>Content</P> </Space> </RedBox>
Spacing with no margin collapse, due to the flex usage
bottom="small"
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