Layout

The guiding principle for layout in Braid is that components should not provide surrounding white space. Instead, spacing between elements is owned entirely by layout components. This approach ensures that the system is as composable as possible while keeping white space completely predictable.
All of the components referenced below can be infinitely nested within each other to create a wide variety of standard layouts. Getting a firm grasp of these components is an essential part of working effectively with Braid.

Spacing #

Braid provides a standard white space scale that is available across the entire component suite. As much as possible, Braid tries to make use of this scale rather than generating custom spacing rules.
none
gutter
xxsmall
xsmall
small
medium
large
xlarge
xxlarge

Box #

‘Box’ is the most low-level layout component provided by Braid. Its job is to render an individual element on the screen.
In terms of page layout, ‘Box’ most notably provides a set of padding options which can be used to create container elements with internal spacing.
  • padding
  • paddingX
  • paddingY
  • paddingTop
  • paddingBottom
  • paddingLeft
  • paddingRight
These options accept a value from our white space scale.
For example, if you wanted to create a container element with small spacing on all sides:
Lorem ipsum dolor sit amet.
<Box padding="small">
  <Text>Lorem ipsum dolor sit amet.</Text>
</Box>
These also support the ‘responsive props’ format which allows you to specify an array of values for different screen sizes.
For example, if you wanted small spacing on mobile but medium spacing from tablet upwards:
Lorem ipsum dolor sit amet.
<Box padding={["small", "medium"]}>
  <Text>Lorem ipsum dolor sit amet.</Text>
</Box>
If required, you’re also able to specify a different value for desktop screens.
For example, if you wanted to set the previous example’s spacing to large on desktop:
Lorem ipsum dolor sit amet.
<Box padding={["small", "medium", "large"]}>
  <Text>Lorem ipsum dolor sit amet.</Text>
</Box>

Card #

Rather than nesting content in arbitrary ‘Box’ elements, you may prefer to use standard ‘Card’ elements instead.
Lorem ipsum dolor sit amet.
<Card>
  <Text>Lorem ipsum dolor sit amet.</Text>
</Card>

Stack #

The most common white space on screen is between elements stacked vertically. For this use case, Braid provides a ‘Stack’ component that accepts a ‘space’ prop.
For example, if you wanted to render a stack of ‘Heading’ and ‘Text’ elements with large spacing between them:

Heading

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse dignissim dapibus elit, vel egestas felis pharetra non. Cras malesuada, massa nec ultricies efficitur, lectus ante consequat magna, a porttitor massa ex ut quam.
Phasellus ipsum tortor, aliquet dapibus fermentum in, mollis vel metus. Vestibulum malesuada ante eu velit malesuada, nec ultricies sapien finibus. Aenean rutrum in sem a ullamcorper. Integer ut euismod urna. Interdum et malesuada fames ac ante ipsum primis in faucibus.
<Card>
  <Stack space="large">
    <Heading level="3">Heading</Heading>
    <Text>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse
      dignissim dapibus elit, vel egestas felis pharetra non. Cras malesuada,
      massa nec ultricies efficitur, lectus ante consequat magna, a porttitor
      massa ex ut quam.
    </Text>
    <Text>
      Phasellus ipsum tortor, aliquet dapibus fermentum in, mollis vel metus.
      Vestibulum malesuada ante eu velit malesuada, nec ultricies sapien
      finibus. Aenean rutrum in sem a ullamcorper. Integer ut euismod urna.
      Interdum et malesuada fames ac ante ipsum primis in faucibus.
    </Text>
  </Stack>
</Card>
Just like ‘Box’, you can also specify different spacing values for different screen sizes:

Heading

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse dignissim dapibus elit, vel egestas felis pharetra non. Cras malesuada, massa nec ultricies efficitur, lectus ante consequat magna, a porttitor massa ex ut quam.
Phasellus ipsum tortor, aliquet dapibus fermentum in, mollis vel metus. Vestibulum malesuada ante eu velit malesuada, nec ultricies sapien finibus. Aenean rutrum in sem a ullamcorper. Integer ut euismod urna. Interdum et malesuada fames ac ante ipsum primis in faucibus.
<Card>
  <Stack space={["medium", "large"]}>
    <Heading level="3">Heading</Heading>
    <Text>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse
      dignissim dapibus elit, vel egestas felis pharetra non. Cras malesuada,
      massa nec ultricies efficitur, lectus ante consequat magna, a porttitor
      massa ex ut quam.
    </Text>
    <Text>
      Phasellus ipsum tortor, aliquet dapibus fermentum in, mollis vel metus.
      Vestibulum malesuada ante eu velit malesuada, nec ultricies sapien
      finibus. Aenean rutrum in sem a ullamcorper. Integer ut euismod urna.
      Interdum et malesuada fames ac ante ipsum primis in faucibus.
    </Text>
  </Stack>
</Card>
To visually break up content, you can insert dividers between all stack elements by setting the ‘dividers’ prop on Stack:

