Patterns
Patterns are layout primitives that can be used to create robust and responsive layouts with ease. Bamboo comes with predefined patterns like flex, grid, center, container, etc. Each one is a function that returns a class name.
Pattern properties can be overridden as needed, just like in the css function. To define your own, see
customization.
Predefined Patterns
Patterns are removed whenever one turns out to be a second spelling of something the system already had. box(styles)
was exactly css(styles) and visuallyHidden() was css({ srOnly: true }); stack, hstack, vstack and wrap
were flex with defaults frozen; square and circle were center with a size; and cq was
css({ containerType, containerName }). Each section below says what to write instead.
Container
The Container pattern is used to create a container with a max-width and center the content.
By default, the container sets the following properties:
maxWidth: 8xlmarginX: autoposition: relativepaddingX: { base: 4, md: 6, lg: 8 }
import { container } from '../styled-system/patterns'
function App() {
return (
<div className={container()}>
<div>First</div>
<div>Second</div>
<div>Third</div>
</div>
)
}
Aspect Ratio
The Aspect Ratio pattern is used to create a container with a fixed aspect ratio. It is used when displaying images, maps, videos and other media.
Note: In most cases, we recommend using the aspectRatio property instead of the pattern.
The aspectRatio function accepts the following properties:
ratio: The aspect ratio of the container. Can be a number or a string.
import { aspectRatio } from '../styled-system/patterns'
function App() {
return (
<div className={aspectRatio({ ratio: 16 / 9 })}>
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m1" title="Google map" frameBorder="0" />
</div>
)
}
Flex
The Flex pattern is used to create a flex container and provides some shortcuts for the flex property.
The flex function accepts the following properties:
direction: The flex direction of the container. Can berow,column,row-reverseorcolumn-reverse.wrap: An alias for the cssflex-wrapproperty.align: An alias for the cssalign-itemsproperty.justify: An alias for the cssjustify-contentproperty.basis: An alias for the cssflex-basisproperty.grow: An alias for the cssflex-growproperty.shrink: An alias for the cssflex-shrinkproperty.
Any other style property is accepted too, so gap and the rest of the box model work here without being listed above.
import { flex } from '../styled-system/patterns'
function App() {
return (
<div className={flex({ direction: 'row', align: 'center', gap: '6' })}>
<div>First</div>
<div>Second</div>
<div>Third</div>
</div>
)
}
stack, hstack, vstack and wrap were removed. Each was flex with defaults frozen, so writing the default you
want is the whole migration — and the gap they applied silently is now yours to choose:
flex({ direction: 'column', gap: '8px' }) // was stack()
flex({ align: 'center', gap: '8px' }) // was hstack()
flex({ direction: 'column', align: 'center', gap: '8px' }) // was vstack()
flex({ wrap: 'wrap', gap: '8px' }) // was wrap()Center
The Center pattern is used to center the content of a container, optionally at a fixed size.
The center function accepts the following properties:
inline: Whether to useinline-flexorflexfor the container. The value is a boolean.size: Setswidthandheighttogether, and stops a flex parent from shrinking the result.
import { center } from '../styled-system/patterns'
function App() {
return (
<div className={center({ bg: 'red.200' })}>
<Icon />
</div>
)
}
Pass size for a fixed square, and add borderRadius for a circle:
import { center } from '../styled-system/patterns'
function App() {
return (
<>
<div className={center({ size: '12', bg: 'red.300' })}>1</div>
<div className={center({ size: '12', borderRadius: 'full', bg: 'red.300' })}>2</div>
</>
)
}
square and circle were removed. square({ size }) is center({ size }), and circle({ size }) is
center({ size, borderRadius: 'full' }) — borderRadius is an ordinary style property, so the rounded case never
needed a pattern of its own.
LinkOverlay
The link overlay pattern is used to expand a link's clickable area to its nearest parent with position: relative.
We recommend using this pattern when the relative parent contains at most one clickable link.
import { css } from '../styled-system/css'
import { linkOverlay } from '../styled-system/patterns'
function App() {
return (
<div className={css({ pos: 'relative' })}>
<img src="https://via.placeholder.com/150" alt="placeholder" />
<a href="#" className={linkOverlay()}>
View more
</a>
</div>
)
}
Float
The Float pattern is used to anchor an element to the top, bottom, left or right of the container.
It requires a parent element with position: relative styles.
The float function accepts the following properties:
placement: The placement of the element. Can bebottom-end,bottom-start,top-end,top-start,bottom-center,top-center,middle-center,middle-endormiddle-start. Defaults totop-end.offset: The offset of the element from the edge of the container. Can be a number or a string.offsetX: Same asoffset, but only for the horizontal axis.offsetY: Same asoffset, but only for the vertical axis.
import { css } from '../styled-system/css'
import { float } from '../styled-system/patterns'
function App() {
return (
<div className={css({ position: 'relative' })}>
<div className={float({ placement: 'top-start' })}>3</div>
</div>
)
}
Grid
The Grid pattern is used to create a grid layout.
The grid function accepts the following properties:
columns: The number of columns in the grid.gap: The gap between the grid items.columnGap: The gap between the grid items horizontally.rowGap: The gap between the grid items vertically.minChildWidth: The minimum width of the child elements before wrapping (must not be used withcolumns).
import { grid } from '../styled-system/patterns'
function App() {
return (
<div className={grid({ columns: 3, gap: '6' })}>
<div>First</div>
<div>Second</div>
<div>Third</div>
</div>
)
}
Grid Item
The Grid Item pattern is used to style the children of a grid container.
The gridItem function accepts the following properties:
colSpan: The number of columns the item spans.rowSpan: The number of rows the item spans.rowStart: The row the item starts at.rowEnd: The row the item ends at.colStart: The column the item starts at.colEnd: The column the item ends at.
import { grid, gridItem } from '../styled-system/patterns'
function App() {
return (
<div className={grid({ columns: 3, gap: '6' })}>
<div className={gridItem({ colSpan: 2 })}>First</div>
<div>Second</div>
<div>Third</div>
</div>
)
}
Divider
The Divider pattern is used to create a horizontal or vertical divider.
The divider function accepts the following properties:
orientation: The orientation of the divider. Can behorizontalorvertical.thickness: The thickness of the divider. Can be a sizing token, or arbitrary value.color: The color of the divider. Can be a color token, or arbitrary value.
import { divider, flex } from '../styled-system/patterns'
function App() {
return (
<div className={flex({ direction: 'column', gap: '8px' })}>
<button>First</button>
<div className={divider({ orientation: 'horizontal' })} />
<button>Second</button>
</div>
)
}
Spacer
The Spacer pattern is used to create an adjustable, empty space in a flex or grid layout.
The spacer function accepts the following properties:
size: The fixed size of the spacer. Can be a spacing token, or arbitrary value. When omitted, the spacer grows to fill the remaining space.
import { flex, spacer } from '../styled-system/patterns'
function App() {
return (
<div className={flex({ align: 'center', gap: '8px' })}>
<div>Logo</div>
<div className={spacer()} />
<div>Menu</div>
</div>
)
}
Bleed
The Bleed pattern is used to create a full width element by negating the padding applied to its parent container.
The bleed function accepts the following properties:
inline: The amount of padding to negate on the horizontal axis. Should match the parent's padding.block: The amount of padding to negate on the vertical axis. Should match the parent's padding.
import { css } from '../styled-system/css'
import { bleed } from '../styled-system/patterns'
export function Page() {
return (
<div className={css({ px: '6' })}>
<div className={bleed({ inline: '6' })}>Welcome</div>
</div>
)
}
Container Queries
There is no pattern for this — containerType and containerName are ordinary utilities, and containerName is
already typed against the containerNames theme key.
import { css } from 'styled-system/css'
function Demo() {
return (
<nav className={css({ containerType: 'inline-size' })}>
<div
className={css({
fontSize: { base: 'lg', '@/sm': 'md' },
})}
/>
</nav>
)
}
You can also use named container queries:
// 1 - Define container conditions
export default defineConfig({
// ...
theme: {
containerNames: ['sidebar', 'content'],
containerSizes: {
xs: '40em',
sm: '60em',
md: '80em',
},
},
})
// 2 - Name the container and query it
import { css } from 'styled-system/css'
function Demo() {
return (
<nav className={css({ containerType: 'inline-size', containerName: 'sidebar' })}>
<div
className={css({
// When the sidebar container reaches the `sm` size
// change font size to `md`
fontSize: { base: 'lg', '@sidebar/sm': 'md' },
})}
/>
</nav>
)
}
The cq pattern was removed. It renamed two properties onto containerType and containerName and defaulted the
first to inline-size, which is one default's worth of value for a name that sat next to the unrelated container
pattern in autocomplete.
Read more about container queries here.