Conditions
The stylesheet holds reusable visual choices;
element-local direct formatting lives in attrs.style. This page covers how
those choices vary: by environment and by what the surface is for.
There is no view-selection engine — no scoring, no extends, no “pick one
profile” step. Variation is exactly what the CSS cascade already does: rules
guarded by conditions, resolved by specificity and source order.
Environment conditions — real @media
Anything the rendering environment can answer is a native media query, so a bare file adapts in any browser with zero tooling:
| Axis | Spelling |
|---|---|
| medium | @media screen, @media print |
| viewport width / height | (min-width: …), (max-width: …) |
| orientation | (orientation: portrait | landscape) |
| color capability | (monochrome), (color) — e-ink targets |
| pointer / hover | (pointer: coarse | fine), (hover: hover | none) |
| pixel density | (min-resolution: …) |
| color scheme | light-dark() values + color-scheme (see Theming) |
An engine evaluates the same enumerated feature set in JS wherever a live browser cascade isn’t available — pagination, print materialization, and preview emulation: a renderer can enumerate every condition a sheet mentions and render it under a forced environment (a monochrome e-reader, a narrow phone, the printed page).
App conditions — data-spub-* guards
What the environment can’t answer — what the surface is for, which device class is targeted, which export is running — is applied by the hosting application (or an export pipeline) as attribute tokens on the document root, and tested by ordinary attribute selectors:
html[data-spub-intent~="edit"] main { --spub-editor-active-block: highlight; }
html[data-spub-device~="ereader"] main { font-family: serif; }
html[data-spub-package~="epub"] main { max-width: none; }
| Axis | Attribute | Tokens |
|---|---|---|
| intent | data-spub-intent |
write · edit · read · skim · annotate · proof · cover · snippet |
| device | data-spub-device |
the class vocabulary phone · tablet · desktop · ereader and open app-defined device ids in one list — either matches |
| export syntax | data-spub-syntax |
syntax ids, during an export render pass |
| package | data-spub-package |
package ids (epub), during package encoding |
| scheme | data-spub-scheme |
light | dark — the app’s explicit override |
The attributes are runtime state, never serialized into a file. In a bare browser they are absent, every guard is inert, and the unguarded rules apply — so a bare file is the read-on-screen posture, by construction. A guard adds attribute specificity, so a rule stating more conditions beats one stating fewer — the browser enforces what a scoring engine would otherwise have to compute.
The cover and snippet intents are entry-rendering intents — an
application surface rendering one work’s entry as a small visual card or a
compact text row. The guard vocabulary is fixed here; the surfaces are app
concerns.
User and application styling layers (default styles, themes, appearance tweaks) are app-internal runtime composition, never part of a file — see the app’s Themes documentation.