Broader Ideas
content-visibility versus virtualization
Two answers to "this list is too long", with very different costs:
content-visibility: auto | virtualization | |
|---|---|---|
| Code | one CSS declaration | scroll handling, measurement, windowing, key management |
| DOM | full (261,011 nodes, measured) | small |
| Memory | full DOM retained | bounded |
| Find-in-page | works | broken for unrendered rows |
| Sequential focus / a11y | works | needs care |
| Scroll restoration | browser handles it | you handle it |
| Measured initial layout | 7.9 ms vs 401.9 ms | comparable, at much higher complexity |
Try the declarative option first. Virtualization remains necessary when the DOM itself is the constraint — memory on low-end devices, or hundreds of thousands of rows — but it buys DOM size at the cost of correctness features the browser was giving you free. Measured properly in fe-30.
Layers make the CSS strategy decision reversible again
Much of the appeal of CSS Modules, styled-components and utility-first CSS was escaping specificity conflicts — hashing, scoping, or abolishing the cascade because coordinating it across teams had failed.
Cascade layers address that directly and structurally. A decision made in 2019 to adopt runtime CSS-in-JS "because our CSS was unmanageable" was reasonable then and may not be now. That makes it a good candidate for the re-examination process in fe-49 (migrations) and a standing item on a technology radar (fe-50).
The general pattern is worth naming: platform capability changes invalidate past architectural decisions. A Principal Engineer's job includes noticing when a constraint that justified a decision has quietly disappeared — nobody sends a notification.
Design tokens are a cascade decision
The token pipeline that survives contact with multiple teams:
design source (Figma / JSON)
↓ build
CSS custom properties in an early @layer
↓ inherited, runtime-overridable
components consume var(--token)
↓
themes / density / brands override at any subtree
Two properties this gets which preprocessor variables cannot: runtime overridability (theme
switching, per-subtree density, user preferences) and a JS interop boundary
(getComputedStyle(el).getPropertyValue('--x')).
The cost, which should be designed for rather than discovered: a token rename is a runtime break, not a compile error. Mitigations — generate the token layer from one source, type the consumer API, keep deprecated aliases for one major version — are the substance of fe-38.
Containment as an architectural contract
contain: layout is a claim about a component's boundaries: nothing inside can affect layout
outside. That is the same claim a well-designed component makes about state, data flow and side
effects.
Where this becomes interesting: a component that cannot honour contain — because it must grow
its parent, or escape its bounds — is usually a component with a leaky interface in other ways too.
Containment failure is a useful smell for design problems that have nothing to do with CSS.
The measured 80% reduction is the mechanical payoff. The architectural payoff is a boundary you can reason about, which is why this connects forward to fe-19 (application architecture) rather than only to fe-11 (performance).
Logical properties are the cheapest i18n decision you will ever make
margin-left: 1rem; /* a rewrite when RTL arrives */
margin-inline-start: 1rem; /* correct in both directions, same cost today */
Retrofitting is expensive and error-prone; adopting is free. The full RTL story — bidirectional text, mirrored icons, logical scroll direction — is fe-26, but the stylesheet-level decision is made here and should simply be a lint rule.
The same argument applies to inset, padding-block, border-inline-end, and text-align: start.
There is no case for physical properties in new code except deliberate physical positioning
(a shadow that must fall to the right regardless of writing direction).