Skip to content
Alpha

Hololink UI is under active development. Components, APIs and these docs may change without notice.

Layout

Spacing follows a 4px step scale (--p-space-N). Use the semantic aliases in your own code. They name the intent, so you can retune the rhythm in one place.

TokenValuePreview
--s-space-2xs0.25rem
--s-space-xs0.5rem
--s-space-sm0.75rem
--s-space-md1rem
--s-space-lg1.5rem
--s-space-xl2rem
--s-space-inset1rem
--s-space-stack-sm0.5rem
--s-space-stack-md1rem
--s-space-stack-lg2rem
--s-space-inline-sm0.5rem
--s-space-inline-md1rem
Token Use
--s-space-2xs Hairline gaps, icon nudges
--s-space-xs Tight gaps
--s-space-sm Control padding, gaps
--s-space-md Default gap and padding
--s-space-lg Section padding
--s-space-xl Large separation
--s-space-inset Container padding
--s-space-stack-sm, -md, -lg Vertical rhythm
--s-space-inline-sm, -md Horizontal gaps

For reference. The scale steps are 0, 4, 8, 12, 16, 20, 24, 32, 40, 48 and 64px, named by step number (1 to 16).

TokenValuePreview
--p-space-00
--p-space-10.25rem
--p-space-20.5rem
--p-space-30.75rem
--p-space-41rem
--p-space-51.25rem
--p-space-61.5rem
--p-space-82rem
--p-space-102.5rem
--p-space-123rem
--p-space-164rem

For layout, prefer the layout components over hand-written CSS: Stack, Grid and Container.

The global stylesheet (packages/ui/src/styles/global.css) imports its layers in order of increasing specificity:

  1. Settings (settings/tokens.css): the only place --p-* tokens are defined and --s-* tokens are mapped.
  2. Trumps (trumps/utilities.css): the u-* helper classes. This is the only layer where !important is tolerated. See CSS utilities.
  3. Components: each component’s CSS lives beside it (src/components/holo-*/holo-*.css), scoped by Shadow DOM with :host and flat class selectors.

Add a new global concern to the matching layer. Do not put tokens in component files or component rules in the utilities.

Components respond to the size of their container, not the viewport. Declare container-type: inline-size on a wrapper and query it with @container.

Reserve @media for user-preference queries such as prefers-reduced-motion and forced-colors. Colour scheme is handled by light-dark() in the tokens.

One
Two
Three

Drag the bottom-right corner of the frame. Below 28rem the items stack, above it they sit in a row.

.frame {
container-type: inline-size;
}
.items {
display: grid;
gap: var(--s-space-sm);
}
@container (min-width: 28rem) {
.items {
grid-template-columns: repeat(3, 1fr);
}
}

The container cannot style itself from its own query, so put the responding rules on a child, as above.

Use only these layers. Do not invent values.

TokenValuePreview
--s-z-index-dropdown100layer 100
--s-z-index-sticky200layer 200
--s-z-index-overlay300layer 300
--s-z-index-modal400layer 400
--s-z-index-popover500layer 500
Token Value Use
--s-z-index-dropdown 100 Dropdowns
--s-z-index-sticky 200 Sticky headers
--s-z-index-overlay 300 Overlays
--s-z-index-modal 400 Modals
--s-z-index-popover 500 Popovers, above everything

The primitives also define --p-z-index-under (-1) and --p-z-index-normal (1). Prefer top-layer features (<dialog>.showModal() and the popover attribute) over z-index where you can.