# Layout (/docs/layout)



## Choose a layout component [#choose-a-layout-component]

| Component                                      | Use when                                                         |
| ---------------------------------------------- | ---------------------------------------------------------------- |
| [Box](/components/layout/box)                  | You need a custom flex or grid layout, or visual utilities       |
| [Stack](/components/layout/stack)              | Direct children should flow on the logical block axis            |
| [Cluster](/components/layout/cluster)          | Direct children should flow on the logical inline axis and wrap  |
| [Grid](/components/layout/grid)                | Direct children need an explicit equal column count              |
| [AutoGrid](/components/layout/auto-grid)       | Columns should grow from a minimum inline size                   |
| [Track](/components/layout/track)              | Rails need controlled alignment beside flexible inline content   |
| [Container](/components/layout/container)      | Content needs a maximum inline size and local responsive queries |
| [AspectRatio](/components/layout/aspect-ratio) | Media should fill a locked inline-to-block ratio                 |
| [ScrollFade](/components/layout/scroll-fade)   | Scrollable content should fade at its edges                      |

## Box [#box]

Box is the general layout element. Use it to:

* Provide spacing to child elements.
* Impose sizing constraints on content.
* Control layout behaviour within flex and grid containers.
* Hide content responsively.

```tsx
import { Box } from '@luke-ui/react/box';

<Box maxInlineSize="42rem" padding="sp24">
	{children}
</Box>;
```

Use semantic HTML when no layout properties are needed. Box is a layout tool, not a replacement for
every element. Use `createSprinkles` from `@luke-ui/react/styles` when another application-owned
element needs the same responsive layout properties without wrapping it in a `Box`.
`createSprinkles` passes through its own enumerable string-keyed non-utility props and replaces any
input `className` or `style` with the generated values.

## Responsive values [#responsive-values]

Properties passed to `Box` and Sprinkles accept either a direct value or an object keyed by
breakpoint. Layout utility props exposed by layout components accept the same responsive form.

Responsive values resolve against the nearest ancestor size container. Luke UI uses the document
root as the fallback. Use `Container` when descendants should respond to a nearer content area.
Component-responsive styles always query an ancestor. They do not query the component itself.

Portalled content leaves containers around its trigger and resolves against the nearest size
container at its portal location, falling back to the root when there is none.

The root container measures its own content box, which can differ from the browser viewport width by
the width of a visible scrollbar. A breakpoint set exactly at the viewport width can miss by a few
pixels when a scrollbar is present.

| Breakpoint | Minimum container inline size |
| ---------- | ----------------------------- |
| `initial`  | 0px (base)                    |
| `bp640`    | 640px                         |
| `bp768`    | 768px                         |
| `bp1024`   | 1024px                        |
| `bp1280`   | 1280px                        |
| `bp1536`   | 1536px                        |

Each breakpoint is a fixed constant, not a theme token. A custom theme cannot change these sizes.
Every breakpoint is a minimum inline size, so there is no maximum size or range condition. A value
set at `bp640` also applies at `bp768` and above, unless a later breakpoint overrides it. Values
cascade up from `initial`, so specify only the points where the layout changes.

Import `breakpoints` from `@luke-ui/react/styles` when you author `@container` queries against the
same thresholds Luke UI responsive props use.

apps/docs/src/examples/layout/breakpoints.tsx

```tsx
import { breakpoints } from '@luke-ui/react/styles';
import { vars } from '@luke-ui/react/theme';
import { ExampleItem } from '#docs';

export default () => {
	return (
		<>
			<style
				dangerouslySetInnerHTML={{
					__html: `
				.layout-breakpoints {
					display: flex;
					flex-direction: column;
					gap: ${vars.space.sp12};
				}

				@container (inline-size >= ${breakpoints.bp768}px) {
					.layout-breakpoints {
						flex-direction: row;
					}
				}
			`,
				}}
			/>
			<div className="layout-breakpoints">
				<ExampleItem style={{ flex: 1 }}>First</ExampleItem>
				<ExampleItem style={{ flex: 1 }}>Second</ExampleItem>
			</div>
		</>
	);
};
```

apps/docs/src/examples/box/responsive-layout.tsx

```tsx
import { Box } from '@luke-ui/react/box';
import { Text } from '@luke-ui/react/text';
import { vars } from '@luke-ui/react/theme';

export default () => {
	return (
		<Box display="flex" flexDirection={{ initial: 'column', bp768: 'row' }} gap="sp12">
			<Item />
			<Item />
		</Box>
	);
};

function Item() {
	return (
		<Box
			alignItems="center"
			display="flex"
			justifyContent="center"
			padding="sp16"
			style={{
				backgroundColor: vars.color.background.neutral.solid.rest,
				flex: 1,
				minBlockSize: '4rem',
			}}
		>
			<Text
				elementType="span"
				fontWeight="label"
				style={{ color: vars.color.foreground.neutral.onSolid }}
			>
				Item
			</Text>
		</Box>
	);
}
```

Set a responsive value when the layout needs a deliberate change. Prefer intrinsic wrapping when the
content can adapt without a breakpoint.

## Spacing and sizing [#spacing-and-sizing]

Padding, gap, and margin accept `0` plus value-based spacing keys such as `sp16` and `sp24`. The
number in each key reflects its value at the default 16px root and is emitted as `rem`. Margin also
accepts `auto`. Sizing and grid-placement properties accept their CSS values.

Use logical properties such as `paddingInline`, `marginBlockStart`, and `maxInlineSize`. They work
in both writing directions without a second layout rule.

## Visual styles [#visual-styles]

The layout properties include theme-backed background, border colour, radius, and depth values, plus
fixed border width and style values. Typography and interaction states stay with a component API.
When a custom element that is not a Box needs a visual token, use `vars` from
`@luke-ui/react/theme`. Semantic values follow the active identity and colour mode, while Luke UI
defines its spacing scale and typography styles in source.

## Continue learning [#continue-learning]

<Cards>
  <Card href="/components/layout/stack" title="Stack">
    Stack children on the block axis.
  </Card>

  <Card href="/components/layout/cluster" title="Cluster">
    Cluster lays out children on the inline axis with wrapping by default.
  </Card>

  <Card href="/components/layout/grid" title="Grid">
    Lay out children in an explicit equal column count.
  </Card>

  <Card href="/components/layout/auto-grid" title="AutoGrid">
    Lay out children from a minimum column inline size.
  </Card>

  <Card href="/components/layout/track" title="Track">
    Align rails beside flexible inline content.
  </Card>

  <Card href="/components/layout/container" title="Container">
    Constrain content and establish a local size container.
  </Card>

  <Card href="/components/layout/aspect-ratio" title="Aspect ratio">
    Lock media to an inline-to-block ratio.
  </Card>

  <Card href="/components/layout/scroll-fade" title="Scroll Fade">
    Fade scrollable content at its edges.
  </Card>

  <Card href="/components/layout/box" title="Box">
    See the Box example, props, and custom element rendering contract.
  </Card>

  <Card href="/docs/styling" title="Styling">
    Learn where layout utilities sit beside components.
  </Card>
</Cards>
