Flex
Flex is the main layout container of Apollion. It renders a <div> with
display: flex and accepts the structural style API — spacing (margin/padding),
size, container geometry, the flex layout props (gap, flexDirection,
alignItems, justifyContent, …) and the responsive channels — in addition to
the native <div> props.
Flex is layout only (ADR-028): it carries no background, border,
elevation, typography or motion. Seeing a Flex (or Box / Grid) in a tree
always means "this arranges things". When a block needs a visual ground —
background, rounded border, shadow — that is a Paper or Card, and
text styling belongs to Text. (Some examples below still paint their demo
items to make the layout visible; author real UI with Paper for the surface.)
When to use
| ✅ Use when… | 🚫 Avoid when… |
|---|---|
|
Spacing
With Flex you can create spacing between elements and orient them in a
row or column, using the gap and flexDirection props.
loading
You can also control margin and padding using shorthands:
<Flex p="micro" /> // padding
<Flex pt="xs" /> // padding-top
<Flex pb="small" /> // padding-bottom
<Flex pl="medium" /> // padding-left
<Flex pr="large" /> // padding-right
<Flex py="xl" /> // vertical padding
<Flex px="xxl" /> // horizontal padding
<Flex m="micro" /> // margin
<Flex mt="xs" /> // margin-top
<Flex mb="small" /> // margin-bottom
<Flex ml="medium" /> // margin-left
<Flex mr="large" /> // margin-right
<Flex my="xl" /> // vertical margin
<Flex mx="xxl" /> // horizontal marginFlex children
flex="initial"
Allows a child to shrink, but not grow — it respects the initial size.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui ad labore ipsam.
<Flex flexDirection="row" wrap="wrap" gap="small">
<Flex flex="initial">{/* does not grow; shrinks if needed */}</Flex>
<Flex flex="initial">{/* does not grow; shrinks if needed */}</Flex>
</Flex>flex="fluid"
Makes the child grow and shrink as needed, ignoring the initial size.
<Flex flexDirection="row" wrap="wrap" gap="small">
<Flex flex="fluid" />
<Flex flex="fluid" />
<Flex flex="fluid" />
</Flex>flex="auto"
Makes the child grow and shrink, respecting the initial size.
<Flex flexDirection="row" wrap="wrap" gap="small">
<Flex flex="auto" />
<Flex flex="auto" />
</Flex>flex="none"
Prevents both growing and shrinking — useful to "pin" a child between fluid elements.
<Flex flexDirection="row" wrap="wrap" gap="small">
<Flex flex="fluid" />
<Flex flex="none">{/* neither grows nor shrinks */}</Flex>
<Flex flex="fluid" />
</Flex>Borders
loading
Background — that's Paper's job
Flex technically accepts bgColor (the prop surface is shared with every
container), but reaching for it is the signal you want
Paper instead. The division is semantic, and it
is meant to be read in the code: a Flex declares structure — rows,
columns, gaps, alignment — while a Paper declares a content surface —
something the user is meant to look at. Paper has every Flex prop, plus
the two things only a content surface earns: a background and a shadow.
Painting a background on a Flex gives a structural node a visual role,
and the next reader can no longer tell the skeleton from the skin.
// Structure: invisible skeleton — Flex.
<Flex flexDirection="row" wrap="wrap" gap="medium">
{/* Content surface: visible sheet — Paper. */}
<Paper p="medium" borderRadius="xs">
<Text text="Content" />
</Paper>
</Flex>Responsive by viewport (viewportMedias)
There are three responsive channels; pick by what the layout should react to:
viewportMedias— one object per viewport breakpoint. The viewport sibling ofcq, and the replacement for the flatmd_/lg_/xl_prefixes. Use it for genuine viewport cases — page shells, chrome shown/hidden by screen — where a container query is not an option (containmentis barred on page-level shells).cq— one object per container size. The layout reacts to the width of its own slot (see container queries).- flat
sm_/md_/lg_/xl_prefixes — the original per-prop viewport channel, now superseded byviewportMedias.
// flat prefixes — one prop per (axis × breakpoint):
<Flex md_flexDirection="row" md_gap="large" xl_p="small" />
// viewportMedias — one object per breakpoint:
<Flex viewportMedias={{ md: { flexDirection: 'row', gap: 'large' }, xl: { p: 'small' } }} />The base (unprefixed) props are the mobile style; each breakpoint opts in on
top, ascending min-width. viewportMedias accepts the same factory surface
as cq (spacing, size, color, flex, font, background, deep — Border excluded).
Polymorphic as on a typed layout object
The styled Flex accepts as / forwardedAs natively. To annotate a plain
layout object and still set as, type it as FlexProps (not
DefaultFlexInterface) — FlexProps adds the polymorphic keys without a local
augmentation:
import type { FlexProps } from '@apollion-dsi/core/containers/flex';
const shell: FlexProps = { as: 'section', gap: 'large', viewportMedias: { md: { flexDirection: 'row' } } };Examples
Flex provides many styles as props, simplifying common layouts without
requiring a dedicated styled-component.
Mixed layout (image + grid)
<Flex gap="small">
<Paper bgColor="primary.light" height={150} deep={0}>
<Image cover src="https://picsum.photos/500?random=10" />
</Paper>
<Flex flexDirection="row" wrap="wrap" gap="small" height={150}>
<Paper bgColor="danger.light" flex="fluid" deep={0} />
<Paper bgColor="danger.light" flex="fluid" deep={0} />
<Paper bgColor="danger.light" flex="fluid" deep={0} />
</Flex>
</Flex>Product card
R$ 1.900,00
/ month
<Paper
maxWidth={280}
minWidth={220}
borderWidth="thin"
borderRadius="xs"
borderStyle="solid"
borderColor="neutral.40"
overflow="hidden"
deep={0}
>
<Flex height={200}>
<Image cover src="https://picsum.photos/200" />
</Flex>
<Flex p="small">
<Text text="Lorem ipsum" color="grayscale.80" fontSize="medium" fontWeight="bold" />
<Text color="grayscale.80">
R$ 1.900,00
<Text color="grayscale.50" fontSize="small">
{' '}
/ month
</Text>
</Text>
<Flex flexDirection="row" wrap="wrap" justifyContent="end" mt="small">
<Button size="small" variant="outlined" text="Rent" />
</Flex>
</Flex>
</Paper>API summary
| Prop | Type | Default | Description |
|---|---|---|---|
gap | number | SpacingInterface | — | Spacing between children. |
flexDirection | 'row' | 'column' | 'row-reverse' | 'column-reverse' | 'column' | Main-axis direction. |
flex | 'fluid' | 'initial' | 'auto' | 'none' | — | Grow/shrink behavior. |
justifyContent | 'start' | 'end' | 'center' | 'between' | 'around' | 'evenly' | 'start' | Main-axis alignment. |
alignItems | 'start' | 'end' | 'center' | 'baseline' | 'stretch' | 'stretch' | Cross-axis alignment. |
wrap | 'wrap' | 'reverse' | 'nowrap' | — | Line wrapping. |
bgColor / color | string | — | Background / text color via theme. |
borderStyle / borderWidth / borderColor / borderRadius | string | — | Borders via theme. |
height / maxHeight / minHeight | number | string | — | Vertical dimensions. |
width / maxWidth / minWidth | number | string | — | Horizontal dimensions. |
p / px / py / pt / pb / pl / pr | number | SpacingInterface | — | Padding (shorthands). |
m / mx / my / mt / mb / ml / mr | number | SpacingInterface | — | Margin (shorthands). |
viewportMedias | Partial<Record<'xs' | 'sm' | 'md' | 'lg' | 'xl', …>> | — | One object per viewport breakpoint (sibling of cq). |
cq | Partial<Record<'xs' | 'sm' | 'md' | 'lg' | 'xl', …>> | — | One object per container size. |
as / forwardedAs | React.ElementType | — | Render as another element (type a layout object as FlexProps). |
This component's API is the system's layout props (spacing, color, flex/grid, size, border).
Avoid reaching for Paper out of habit when Flex would do — Paper only
adds value when the content actually needs a depth shadow.