Search
Search
What @layer base covers, how the 23 files are grouped, and the two conventions that run through all of them.
@layer base styles native HTML elements so that unstyled markup already looks right. There is no class to apply: write <table>, <blockquote> or <input type="date"> and they are styled.
Every value comes from a custom property resolved by @uncinq/design-tokens and @uncinq/component-tokens. This package hardcodes almost nothing, so restyling is a matter of changing a token, not overriding a rule.
css/base.css imports all 23 files below, one page each.
| Page | File | Selectors |
|---|---|---|
| Body | base/body.css | body: background, text color, font family, size, weight, line-height |
| Headings | base/headings.css | h1 to h6, plus a per-level size from --font-size-heading-01 to -06 |
| Paragraphs | base/typography.css | p: block spacing and --max-width-paragraph |
| Links | base/link.css | a: colour, underline, focus ring, external-link marker |
| Lists | base/list.css | ul, ol, li in prose context, including nested indentation |
| Blockquotes | base/blockquote.css | blockquote, blockquote cite |
| Code | base/code.css | code, kbd, samp, pre, and inline code separately from block code |
| Address | base/address.css | address: removes the UA italic and resets inner paragraph spacing |
| Abbreviations | base/abbr.css | abbr[title]: dotted underline with its own offset and thickness |
| Superscript | base/sup.css | sup: raised without growing the line box |
| Page | File | Selectors |
|---|---|---|
| Figures | base/figure.css | figure, figcaption, and nested picture, img, .credit |
| Picture | base/picture.css | picture: inline-block |
| Video | base/video.css | video: fluid width, auto height |
| Tables | base/table.css | table, thead, tbody, th, td |
| Details | base/details.css | details, summary, details[open], the marker and the disclosed panel |
Six of these seven files are largely inspired by KNACSS.
| Page | File | Selectors |
|---|---|---|
| Inputs and labels | base/form.css | label, legend, and input excluding button, reset, submit, checkbox, radio and range |
| Checkboxes | base/form-checkbox.css | [type='checkbox'] when it is not a switch, plus its adjacent label |
| Radios | base/form-radio.css | [type='radio'] plus its adjacent label |
| Range | base/form-range.css | [type='range'], the .range wrapper and the .range-value output |
| Select | base/form-select.css | select and optgroup, with a token-driven chevron |
| Switch | base/form-switch.css | [role="switch"], rendered as a track and knob |
| Textarea | base/form-textarea.css | textarea, including field-sizing: content |
Text-like controls (input, textarea, select, checkbox, radio) draw their outline with box-shadow: inset and border: 0, so that focus and hover states change colour without shifting layout by a pixel. The switch and the range thumb are the exceptions: both need a real border, since their outline is part of a shape that moves.
| Page | File | Ships |
|---|---|---|
| Accessibility helpers | base/accessibility.css | .visually-hidden, .visually-hidden-focusable |
It is the only file in this layer that ships classes rather than element selectors.
Hover is guarded. Every hover style in this layer sits inside @media (hover: hover) and (pointer: fine), so nothing sticks on touch.
Motion is guarded. Every transition sits inside @media (prefers-reduced-motion: no-preference).
Redefine the token rather than the rule:
@layer base {
:root {
--table-cell-padding-block: 0.5rem;
}
}
Several files read a component-scoped property with a semantic fallback, for example var(--code-font-family, var(--font-family-code)). That gives you two levels: change the component token to affect only that element, or the semantic token to affect everything that inherits from it.