Docs
Layout Props

Layout Props

Every @apollion-dsi/core component accepts a common set of layout props — spacing, color, flex, size, border and typography — in addition to the props specific to each component. They're declared as data right in the JSX, with no hand-written CSS.

These props are shared by every component. Each component's Properties table lists only its specific API — the layout props below aren't repeated there.

Spacing

margin and padding accept the theme's scale tokens (xs, small, medium, large, xl). Axis and side shortcuts:

PropEffect
m, mt, mr, mb, mlmargin (all / top / right / bottom / left)
mx, mymargin horizontal / vertical
p, pt, pr, pb, plpadding (all / top / right / bottom / left)
px, pypadding horizontal / vertical
gapspace between children (on Flex/Grid)

p="small"

p="medium"

p="large"

<Paper p="large" mb="medium" gap="small">

</Paper>

Color and surface

PropEffect
colortext/content color (semantic or foundation token)
readabletext intent: makes color legible (WCAG) against the theme's surface; true = AA, a number = custom floor
bgColorbackground color
deepelevation/surface level (0n)
deepColor, contrastfine-tuning of surface and contrast

color and bgColor also accept a runtime CSS color (#hex, rgb(), oklch(), var(--*), currentColor) for external-data cases — a per-entity palette from an API, a consumer CSS variable. The value passes through untouched. Prefer theme tokens whenever the color is a design decision: runtime values bypass the theme's contrast guarantees (readable still applies if you set it explicitly).

Flex

Available on any Flex-based container (Flex, Paper, Card):

PropEffect
flexDirectionrow / column (+ -reverse)
alignItems, justifyContentcross-axis / main-axis alignment
alignContentpacking of wrapped lines
gapspace between children
grow, shrink, flex, flexBasisflex sizing
wrap, orderline wrapping and order
alignSelf, justifySelfthe item's own alignment
<Flex flexDirection="row" wrap="wrap" justifyContent="between" alignItems="center" gap="small">

</Flex>

Alignment gotchas: Flex's flexDirection default is column (not CSS's row) — for a row, declare row explicitly. On that default column, vertical centering is justifyContent="center" (main axis); alignItems is the cross axis (horizontal). Tokens are semantic (start, between); the native names (flex-start, space-between) are accepted as aliases, and an unknown value warns in development instead of silently emitting nothing. With mixed typography on the same line (a large value + a small suffix), alignItems="center" centers the line boxes and looks crooked; use alignItems="baseline" to align on the baseline. gap={0} is valid and zeroes the space between children.

Container queries — the cq channel

Viewport prefixes answer "how wide is the viewport"; cq answers "how wide is my slot". Mark the slot with containment, then any child adapts to the slot's width with the same factory props, per theme.containerSizes key (xs 240 · sm 360 · md 480 · lg 640 · xl 900, a separate scale from viewport breakpoints — slot widths are not viewport widths):

<Flex containment="inline-size">
  <Card cq={{ sm: { p: 'large' }, md: { flexDirection: 'row' } }} />
</Flex>

Mobile-first applies here too: the base style IS the narrow-slot style and wider slots opt in via ascending min-width container queries. Card is already a size container — content inside a Card can use cq with no extra wrapper. Never mark page-level shells (GlobalStyle, layout roots) as containers — containment belongs on the immediate wrapper of the adapting component.

The full story — the mental model, the containment marker, the containerSizes scale, where cq stops and JS begins, and how to explore it in Storybook — lives in Container Queries.

Grid

Grid configures columns/areas per breakpoint via medias:

<Grid medias={{ xs: { columns: '1fr' }, md: { columns: '1fr 2fr', areas: '"a b"' } }}>…</Grid>

columns also accepts a typed auto-repeat object — the zero-media-query card grid (tracks wrap by container width, minimum guarded with min(<min>, 100%) so it never overflows a narrow viewport):

<Grid medias={{ xs: { columns: { autoFit: '250px' }, gap: 'medium' } }}>…</Grid>

Alignment is part of the grid surface — on the host and per breakpoint — with the same tokens as Flex: alignItems, justifyContent, alignContent, plus grid-only justifyItems and placeItems. Centering a cell's content needs no nested Flex:

<Grid
  height="100%"
  alignItems="center"
  justifyItems="center"
  medias={{ md: { columns: '1fr 1fr', placeItems: 'start' } }}
>

</Grid>

Size

width, height, minWidth, maxWidth, minHeight, maxHeight — accept tokens, numbers (px) or CSS strings ('100%', '24rem').

Position and display

PropEffect
displayflex, block, grid, none
position, top, right, bottom, left, zIndexpositioning
transformCSS string ('translate(-50%, -33px)') — recenter an anchored overlay
overflow, overflowX, overflowYoverflow control
cursor, isHidden, absoluteFill, truncatecommon utilities

Border and radius

PropEffect
borderColor, borderStyle, borderWidth, borderPositionborder
borderRadius, round, squareradius (per-corner shortcuts: roundTop, sharpBottomLeft…)

Typography

fontFamily, fontSize, fontWeight, fontStyle, lineHeight, letterSpacing, textAlign, textTransform, textDecoration, whiteSpace, wordBreak — accept tokens from the theme's typographic scale.

legibility="on-photo" applies a reading shadow for text over a photographic/illustrated background (a closed preset — not a free-form textShadow).

Responsive

Any prop above accepts per-breakpoint variants with the sm_, md_, lg_ and xl_ prefixes (mobile-first — the unprefixed version is the default):

<Flex flexDirection="column" md_flexDirection="row" wrap="wrap" gap="small" md_gap="large">

</Flex>

Where these props belong

Knowing how to declare spacing and alignment is half the job; the other half is deciding which element they live on. An Apollion leaf component is already a flex container, so most of a screen's Flexes are wrappers that can disappear — with the spacing moving onto the child itself.

The full rule, the table of which props each leaf accepts, and the audit checklist live in Composition.

// bad — Flex exists only to carry the mb
<Flex mb="medium">
  <Button text="Save" />
</Flex>
 
// good — the spacing lives on the Button itself
<Button text="Save" mb="medium" />