The Fit engine (fit.js) shrinks a horizontal row to fit its
container — degrading the least-important slots first, lowest priority first,
and restoring them as space returns. It powers the navbar, but it's not
navbar-only: call pureAdmin.components.fit.init(el) on any flex
row (a toolbar, a filter bar, a card's action cluster).
data-pa-fit="hide|steps|sidebar" makes an element a slot;
data-pa-fit-priority orders them (lower goes first);
data-pa-fit-auto on a container folds in every child
without tagging each; data-pa-fit-ignore pins one out entirely;
and pureAdmin.config.fit.defaultPriority (or a container's
data-pa-fit-default-priority) sets the fallback rank.
Drag the sliders — or just open this page on a narrow phone —
to watch each row fold.
1 · Card toolbar — shrink, don't lose
A steps slot degrades full label → icon-only → gone
instead of vanishing outright, so an action stays reachable as an icon before
it's dropped. Here Save is pinned full
(data-pa-fit-ignore); Duplicate and
Export shrink to icons (higher priority survives longer);
Delete is un-tagged, so it inherits the toolbar's
data-pa-fit-default-priority="20" and drops first.
Drag left: Delete drops → Export shrinks to its icon, then drops → Duplicate shrinks → only Save remains, always full.
2 · Product card — chart ↔ KPI
A different job needs a different tool. Swapping a rich chart
for compact KPI numbers is a 2-D layout change, not a 1-D row
fold — so this one is a pure CSS container query on the card,
no JS engine. Left half stays product info (category, title, code); the right
half shows the Chart.js sparkline while there's room and swaps to a
pa-stat KPI once the card narrows past 45rem (450px). Every
visible piece — pa-card, pa-badge, pa-stat,
the chart — is a real component.
Arabica Cold Brew
SKU-4471 · 1 L bottle
Drag left (or view on a phone): past 45rem the chart gives way to
the KPI stat — same data, denser. Drag right to bring the chart back.
Same card, no slider — resize your browser window
Identical card, but with no .fit-stage wrapper and no
slider — it's just full-width in the page. The container query reads
the card's real width, so drag your browser window narrower and the
chart becomes the KPI on its own. (The sidebar eats ~250px, so the card hits
the 450px breakpoint while the window is still ~730px.) This is the production
behaviour; the slider above only simulated it.
Arabica Cold Brew
SKU-4471 · 1 L bottle
3 · Rich product card — degrade on multiple levels
The real power shows when one card restyles on several axes at once.
This product card is a single CSS container query with three
widths. As it narrows, the three data panels
(Orders · Stock · Sales) collapse from a
3-column grid into tabs, then the tab labels
drop to icons only; in step, the header sheds its supplier,
then its packaging line and trend badge. Every visible piece —
pa-badge, pa-stat, pa-tabs,
pa-dot-leaders — is a real component; only the layout switches.
Arabica Cold Brew
Orders
Stock
Sales
Three levels, one query. ≥640px → the 3-panel grid; 340–640px → tabbed with labels; <340px → icon-only tabs. Drag slowly and watch the header drop its supplier, packaging, then trend badge at the matching steps — nothing is re-fetched or re-rendered, the same markup just re-flows.
4 · Same card, on the engine — with a chart it builds on demand
This is example 3's product card again — the same three-level degrade
(3-panel grid → tabs → icon tabs) with the same header
trimming — but driven by the Container Breakpoint engine
instead of a CSS @container. Why bother, if CSS already did it?
Two things CSS can't: the engine toggles a real .d-none
class you can watch hop in devtools (not an invisible computed
display:none), and it fires an event — so the
grid-only revenue chart is built only when the card is
wide enough to show it, and destroyed otherwise. Watch the log.
data-pa-breakpoints='{"icons":0,"tabs":34,"grid":64}' names the
three modes; each swappable piece carries data-pa-show="grid" /
"grid tabs" / "tabs" and the engine toggles
.d-none on the ones out of mode. [data-mode="grid"]
still does the one thing that's a real layout change rather than a show/hide —
the 2-D panels grid — and the pa:breakpoint event drives the
chart's build / destroy. Every visible piece is a real pa-* component.
data-pa-breakpoints are rem — minimum widths of
the card itself (its content-box inline size), not the viewport and
not percentages. pure-admin's root font-size is 10px, so
34 = 340px and 64 = 640px — the same numbers as the
@container breakpoints in example 3. The engine picks the
largest mode whose width the card has passed (700px → grid,
500px → tabs). Prefer pixels? Add
data-pa-breakpoint-unit="px" and write
{"icons":0,"tabs":340,"grid":640} — identical behaviour.
Percent isn't a unit here on purpose: "does this layout fit" is an
absolute-pixel question (label widths, gaps, padding); for viewport-relative
rules reach for a CSS media query instead.
Arabica Cold Brew
Orders
Stock
Sales
steps to keep something reachable, hide for
supplementary bits. A container query (example 2) is for a
2-D layout swap — chart ↔ KPI, sidebar ↔ drawer, and
(example 3) several swaps stacked into one query: panels → tabs → icons plus
header trimming, all keyed off the card's own width. And when the hidden
branch is expensive (a chart, a date-picker, a shadow-DOM
widget), reach past CSS for the Container Breakpoint engine
(example 4): same width thresholds, but it emits an event so JS can
build the widget only when its mode is on screen and tear it down
otherwise — the piece a Svelte/LiveView wrapper turns into real
mount/unmount. None of these is a form-reflow engine: for fields wrapping to
new lines, use the grid / flex-wrap.