Skip to main contentSkip to docs navigation

A flexbox container exposing direction, wrap, justification, alignment, and gap as props — the escape hatch when Stack's fixed defaults aren't enough.

<Flex> turns an element into a flexbox container (.d-flex, or .d-inline-flex when inline is set) and exposes the underlying flex properties as props: direction, wrap, justify, align, alignContent, gap/rowGap/columnGap. Each takes a value, or an object with a value per breakpoint.

Reach for <Stack> first for simple one-dimensional arrangements — it wraps .hstack/.vstack with alignment defaults baked in. Reach for <Flex> instead once more control is needed than Stack's defaults give: wrapping, main-axis justification, cross-axis alignment other than Stack's fixed default, or no default flex/align behavior at all (a bare .d-flex with nothing else set).

A Tailwind build of @chassis-ui/css has the classes of the <Flex> props only with its safelist loaded: see Tailwind.

Basic usage

With no props, <Flex> is a plain flexbox row using the browser's defaults (flex-direction: row, no wrap, items stretched to the container's cross-axis size):

First item
Second item
Third item
JSX
import { Flex } from '@chassis-ui/react'

export const Example = () => {
  return (
    <Flex gap="md">
      <div>First item</div>
      <div>Second item</div>
      <div>Third item</div>
    </Flex>
  )
}

Direction

direction sets flex-direction. Omit it for the browser default (row).

First item
Second item
Third item
JSX
import { Flex } from '@chassis-ui/react'

export const Example = () => {
  return (
    <Flex direction="column" gap="md">
      <div>First item</div>
      <div>Second item</div>
      <div>Third item</div>
    </Flex>
  )
}

Justify content

justify sets justify-content, aligning items along the main axis.

First item
Second item
Third item
JSX
import { Flex } from '@chassis-ui/react'

export const Example = () => {
  return (
    <Flex justify="between">
      <div>First item</div>
      <div>Second item</div>
      <div>Third item</div>
    </Flex>
  )
}

Align items

align sets align-items, aligning items along the cross axis.

First item
Second item
Third item
JSX
import { Flex } from '@chassis-ui/react'

export const Example = () => {
  return (
    <Flex align="center" style={{ height: '100px' }}>
      <div>First item</div>
      <div>Second item</div>
      <div>Third item</div>
    </Flex>
  )
}

Wrap

wrap sets flex-wrap, letting items move onto new lines instead of overflowing or shrinking to fit. Once a container wraps, align still governs how each item sits within its own line; alignContent (below) governs how the lines themselves are spaced.

One
Two
Three
Four
Five
JSX
import { Flex } from '@chassis-ui/react'

export const Example = () => {
  return (
    <Flex wrap="wrap" gap="sm" style={{ width: '200px' }}>
      <div>One</div>
      <div>Two</div>
      <div>Three</div>
      <div>Four</div>
      <div>Five</div>
    </Flex>
  )
}

Align content

alignContent sets align-content, distributing wrapped lines along the cross axis. It has no effect on single-line (non-wrapping) containers, so it only does something combined with wrap:

One
Two
Three
Four
Five
JSX
import { Flex } from '@chassis-ui/react'

export const Example = () => {
  return (
    <Flex wrap="wrap" alignContent="between" gap="sm" style={{ width: '200px', height: '220px' }}>
      <div>One</div>
      <div>Two</div>
      <div>Three</div>
      <div>Four</div>
      <div>Five</div>
    </Flex>
  )
}

Row and column gaps

gap sets spacing on both axes at once. rowGap/columnGap control each axis independently, and take precedence over gap on their own axis — useful once a wrapped container needs different spacing between lines than between items on the same line.

One
Two
Three
Four
Five
JSX
import { Flex } from '@chassis-ui/react'

export const Example = () => {
  return (
    <Flex wrap="wrap" rowGap="xl" columnGap="xs" style={{ width: '200px' }}>
      <div>One</div>
      <div>Two</div>
      <div>Three</div>
      <div>Four</div>
      <div>Five</div>
    </Flex>
  )
}

