Layout components are the foundational building blocks for structuring your UI. They provide flexible, theme-aware containers with powerful styling capabilities.
The Box component is the most fundamental layout primitive. It’s a div element with support for system props and the sx prop for theme-aware styling.
import { Box } from '@theme-ui/components'
<Box
p={3}
bg="background"
sx={{
borderRadius: 4,
boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
}}
>
Box content
</Box>
Render the Box as a different HTML element or component
Variant style from theme.variants
Emotion css prop for additional styles
System Props
Box supports a wide range of system props for common CSS properties:
Spacing:
margin, m - margin
marginTop, mt - margin-top
marginRight, mr - margin-right
marginBottom, mb - margin-bottom
marginLeft, ml - margin-left
marginX, mx - horizontal margin
marginY, my - vertical margin
padding, p - padding
paddingTop, pt - padding-top
paddingRight, pr - padding-right
paddingBottom, pb - padding-bottom
paddingLeft, pl - padding-left
paddingX, px - horizontal padding
paddingY, py - vertical padding
Color:
color - text color
backgroundColor, bg - background color
opacity - opacity
Examples
Basic Box
<Box p={4} bg="muted">
A simple box with padding and background color
</Box>
Responsive Spacing
<Box
p={[2, 3, 4]} // Different padding at different breakpoints
m={[1, 2, 3]}
>
Responsive box
</Box>
As Different Element
<Box as="section" p={4}>
Rendered as a section element
</Box>
The Flex component extends Box with display: flex by default, making it easy to create flexbox layouts.
import { Flex } from '@theme-ui/components'
<Flex sx={{ alignItems: 'center', gap: 3 }}>
<Box>Item 1</Box>
<Box>Item 2</Box>
<Box>Item 3</Box>
</Flex>
Flex accepts all Box props and automatically applies display: flex.
Examples
Horizontal Layout
<Flex sx={{ justifyContent: 'space-between', alignItems: 'center' }}>
<Box>Left</Box>
<Box>Right</Box>
</Flex>
Vertical Stack
<Flex sx={{ flexDirection: 'column', gap: 2 }}>
<Box>Item 1</Box>
<Box>Item 2</Box>
<Box>Item 3</Box>
</Flex>
Centered Content
<Flex
sx={{
height: '100vh',
alignItems: 'center',
justifyContent: 'center'
}}
>
<Box>Centered content</Box>
</Flex>
The Grid component creates CSS Grid layouts with a simple API for defining columns and gaps.
import { Grid } from '@theme-ui/components'
<Grid columns={[1, 2, 3]} gap={3}>
<Box>Grid item 1</Box>
<Box>Grid item 2</Box>
<Box>Grid item 3</Box>
<Box>Grid item 4</Box>
</Grid>
width
ResponsiveStyleValue<string | number>
Minimum width of child elements. Creates auto-fit or auto-fill grid columns.
columns
ResponsiveStyleValue<string | number>
Number of columns to use for the layout. Cannot be used with width prop.
gap
ResponsiveStyleValue<string | number>
default:"3"
Space between grid items (uses theme spacing scale)
repeat
'fit' | 'fill'
default:"'fit'"
Auto-repeat track behavior (auto-fit or auto-fill)
Grid also accepts all Box props.
Examples
Responsive Columns
<Grid columns={[1, 2, 3]} gap={4}>
<Card>Card 1</Card>
<Card>Card 2</Card>
<Card>Card 3</Card>
</Grid>
Fixed Width Columns
<Grid width="200px" gap={3}>
<Box>Auto-fit columns with min-width 200px</Box>
<Box>Grid will create as many columns as fit</Box>
<Box>Responsive without media queries</Box>
</Grid>
Custom Gap
<Grid columns={2} gap={[2, 3, 4]}>
<Box>Item with responsive gap</Box>
<Box>Gap increases at larger breakpoints</Box>
</Grid>
Container
The Container component creates a centered layout with a maximum width, perfect for page content.
import { Container } from '@theme-ui/components'
<Container>
<Heading>Page Title</Heading>
<Paragraph>Page content...</Paragraph>
</Container>
Container accepts all Box props. It uses the container variant from theme.layout by default.
variant
string
default:"'container'"
Variant from theme.layout
Default Styles
The Container component applies these default styles:
{
width: '100%',
maxWidth: 'container', // from theme.sizes.container
mx: 'auto' // centers the container
}
Examples
Basic Container
<Container py={4}>
<Heading>Welcome</Heading>
<Paragraph>This content is centered with max-width.</Paragraph>
</Container>
Custom Variant
Define variants in your theme:
// theme.js
export default {
layout: {
container: {
maxWidth: '1200px',
px: 3
},
narrow: {
maxWidth: '768px',
px: 3
}
}
}
Then use the variant:
<Container variant="narrow">
Narrow container content
</Container>
Full-Width Sections
<Box>
<Box bg="primary" color="white">
<Container py={5}>
<Heading>Hero Section</Heading>
</Container>
</Box>
<Container py={4}>
<Heading>Main Content</Heading>
</Container>
</Box>