Skip to contentAsheeUIAsheeUI

Split

Two panes side by side when there is room, stacked when there is not.

A split is two things and a rule for when to put them beside each other. Above the breakpoint you name the panes share the width; below it they stack in the order you wrote them, so a narrow screen reads them as a column rather than losing one.

It is narrower than Grid on purpose, two panes, never three, and cleverer than Stack, because the panes know how much of the width each takes and when to stop sitting side by side. That is the shape of a documentation page, a settings screen and a master–detail view: a subject beside its context.

Usage

import { Card, Split } from "@asheeui/web";

<Split
  stackAt="md"
  ratio="start"
  start={<p>The article.</p>}
  end={<Card title="Summary">£4,280.00</Card>}
/>

The primitive carries no width, no gutter and no background of its own: each pane is as wide as the layout allows, and the content inside it decides how it looks. That is what makes the same element a sidebar beside an article and a comparison of two cards.

The breakpoint

stackAt is sm, md, lg or xl and defaults to lg. Below it the panes are a column; at it and above they are a row. The switch is a class variant rather than an unmount, so both panes are always in the document, nothing is hidden below the breakpoint, and the reading order is the order you wrote them in at every width.

Choose the breakpoint by the content rather than by the device. A narrow aside fits beside an article from md, while two columns of real text need xl before they stop being cramped. A pane can also be omitted: start or end on its own renders a single pane, which is how a layout that grows a second pane at a breakpoint starts.

Ratio, divider and a sticky second pane

ratio divides the width once the panes sit side by side: equal halves it, start gives the first pane two thirds, and end gives the second pane two thirds. The division is written as a flex basis, so the two panes and the gap between them still add up to the width.

divider draws the boundary between the panes, a horizontal rule while they are stacked and a vertical one once they are side by side, because the utility follows the flex direction. It is a surface detail rather than a semantic one, so it is off unless you ask for it, and it is worth asking for when two bordered panes would otherwise float into each other.

stickyEnd pins the second pane while the first scrolls, which is what a table of contents or a summary column wants. A sticky pane also stops stretching, so it moves within its parent instead of being stretched to the parent's height; the effect needs the page to scroll before it does anything at all.

Props

stackAt, ratio, gap and align are registered by the component as lg, equal, lg and stretch, so each resolves from the instance, then components.split, then that value. divider and stickyEnd are intentionally not registered: a rule between panes and a pane that follows the scroll are decisions about one layout rather than about the product, so they stay off unless the instance or the application says otherwise.

Accessibility

  • Neither pane is hidden, removed or reordered below the breakpoint: both are in the document, in the written order, so a reader hears start then end at every width and no content depends on a wide window.
  • The component adds no role, landmark or tabindex, so each pane is read as whatever it contains. A pane that is navigation should hold the navigation component, so the landmark and its name come from the component that knows them.
  • divider is a border drawn by the container's divide utility, decoration with no announcement, so the boundary between two panes is never the only thing that says where one ends.
  • A sticky second pane follows the scroll visually and keeps its place in the document, so the keyboard order does not change when it pins.

The gap, the alignment words and the as prop come from the layout family rather than from this component, see Layout and spacing.

Native

The compatibility matrix records the platform's equivalent as Split: @asheeui/native exports the same component with the same stackAt, ratio, gap, align and divider, and the same division of the width. It reads the window through useBreakpoint instead of a media query, so the direction is decided in the render pass rather than by a stylesheet. stickyEnd is a shared option the platform leaves alone, because the platform has no scroll-linked positioning. See React Native.