Responsive

Each of direction/wrap/justify/align/alignContent/gap/rowGap/columnGap takes an object in place of a value: base is the value from the narrowest viewport, and a key named after a breakpoint (sm/md/lg/xl/2xl) is the value from that breakpoint up, as in direction={{ base: 'column', md: 'row' }}. An object with no base leaves the prop unset below its first breakpoint. Unlike <Stack>'s direction, which relies on container queries, Flex's breakpoint classes are plain viewport min-width media queries — no .contains-inline ancestor needed. Below the md breakpoint the container stacks its children in a column; at md and above it switches to a row with items spaced apart:

First item
Second item
Third item
JSX
import { Flex } from '@chassis-ui/react'

export const Example = () => {
  return (
    <Flex
      direction={{ base: 'column', md: 'row' }}
      gap={{ base: 'sm', md: 'md' }}
      justify={{ md: 'between' }}
    >
      <div>First item</div>
      <div>Second item</div>
      <div>Third item</div>
    </Flex>
  )
}

Item-level utilities

<Flex> covers container-level properties only. Per-item concerns — align-self, order, flex-grow/flex-shrink, flex-fill, or an auto-margin spacer like .ms-auto — apply directly via className on a child, the same as with plain chassis-css markup. Below, .ms-auto pushes everything after it to the end of the row:

First item
Second item
Third item
JSX
import { Flex } from '@chassis-ui/react'

export const Example = () => {
  return (
    <Flex gap="md">
      <div>First item</div>
      <div className="ms-auto">Second item</div>
      <div>Third item</div>
    </Flex>
  )
}

API

PropTypeDefault
align?Responsive<"center" | "start" | "end" | "baseline" | "stretch">—
Sets align-items, aligning items along the cross axis. Takes an object per breakpoint, as direction does.
alignContent?Responsive<"center" | "start" | "end" | "between" | "around" | "stretch">—
Sets align-content, distributing wrapped lines along the cross axis. Has no effect on single-line (non-wrapping) containers. Takes an object per breakpoint, as direction does.
asChild?boolean—
Render the single child element in place of this component's own element, with this component's classes, props and ref merged onto it: <Button asChild><Link href="/login">Log in</Link></Button>. The alternative to component for React Server Components — an element can be passed from the server to this package's client components, a component reference (component={Link}) can't.
className?string—
A string of all className you want applied to the component.
columnGap?{ Responsive<Spacing | 0> }—
Spacing between columns (the main axis), mapped to the column-gap-* utility classes. Independent of gap/rowGap. Takes an object per breakpoint, as direction does.
component?ElementType—
Component used for the root node. Either a string to use a HTML element or a component.
direction?Responsive<"row" | "column" | "row-reverse" | "column-reverse">—
Sets flex-direction. Omit for the browser default (row). An object sets it per breakpoint, base being the narrowest width: { base: 'column', md: 'row' }. The breakpoints are widths of the viewport, so unlike Stack's direction they need no .contains-inline ancestor.
gap?{ Responsive<Spacing | 0> }—
Spacing between children on both axes, mapped to the gap-* utility classes. Overridden per axis by rowGap/columnGap where set. Takes an object per breakpoint, as direction does.
inline?boolean—
Renders an inline flex container (.d-inline-flex) instead of a block-level one (.d-flex, the default).
justify?Responsive<"center" | "start" | "end" | "between" | "around" | "evenly">—
Sets justify-content, aligning items along the main axis. Takes an object per breakpoint, as direction does.
ref?any—
rowGap?{ Responsive<Spacing | 0> }—
Spacing between rows (the cross axis when wrapped), mapped to the row-gap-* utility classes. Independent of gap/columnGap. Takes an object per breakpoint, as direction does.
wrap?Responsive<"wrap" | "nowrap" | "wrap-reverse">—
Sets flex-wrap. Omit for the browser default (nowrap). Takes an object per breakpoint, as direction does.