Heading

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse dignissim dapibus elit, vel egestas felis pharetra non. Cras malesuada, massa nec ultricies efficitur, lectus ante consequat magna, a porttitor massa ex ut quam.
Phasellus ipsum tortor, aliquet dapibus fermentum in, mollis vel metus. Vestibulum malesuada ante eu velit malesuada, nec ultricies sapien finibus. Aenean rutrum in sem a ullamcorper. Integer ut euismod urna. Interdum et malesuada fames ac ante ipsum primis in faucibus.
<Card>
  <Stack dividers={true} space="gutter">
    <Heading level="3">Heading</Heading>
    <Text>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse
      dignissim dapibus elit, vel egestas felis pharetra non. Cras malesuada,
      massa nec ultricies efficitur, lectus ante consequat magna, a porttitor
      massa ex ut quam.
    </Text>
    <Text>
      Phasellus ipsum tortor, aliquet dapibus fermentum in, mollis vel metus.
      Vestibulum malesuada ante eu velit malesuada, nec ultricies sapien
      finibus. Aenean rutrum in sem a ullamcorper. Integer ut euismod urna.
      Interdum et malesuada fames ac ante ipsum primis in faucibus.
    </Text>
  </Stack>
</Card>
If you’d prefer to take control over the placement of dividers, you can use the ‘Divider’ component directly:

Heading

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse dignissim dapibus elit, vel egestas felis pharetra non. Cras malesuada, massa nec ultricies efficitur, lectus ante consequat magna, a porttitor massa ex ut quam.
Phasellus ipsum tortor, aliquet dapibus fermentum in, mollis vel metus. Vestibulum malesuada ante eu velit malesuada, nec ultricies sapien finibus. Aenean rutrum in sem a ullamcorper. Integer ut euismod urna. Interdum et malesuada fames ac ante ipsum primis in faucibus.
<Card>
  <Stack space="gutter">
    <Heading level="3">Heading</Heading>
    <Text>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse
      dignissim dapibus elit, vel egestas felis pharetra non. Cras malesuada,
      massa nec ultricies efficitur, lectus ante consequat magna, a porttitor
      massa ex ut quam.
    </Text>
    <Divider />
    <Text>
      Phasellus ipsum tortor, aliquet dapibus fermentum in, mollis vel metus.
      Vestibulum malesuada ante eu velit malesuada, nec ultricies sapien
      finibus. Aenean rutrum in sem a ullamcorper. Integer ut euismod urna.
      Interdum et malesuada fames ac ante ipsum primis in faucibus.
    </Text>
  </Stack>
</Card>
Multiple ‘Stack’ components can be nested to create more complex white space rules. For example, if you wanted to create multiple grouped blocks of text like you might see on a job summary card:

Heading

Line 1
Line 2
Line 3
Line 1
Line 2
Line 3
<Card>
  <Stack space="gutter">
    <Heading level="4">Heading</Heading>
    <Stack space="small">
      <Text>Line 1</Text>
      <Text>Line 2</Text>
      <Text>Line 3</Text>
    </Stack>
    <Stack space="small">
      <Text>Line 1</Text>
      <Text>Line 2</Text>
      <Text>Line 3</Text>
    </Stack>
  </Stack>
</Card>
‘Stack’ also supports horizontal alignment. For example, if you wanted to centre align all content within a card:
Badge

Heading Text

Lorem ipsum dolor sit amet.
<Card>
  <Stack align="center" space="medium">
    <IconPromote tone="promote" />
    <Badge tone="promote">Badge</Badge>
    <Heading align="center" level="4">
      Heading Text
    </Heading>
    <Text align="center" tone="secondary">
      Lorem ipsum dolor sit amet.
    </Text>
  </Stack>
</Card>
Individual stack items can be hidden on different screen sizes by wrapping them with the Hidden component. For example, if you wanted to hide the second item in a stack on mobile:
Item 1
Item 2
Item 3
<Card>
  <Stack align="center" space="medium">
    <Text>Item 1</Text>
    <Hidden below="tablet">
      <Text>Item 2</Text>
    </Hidden>
    <Text>Item 3</Text>
  </Stack>
</Card>

Inline #

If you’d like to render a set of components in a row with equal spacing around them, wrapping onto multiple lines when necessary, Braid provides an ‘Inline’ component:
Lorem ipsum
Dolor
Sit amet
Consectetur
Adipiscing elit
Suspendisse dignissim
Dapibus elit
Vel egestas felis
Pharetra non
<Card>
  <Inline space="small">
    <Badge>Lorem ipsum</Badge>
    <Badge>Dolor</Badge>
    <Badge>Sit amet</Badge>
    <Badge>Consectetur</Badge>
    <Badge>Adipiscing elit</Badge>
    <Badge>Suspendisse dignissim</Badge>
    <Badge>Dapibus elit</Badge>
    <Badge>Vel egestas felis</Badge>
    <Badge>Pharetra non</Badge>
  </Inline>
</Card>
Similar to ‘Stack’, ‘Inline’ also supports horizontal alignment of its children:
Lorem ipsum
Dolor
Sit amet
<Card>
  <Inline align="center" space="small">
    <Badge>Lorem ipsum</Badge>
    <Badge>Dolor</Badge>
    <Badge>Sit amet</Badge>
  </Inline>
