Logical Properties, Modern CSS, and Performance Hints
TL;DR
A grab-bag of modern CSS that comes up at senior level: logical properties (margin-inline, inset-block-start) that adapt to writing direction (RTL/vertical) for free; aspect-ratio to reserve space (CLS); scroll-snap for carousels; and the performance levers — content-visibility (skip rendering offscreen content), contain (isolate a subtree), and will-change (promote to a layer, used sparingly). Plus the two preference-driven features every senior wires up: dark mode (prefers-color-scheme + color-scheme) and prefers-reduced-motion.
Interview Q&A
Q: What are logical properties and why use them?
A: Flow-relative equivalents of physical properties — they follow the writing direction instead of fixed sides:
| Physical | Logical |
|---|---|
margin-left/right |
margin-inline-start/end (or margin-inline) |
margin-top/bottom |
margin-block-start/end (or margin-block) |
top/left (inset) |
inset-block-start / inset-inline-start |
width/height |
inline-size / block-size |
border-top-left-radius |
border-start-start-radius |
In an RTL locale, margin-inline-start automatically becomes the right side — so one stylesheet works for LTR and RTL without flipping. Essential for internationalized apps; good default even for LTR-only.
Q: What does aspect-ratio do?
A: Sizes a box to a ratio so space is reserved before content loads — preventing layout shift (CLS):
.video { aspect-ratio: 16 / 9; width: 100%; } /* height derived; no jump when the iframe loads */
img { aspect-ratio: 3 / 2; width: 100%; height: auto; }
Pair with width/height attributes on <img> for the best result (../01_html/02_responsive_images.md).
Q: How does scroll-snap work?
A: Declarative snapping for carousels/galleries — no JS:
.carousel { scroll-snap-type: x mandatory; overflow-x: auto; display: flex; }
.slide { scroll-snap-align: start; flex: 0 0 100%; }
mandatory always snaps; proximity snaps only when close. scroll-driven animations (animation-timeline: view()/scroll()) extend this to tie animation progress to scroll position, also without JS.
Q: What are content-visibility and contain?
A: Performance hints that limit how much the browser renders:
content-visibility: auto— skips rendering (layout/paint) of offscreen elements until they’re near the viewport, withcontain-intrinsic-sizeto reserve approximate space. Massive win for long lists/articles — the browser does layout only for what’s visible..post { content-visibility: auto; contain-intrinsic-size: auto 500px; }contain: layout/paint/size/style— promises the browser a subtree is independent, so changes inside don’t reflow/repaint the rest.contain: contentis a common bundle. Reduces the scope of layout work.
Both improve rendering performance on large pages — see ../15_performance/.
Q: When should you use will-change?
A: Sparingly. will-change: transform hints the browser to promote an element to its own compositor layer before an animation, avoiding a first-frame jank. But it costs memory, creates a stacking context, and overuse (or leaving it on permanently) hurts performance. Apply it just before animating and remove it after; never put will-change on many elements “to be safe.” Prefer animating only transform/opacity (compositor-only, no layout/paint).
Q: How do you implement dark mode in modern CSS?
A: CSS variables + prefers-color-scheme, with color-scheme so form controls/scrollbars adapt too:
:root { color-scheme: light dark; --bg: white; --fg: #111; }
@media (prefers-color-scheme: dark) { :root { --bg: #0b0b0b; --fg: #f5f5f5; } }
[data-theme="dark"] { --bg: #0b0b0b; --fg: #f5f5f5; } /* explicit override */
body { background: var(--bg); color: var(--fg); }
Default from the OS preference, allow an explicit toggle to override, and set color-scheme so native UI (inputs, scrollbars) matches. Token details: ../08_component_libraries/design_tokens_and_theming.md.
Q: What is prefers-reduced-motion and why honor it?
A: A media query for users who’ve asked the OS to reduce motion (vestibular disorders, distraction). Gate non-essential animation behind it (WCAG 2.3.3):
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
Reduce or remove large transforms/parallax; keep essential motion subtle.
Gotchas / edge cases
content-visibility: autowithoutcontain-intrinsic-sizemakes the scrollbar jump as elements render — always provide an intrinsic size estimate.will-changeleft on permanently is a known anti-pattern — wastes memory and can reduce performance; add/remove around the animation.- Animating
width/height/top/lefttriggers layout every frame (jank); animatetransform/opacityinstead. - Mixing logical and physical properties for the same side can conflict; commit to logical for i18n.
- Dark mode flash (FOUC) — set the theme before first paint via an inline script; don’t wait for React hydration (../19_rendering_modes/).
aspect-ratiowith explicit height — if both are set and conflict, height wins and the ratio is ignored; let one dimension be derived.
What a senior is expected to say
- “Logical properties (
margin-inline,inset-block-start) adapt to writing direction — one stylesheet for LTR/RTL.aspect-ratioreserves space to avoid CLS.” - “
content-visibility: auto(withcontain-intrinsic-size) skips offscreen rendering — big win on long pages;containscopes layout/paint. I animate onlytransform/opacity.” - “
will-changeis a sparing, temporary hint — leaving it on costs memory and backfires.” - “Dark mode via CSS vars +
prefers-color-scheme+color-scheme, with a pre-paint script to avoid the flash; and I always honorprefers-reduced-motion.”
Cross-references
- Rendering perf (layers, reflow/repaint): ../15_performance/
aspect-ratio+ responsive images: ../01_html/02_responsive_images.md- Theming/tokens and the dark-mode flash: ../08_component_libraries/design_tokens_and_theming.md, ../19_rendering_modes/
- Reduced motion as an a11y concern: ../16_accessibility/01_wcag_and_pour.md
Further reading
- MDN — CSS logical properties: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_logical_properties_and_values
- MDN —
content-visibility: https://developer.mozilla.org/en-US/docs/Web/CSS/content-visibility - web.dev —
content-visibility: https://web.dev/articles/content-visibility - MDN —
prefers-reduced-motion: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion