Skip to content
AgileLogics
6 min read

Feature Queries and Progressive Enhancement

Prerequisites: Anchor positioning, popovers, and view transitions

New CSS ships constantly. Progressive enhancement means writing a solid baseline that works everywhere, then layering improvements that only apply where supported.

Fallbacks through the cascade

Browsers ignore declarations they don't understand, so write the safe value first:

.hero {
  min-height: 100vh;
  min-height: 100dvh;
}

.title {
  color: #3b5bdb;
  color: oklch(55% 0.18 265);
}

Browsers that know dvh and oklch() use the second declaration; others keep the first.

@supports

.gallery { display: flex; flex-wrap: wrap; gap: 1rem; }

@supports (display: grid) {
  .gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr)); }
}

@supports not (anchor-name: --a) {
  .tooltip { position: static; }
}

@supports selector(:has(a)) {
  .card:has(img) { padding-top: 0; }
}

@supports (color: color-mix(in oklab, red, blue)) and (container-type: inline-size) {
  .panel { background: color-mix(in oklab, var(--brand) 8%, white); }
}
  • @supports (property: value) tests a declaration; selector(...) tests a selector; combine with and, or, not.
  • JavaScript has the same test:
<script>
  console.log(CSS.supports("display", "grid"));
  console.log(CSS.supports("color: oklch(50% 0.1 200)"));
  console.log(CSS.supports("selector(:has(a))"));
  console.log(CSS.supports("display: magic"));
</script>
true
true
true
false

(Output from Chromium 153 — any current browser gives the same answers.)

Baseline

Baseline is a shared label from browser vendors and web.dev: a feature is "newly available" when it works in the current versions of Chrome, Edge, Firefox, and Safari, and "widely available" 30 months after that. MDN pages show the status at the top. A practical policy: use widely available features freely, newly available ones with a fallback or where failure is harmless, and anything else as an enhancement.

What's safe to use now

Flexbox, Grid, gap, custom properties, clamp(), aspect-ratio, logical properties, :is()/:where(), :focus-visible, :has(), container size queries, cascade layers, nesting, oklch(), color-mix(), and dvh are all supported by every current major browser. Newer items in this course — anchor positioning, @scope in Firefox, scroll-driven animations, cross-document view transitions, field-sizing — are best treated as enhancements for now.

Vendor prefixes

Prefixes like -webkit- are mostly history. Don't write them by hand; let Autoprefixer or Lightning CSS add the few that your browser targets still need.