Skip to content

Layout utilities

Hypermedia Components ships a handful of layout utilities in the hc.utilities cascade layer. They are the responsive building blocks the rest of the system leans on — including the hc-shell application shell.

They are deliberately few and semantic. This is not a utility-first framework: there are no spacing scales sprayed across class names, no md: / lg: breakpoint prefixes. Each utility is intrinsically responsive — it adapts to the space it is given through flex-wrap, grid auto-fill, or content-based flex ratios, with no media queries. The same class behaves correctly in a full page, a dialog, a card, or a sidebar, because it responds to its container, not the viewport.

The utilities are in the full stylesheet already. For granular setups, import just this layer on top of the core:

import '@hypermedia-components/core/css/core'; // tokens + base
import '@hypermedia-components/core/css/utilities'; // this layer

Because they live in the last cascade layer, your own application CSS overrides them without specificity fights.

Every utility exposes one or two local custom properties with token-based fallbacks. Set them inline or in a wrapper rule — never add per-element variant classes:

<ul class="hc-cluster" style="--hc-cluster-gap: var(--hc-space-4)"></ul>

Children laid out in a column with one consistent gap. Knob: --hc-stack-gap (default --hc-space-3).

First
Second
Third

A horizontal group that wraps when it runs out of room — button rows, tag lists, meta bars, toolbars. Knobs: --hc-cluster-gap (default --hc-space-2), --hc-cluster-align (default center).

As many equal columns as fit at a minimum track width, then it wraps — no breakpoints. Knobs: --hc-grid-min (default 16rem), --hc-grid-gap (default --hc-space-4). The built-in min(…, 100%) guard stops a wide track from overflowing a narrow container.

A
B
C
D
E
F

Swap auto-fill for auto-fit (by setting grid-template-columns yourself) when you want a few items to stretch and fill the row instead of leaving empty tracks.

A centred column with a maximum line length and inline padding. Knobs: --hc-container-max (default 72rem), --hc-container-pad (default --hc-space-4).

<div class="hc-container">
<!-- page content, capped and centred -->
</div>

A two-part layout where the first child is the sidebar and the second is the main region. The main region keeps a minimum width; when it can no longer hold it, the sidebar wraps onto its own row. Pure flexbox, so it reflows by container width — drop it inside a narrow panel and it collapses there too, with no viewport media query. Knobs: --hc-sidebar-width (default 16rem), --hc-sidebar-content-min (default 60%), --hc-sidebar-gap (default --hc-space-4).

Main content area that keeps its width and wraps the sidebar when space runs out.

Content available to assistive technology but removed from the visual layout — skip links, labels for icon-only controls. Unlike .hc-hidden, it stays in the accessibility tree.

<button class="hc-button" type="button">
<svg aria-hidden="true"></svg>
<span class="hc-sr-only">Delete</span>
</button>

display: none !important. Wins over component rules by layer order, and the !important also beats unlayered application CSS and inline display. Use it to toggle visibility from the server (swap the class in/out) or from htmx, without inline styles.

<div class="hc-hidden">Removed from layout entirely</div>
  • Responsive design — the container-first strategy these primitives implement.
  • Tokens — the --hc-space-* scale the gaps default to.
  • hc-shell — the application shell, built on these primitives.