Skip to content
RU
Scale
Density
Theme
Accent

Layout

Split

Two columns of differing importance: the main one and the side one. It wraps by itself when the main part stops having its threshold — with not a single media query.

The component
split-side
The wanted width is 18rem. Filters, properties, a summary.
split-main
It takes the remainder. Narrow the region — the columns stand one under another, and not one @media was needed for that.
Markup
<div class="inst-split">
  <div class="inst-split-side inst-card">
    <div class="inst-card-title">split-side</div>
    <div class="inst-card-sub">The wanted width is 18rem. Filters, properties, a summary.</div>
  </div>
  <div class="inst-split-main inst-card">
    <div class="inst-card-title">split-main</div>
    <div class="inst-card-sub">It takes the remainder. Narrow the region — the columns stand
      one under another, and not one @media was needed for that.</div>
  </div>
</div>

Contract

What Required Why
An inst-split-main and an inst-split-side yes Both parts are wanted: a split is about a layout of differing importance, and without the second it degenerates into a block
The order in the markup = the order on wrapping yes order parts the visual order from the keyboard one, and Tab starts jumping across the screen
The thresholds through --split-side and --split-main yes Roles of tier 3, overridden on the container rather than inside the component
An inst-stack inside a part holding more than one block yes A part of a split is a share of the width, not a column of the flow: it has no gap of its own, and two panels stand flush. The gap is put by the stack; the part cannot put it itself — the class is also worn by a component (inst-split-side inst-card), and the gap would then land inside the card
A media query no The wrapping is done by the intrinsic size: it works inside a narrow panel and in a modal alike

Accessibility

Order The visual order equals the order of the markup. order is not used: it parts Tab from the picture
Zoom The wrapping fires on an increase of type size too: the thresholds are set in rem, so the columns fold along with the growth of the text rather than after it
Landmarks The parts are <div>s. If the side part is complementary content, put an <aside>
Scrolling A split scrolls nothing itself. Independent scrolling is the work of the shell and the panel

Anatomy

The wrapping is achieved not by a query but by two numbers:

The part The rule Which means
inst-split-side flex: 1 1 var(--split-side) A wanted width of 18rem. Ready to squeeze and to stretch
inst-split-main flex: 999 1 0 + min-inline-size: min(var(--split-main), 100%) It takes almost the whole remainder but does not squeeze below 30rem

When the main part stops having its minimum, flex-wrap moves the side one below, and both take the full width. That is the first level of responsiveness — the intrinsic one: it works where there is no container ancestor, inside a narrow panel and in a modal alike.

The min() in the minimum is required: without it a main part of 30rem does not fit into a region of 24rem and sticks out along with a horizontal scrollbar.

The order

The order in the markup is the order on wrapping. If you want the main part on top on a narrow screen, put it first:

<div class="inst-split">
  <div class="inst-split-main">…</div>
  <div class="inst-split-side">…</div>
</div>

order is not used for that: it parts the visual order from the keyboard one, and Tab starts jumping across the screen.

Composition

A list and an inspector

<div class="inst-split">
  <div class="inst-split-main inst-panel">
    <div class="inst-panel-header"><span class="inst-panel-title">Queue</span></div>
    <div class="inst-panel-body inst-panel-body--list">…</div>
  </div>
  <div class="inst-split-side inst-panel">
    <div class="inst-panel-header"><span class="inst-panel-title">Properties</span></div>
    <div class="inst-panel-body">…</div>
  </div>
</div>

With a stack inside

<div class="inst-split">
  <div class="inst-split-main inst-stack">…</div>
  <div class="inst-split-side inst-stack inst-stack--tight">…</div>
</div>

Customization

/* A narrow column of properties, an early wrap */
.inspector-split {
  --split-side: 14rem;
  --split-main: 24rem;
}

Both variables are roles of tier 3, so they are overridden on the container rather than inside the component.

API

Classes
NameWhat it does
class
inst-splitThe container. A row that wraps, with a gap of --pad-panel
inst-split-mainThe main part. It takes the remainder and goes no narrower than --split-main
inst-split-sideThe side part. Its wanted width is --split-side
Tokens
NameValueWhere from
variable
--split-sideThe wanted width of the side part18remthe application sets it
--split-mainBelow this the main part wraps underneath30remthe application sets it
token
--pad-panelvar(--space-5)base +14: density · scale

Why the kit works this way — the constitution · Open source under MIT, github.com/keshon/instrument