</Card>
If you’d like the columns to stack vertically on smaller screens, you can provide the ‘collapseBelow’ prop.
For example, if you wanted buttons to be rendered vertically on mobile but horizontally from tablet upwards:
<Card>
  <Inline collapseBelow="tablet" space="small">
    <Button>Submit</Button>
    <Button weight="weak">Cancel</Button>
  </Inline>
</Card>

Columns #

If you need to lay out content horizontally, Braid provides the ‘Columns’ and ‘Column’ components:
Column 1
Column 2
<Columns space="small">
  <Column>
    <Card>
      <Text>Column 1</Text>
    </Card>
  </Column>
  <Column>
    <Card>
      <Text>Column 2</Text>
    </Card>
  </Column>
</Columns>
Similar to ‘Inline’, if you’d like the columns to stack vertically on smaller screens, you can provide the ‘collapseBelow’ prop.
For example, if you wanted cards to be rendered vertically on mobile but horizontally from tablet upwards:
Column 1
Column 2
<Columns collapseBelow="tablet" space="small">
  <Column>
    <Card>
      <Text>Column 1</Text>
    </Card>
  </Column>
  <Column>
    <Card>
      <Text>Column 2</Text>
    </Card>
  </Column>
</Columns>
All columns are of equal width by default, but you can also customise the width of each column individually.
For example, if you wanted to render a main content area and a sidebar, collapsing to a single column on mobile:
Sidebar
Main content
<Columns collapseBelow="tablet" space="small">
  <Column width="1/3">
    <Card>
      <Text>Sidebar</Text>
    </Card>
  </Column>
  <Column>
    <Card>
      <Text>Main content</Text>
    </Card>
  </Column>
</Columns>
If you want a column to be as small as possible, you can also set its width to ‘content’ which ensures that it’s only as wide as the content within it.
For example, if you wanted a card with a left-aligned ‘Heading’ and a right-aligned ‘OverflowMenu’:

Card heading

Card content
<Card>
  <Stack space="medium">
    <Columns space="small">
      <Column>
        <Heading level="3">Card heading</Heading>
      </Column>
      <Column width="content">
        <OverflowMenu label="Options">
          <MenuItem onClick={function noRefCheck() {}}>First</MenuItem>
          <MenuItem onClick={function noRefCheck() {}}>Second</MenuItem>
        </OverflowMenu>
      </Column>
    </Columns>
    <Text>Card content</Text>
  </Stack>
</Card>
By default, columns are rendered in document order, which also doubles as the screen reader order. If you need the columns to be visually reversed on larger screens, you can provide the ‘reverse’ option:
Sidebar
Main content
<Columns collapseBelow="tablet" reverse={true} space="small">
  <Column width="1/3">
    <Card>
      <Text>Sidebar</Text>
    </Card>
  </Column>
  <Column>
    <Card>
      <Text>Main content</Text>
    </Card>
  </Column>
</Columns>
If you have ‘Column’ elements that are of varying height, you can center them vertically with the ‘alignY’ prop:
Column
Column
Column
Column
Column
Column
Column
Column
<Columns alignY="center" space="small">
  <Column>
    <Card>
      <Stack align="center" space="medium">
        <Text>Column</Text>
        <Text>Column</Text>
      </Stack>
    </Card>
  </Column>
  <Column>
    <Card>
      <Stack align="center" space="medium">
        <Text>Column</Text>
        <Text>Column</Text>
        <Text>Column</Text>
        <Text>Column</Text>
      </Stack>
    </Card>
  </Column>
  <Column>
    <Card>
      <Stack align="center" space="medium">
        <Text>Column</Text>
        <Text>Column</Text>
      </Stack>
    </Card>
  </Column>
</Columns>

Tiles #

If you’d like to render a grid of components with equal spacing between them, Braid provides a ‘Tiles’ component:
Tile
Tile
Tile
Tile
Tile
Tile
Tile
Tile
Tile
<Tiles columns={3} space="small">
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
</Tiles>
If you need to customise the spacing and number of columns per screen size, the ‘columns’ prop is responsive. For example, if you wanted a single column on mobile and three columns from tablet upwards:
Tile
Tile
Tile
Tile
Tile
Tile
Tile
Tile
Tile
<Tiles columns={[1, 3]} space={["xsmall", "small"]}>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
</Tiles>
When the tiles are collapsed to a single column, you can optionally show dividers between them with the ‘dividers’ prop:
Tile
Tile
Tile
Tile
Tile
Tile
Tile
Tile
Tile
<Tiles columns={[1, 3]} dividers={true} space={["none", "small"]}>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
  <Card>
    <Text>Tile</Text>
  </Card>
</Tiles>

ContentBlock #

By default, all layout components will render full width. However, most applications will want to limit the width of content on the screen. In order to address this, Braid provides the ‘ContentBlock’ component that sets a maximum width and centres content horizontally.
Hello World
<ContentBlock>
  <Card>
    <Text>Hello World</Text>
  </Card>
</ContentBlock>
If you’d like a larger content block, you can optionally provide the ‘width’ prop:
Hello World
<ContentBlock width="large">
  <Card>
    <Text>Hello World</Text>
  </Card>
</ContentBlock>