#CSS
8 posts
Using @layer to make CSS precedence a declared order, not a specificity fight
Runaway styles come from everyone solving problems by adding specificity. Cascade layers make the order explicit: between layers only order matters, and specificity applies within a layer.
Anchors hidden behind a sticky header: one scroll-padding-top for the whole site
A sticky header covers every anchor target. scroll-margin per heading always misses one; scroll-padding-top on the scroll container does not, fed by the real header height.
Use the native dialog element: you get more than you think
A hand-rolled modal needs a focus trap, ESC handling, scroll locking and focus restore. Native dialog with showModal has all of it plus ::backdrop, and one style rule as the price.
Dark mode forms stay white: color-scheme is the switch
Painting a dark background does not darken native controls. Select popups, date pickers and autofill follow color-scheme; accent-color only reaches checkboxes and sliders.
Stop guessing the header height: measure it with ResizeObserver
A wrapping navigation, late webfonts and changing content all break constants written into CSS. A ResizeObserver watches the element and writes the measured value back into a variable.
Design tokens: one file that runs the whole site
Why every colour, spacing step and corner radius lives in _tokens.scss — and why changing this site's entire visual direction only touched two files.
Turning screen-printing limits into design tokens
This site's visual direction is Riso screen printing. What I actually built was the printing constraints as tokens, so retheming touched two files and no component changed.
A theme-switch ripple with the View Transitions API
A circle growing from the click point reveals the new theme. The radius must reach the farthest corner, and the custom properties must be cleaned up or they leak into the next switch.
