Layout

This article provides a breakdown of basic concepts and directions on how to compose the layout of any complexity.

Building blocks

Box and Flex components are basic building blocks of any layout composition and are based on CSS box model and CSS flexbox layout model. Listed below are the links that will help you familiarize yourself with these concepts and help you be effective at using Box and Flex components.

Spacing

Padding and Margins

Padding is used for adding spacing inside of the component and margin is used for adding space around the component.

Padding + Margin
Padding
Margin
<Box bg="blackBlue" p="x3" m="x3">Padding + Margin</Box>
<Box bg="blackBlue" p="x6">Padding</Box>
<Box bg="blackBlue" m="x6">Margin</Box>

Box and Flexbox components have several style props for handling margins and paddings while adhering to the Design System's spacing scale.

Layout Composition

Flexbox is used for composing layouts. Establishing direction, alignment, wrapping, and order is achieved through the use of Flexbox props. Do not use floats to compose layout.

Direction (flexDirection prop)

Horizontal layout

1
2
3
<Flex flexDirection="row" color="white">
  <Box bg="blue" m="x1" py="x3" px="x4">1</Box>
  <Box bg="darkBlue" m="x1" py="x3" px="x4">2</Box>
  <Box bg="blackBlue" m="x1" py="x3" px="x4">3</Box>
</Flex>

Vertical layout

1
2
3
<Flex flexDirection="column" color="white">
    <Box bg="blue" m="x1" py="x3" px="x4">1</Box>
    <Box bg="darkBlue" m="x1" py="x3" px="x4">2</Box>
    <Box bg="blackBlue" m="x1" py="x3" px="x4">3</Box>
  </Flex>
</Flex>

Wrapping content (flexWrap prop)

By default, Flexbox will try to fit all of its children within the line. In order to force wrapping, you will need to modify flexWrap prop.

Wrapped content

1
2
3
4
<Flex flexWrap="wrap" color="white">
  <Box bg="blue" m="x1" p="x3" width={ 1 / 3 }>1</Box>
  <Box bg="darkBlue" m="x1" p="x3" width={ 1 / 4 }>2</Box>
  <Box bg="blackBlue" m="x1" p="x3" width={ 1 / 3 }>3</Box>
  <Box bg="black" m="x1" p="x3" width={ 1 / 4 }>4</Box>
</Flex>

Alignment (justifyContent, alignItems prop)

Content distribution along the main axis is controlled through justifyContent prop.

Left aligned

1
2
3
<Flex justifyContent="flex-start" color="white">
  <Box bg="blue" m="x1" py="x3" px="x4">1</Box>
  <Box bg="darkBlue" m="x1" py="x3" px="x4">2</Box>
  <Box bg="blackBlue" m="x1" py="x3" px="x4">3</Box>
</Flex>

Centered

1
2
3
<Flex justifyContent="center" color="white">
  <Box bg="blue" m="x1" py="x3" px="x4">1</Box>
  <Box bg="darkBlue" m="x1" py="x3" px="x4">2</Box>
  <Box bg="blackBlue" m="x1" py="x3" px="x4">3</Box>
</Flex>

Evenly distributed

1
2
3
<Flex justifyContent="space-between" color="white">
  <Box bg="blue" m="x1" py="x3" px="x4">1</Box>
  <Box bg="darkBlue" m="x1" py="x3" px="x4">2</Box>
  <Box bg="blackBlue" m="x1" py="x3" px="x4">3</Box>
</Flex>

Alignment of items on a cross-axis is controlled through alignItems prop.

Vertical centered

1
2
3
<Flex alignItems="center" color="white" bg="lightGrey" p="x1" height="200px">
  <Box bg="blue" m="x1" py="x3" px="x4">1</Box>
  <Box bg="darkBlue" m="x1" py="x3" px="x4">2</Box>
  <Box bg="blackBlue" m="x1" py="x3" px="x4">3</Box>
</Flex>

Order (order prop)

The order prop controls the order in which elements are displayed inside of the Flexbox component.

Changed default order

1
2
3
4
<Flex color="white">
  <Box bg="blue" m="x1" py="x3" px="x4">1</Box>
  <Box bg="darkBlue" m="x1" py="x3" px="x4" order="99">2</Box>
  <Box bg="blackBlue" m="x1" py="x3" px="x4" order="-1" >3</Box>
  <Box bg="black" m="x1" py="x3" px="x4" order="1">4</Box>
</Flex>

A full breakdown of capabilities and list of available props and their values is available on the Flex component page.

Width

The width of the Box and Flex component is set through the width prop. Width accepts any number from 0–1 and is converted to a percentage. Numbers greater than 1 are interpreted as pixel values. Relative units (em/rem/vw/vh/%) are passed through string values.

Varoius ways to set a width

1/4
0.25
140
8.5em
<Flex color="white">
  <Box width={ 1/4 } bg="blue" m="x1" p="x3">1/4</Box>
  <Box width={ 0.25 } bg="darkBlue" m="x1" p="x3">0.25</Box>
  <Box width={ 140 } bg="blackBlue" m="x1" p="x3">140</Box>
  <Box width="8.5em" bg="black" m="x1" p="x3">8.5em</Box>
</Flex>

Responsiveness

Providing different prop values for different breaking points that are based on the theme.breakpoints is possible by passing an object to a prop.

Size and background colour change based on the screen size

1
2
3
<Flex color="white">
  <Box width={ { extraSmall: 1 / 9, small: 1 / 9, medium: 7 / 9 } } bg={ { extraSmall: "blue", small: "darkBlue", medium: "blackBlue" } } m="x1" py="x3" px="x4">1</Box>
  <Box width={ { extraSmall: 1 / 9, small: 7 / 9, medium: 1 / 9 } } bg={ { extraSmall: "darkBlue", small: "blackBlue", medium: "darkBlue" } } m="x1" py="x3" px="x4">2</Box>
  <Box width={ { extraSmall: 7 / 9, small: 1 / 9, medium: 1 / 9 } } bg={ { extraSmall: "blackBlue", small: "blue", medium: "blue" } } m="x1" py="x3" px="x4">3</Box>
</Flex>

2-Column Layout Example

Typical 2-column layout structure with a sidebar or a pannel.

Main content

Sidebar content

<Flex height="400px" flexDirection={ { extraSmall: "column", small: "row", medium: "row" } }>
  <Flex bg="whiteGrey" justifyContent="center" alignItems="center" p="x3" width={ { extraSmall: 1, small: 2 / 3, medium: 1 / 2 } } height={ { extraSmall: "200px", small: "auto", medium: "auto" } }>
    <Text mb={ 0 }>Main content</Text>
  </Flex>
  <Flex bg="lightGrey" flexDirection="column" justifyContent="center" alignItems="center" p="x3" width={ { extraSmall: 1, small: 1 / 3, medium: 1 / 2 } } height={ { extraSmall: "200px", small: "auto", medium: "auto" } }>
    <Text mb={ 0 }>Sidebar content</Text>
  </Flex>
</Flex>

IE11 and Flexbox

To make Flexbox work properly in IE11 additional work may be required. Listed below are the issues that have been discovered and their potential solutions. If you are lucky enough to run into an issue that hasn't been recorded, please let us now in #design-system Slack channel.

Using minHeight

Setting minHeight on a flex container does not apply to its flex items. There are 2 ways to resolve this issue:

  • Substituting minHeight with height (Example)
  • Wrapping flex container with another flex container (Example)

Please refer here for a detailed description of the bug and available solutions.

Related components