-
Notifications
You must be signed in to change notification settings - Fork 1
Layout
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.
‘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.
- Foundational spacing where we don't need the extra features of other, more complex layout components
<Box width={128} m={32} pb="100%" />
Rather than nesting content in arbitrary Box
elements, you may prefer to use standard Card
elements instead.
- Components with defined containers
<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
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.
- Low level flexible spacing
- When we want to use things like
justify-content: space-between
<Flex justifyContent="space-between">
<Card />
<Card />
</Flex>
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.
- Layout of major areas of an application
- Elements that wrap (use responsive props for this, e.g.
width={['100%', '50%']}
)
<Columns>
<Column width={8 / 16} />
</Columns>
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.
- Consistent spacing between sections of a website
- Lists
<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
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.
- Consistent spacing between components that you don't want to wrap
- Placing icons or images beside text
<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>
The Divider
is used in different components, like VStack
, and allows us to easy create divisions of content with a consistent appearance.
- Between sections of content
<VStack space={32}>
<Text>Lorem ipsum dolor</Text>
<Divider />
<Text>Phasellus ipsum tortor</Text>
</VStack>
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.
- A set of tags or badges
- Displaying usernames in a list
<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>
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.
- Hold text to a readable length per line (recommended 60 characters per line)
<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>
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.
- Wrap around content sections
<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>
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.
- Good for images and video elements
<AspectRatio ratio="2:1" bg="brand.primary" />