Skip to content
This repository has been archived by the owner on Oct 25, 2023. It is now read-only.
Jesse McLean edited this page Apr 12, 2020 · 14 revisions

Overview

Our guiding principle for layout is that components should not provide surrounding white space. Instead, spacing between elements is owned entirely by layout components. This approach ensures that components are 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 this starter.

We borrow ideas for layout heavily from Braid Design System.


Table of contents


Spacing

Use cases


📦 (Box)

‘Box’ is the most low-level layout component. It serves as the foundational building block for almost every other component. We inject a number of style props from styled-system into a div allowing us to quickly and easily manipulate CSS properties without writing CSS classes for every definition.

This approach also gives us easy access to our Theme which offers us the ability to consistently reference spacing, fonts, colors, breakpoints, and other features with less mark up.

The Box method has been popularized by major companies such as Segment.

Use cases

  • Foundational spacing where we don't need the extra features of other, more complex layout components

Example

Box

<Box width={128} m={32} pb="100%" />

Card

Rather than nesting content in arbitrary Box elements, you may prefer to use standard Card elements instead.

Use cases

  • Components with defined containers

Example

Card

<Card px={64} py={32}>
  <Text>
    Lorem ipsum dolor. Aenean rutrum in sem a ullamcorper. Integer
    ut euismod urna. Interdum et malesuada fames ac ante ipsum primis
    in faucibus.
  </Text>
</Card>

Flex

Flex is essentially the same as Box except is has display: flex-box enabled by default. This small addition can reduce mark up in a large project and helps people exploring DOM nodes to more easily pinpoint which elements are flex-enabled elements and which are not.

Use cases

  • Low level flexible spacing
  • When we want to use things like justify-content: space-between

Example

Flex

<Flex justifyContent="space-between">
  <Card />
  <Card />
</Flex>

Columns

Columns is the direct parent of Column and defines the spacing between each Column. Columns can accept both Theme properties as well as values as whole numbers or pixels.

We use the Column component directly inside and only inside of the Columns component. This gives us control over setting column width and allows us to pass down spacing properties from Columns to each individual Column.

When we use a Column in another component, we must pass all props into the Column so that the props from Columns are absorbed properly. Use a spread operator like {...props} to do this.

Use cases

  • Layout of major areas of an application
  • Elements that wrap (use responsive props for this, e.g. width={['100%', '50%']})

Example

Columns

<Columns>
  <Column width={8 / 16} />
</Columns>

Stacks

VStack

The most common white space on screen is between elements stacked vertically. For this use case, we provide a VStack component that accepts a ‘space’ prop. It accepts most units and values as well as spacing properties in the Theme. Set the prop dividers to true to separate children with horizontal dividers.

Use cases

  • Consistent spacing between sections of a website
  • Lists

Example

VStack

<VStack space={32}>
  <Heading>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>
</VStack>

HStack

HStack allows us to horizontally stack elements by a value define by the space prop. It accepts most units and values as well as spacing properties in the Theme. Set the prop dividers to true to separate children with vertical dividers.

Use cases

  • Consistent spacing between components that you don't want to wrap
  • Placing icons or images beside text

Example

HStack

<HStack space={32}>
  <svg viewBox="0 0 24 24" >
    <title>GitHub</title>
    <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"></path>
  </svg>
  <Text>
    GitHub
  </Text>
</HStack>

Divider

The Divider is used in different components, like VStack, and allows us to easy create divisions of content with a consistent appearance.

Use cases

  • Between sections of content

Example

Divider

<VStack space={32}>
  <Text>Lorem ipsum dolor</Text>
  <Divider />
  <Text>Phasellus ipsum tortor</Text>
</VStack>

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, we provide an Inline component.

Use cases

  • A set of tags or badges
  • Displaying usernames in a list

Example

Inline

<Inline space={8}>
  <Text>Lorem ipsum</Text>
  <Text>Phasellus tortor</Text>
  <Text>Integer ut</Text>
  <Text>Euismod urna</Text>
  <Text>Lectus ante</Text>
  <Text>Porttitor massa</Text>
</Inline>

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, we provide the ContentBlock component that sets a maximum width and centers content horizontally.

Use cases

  • Hold text to a readable length per line (recommended 60 characters per line)

Example

ContentBlock

<ContentBlock maxWidth={512}>
  <Card>
    <Text>
      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>
  </Card>
</ContentBlock>

Wrapper

We use the Wrapper to center and max-out content so that we maintain readable text and organized content through the main spreads of the project. For this we use ContentBlock. The difference with Wrapper is that it adds margins on each side of the content so that content never bleeds into the edge of the screen.

Use cases

  • Wrap around content sections

Example

Wrapper

<Wrapper px={32}>
  <Card>
    <Text>
      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>
  </Card>
</Wrapper>

AspectRatio

Takes the property ratio and splits it into an array which then has its values divided by each other and multiplied by 100%. This results in a component where child elements are confined to space.

Assigning overflow: hidden to the component will hide anything that might be larger than the aspect ratio.

Use cases

  • Good for images and video elements

Example

AspectRatio

<AspectRatio ratio="2:1" bg="brand.primary" />