CSSProgressive Enhancement & Graceful Degradation

Progressive Enhancement & Graceful Degradation

When a feature won't work identically for every visitor, you have to decide which direction to build in: start simple and add capability, or start capable and add fallbacks. These are two related but distinct philosophies for handling that gap, and they lead to noticeably different outcomes in practice.

Two Philosophies

Approach

Starting point

Direction of work

Progressive enhancement

A solid baseline experience that works everywhere, using only well-supported features.

Layer on enhancements for browsers that support more, typically gated behind @supports checks.

Graceful degradation

The full-featured, modern experience, built first with newer CSS.

Add fallbacks for older browsers afterward, as a secondary pass.

Both approaches acknowledge the same reality — not every browser supports every feature — but they differ in what gets tested and maintained by default. With progressive enhancement, the baseline is the thing you build and test first, so it is guaranteed to work. With graceful degradation, the fallback path is added on top of already-built modern code, which means it is easy to forget, easy to under-test, and easy to let quietly rot as the modern code evolves without anyone re-checking the fallback.

Example: Same Feature, Two Directions

CSS
/* Progressive enhancement: baseline first, enhancement layered on */
.gallery {
  display: flex;       /* baseline every browser gets */
  flex-wrap: wrap;
  gap: 1rem;
}
@supports (display: grid) {
  .gallery {
    display: grid;      /* enhancement, only if supported */
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  }
}

/* Graceful degradation: modern feature first, fallback bolted on after */
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 1rem;
}
@supports not (display: grid) {
  .gallery {
    display: flex;      /* fallback added as an afterthought */
    flex-wrap: wrap;
  }
}

The CSS output can end up almost identical, but the mindset behind writing it is different — and that mindset shows up in which path gets bugs fixed first, which path gets tested in CI, and which path someone remembers to update when the design changes six months later.

Why the Distinction Matters

Graceful degradation is generally considered the less robust approach today. Because the modern experience is built and shipped first, the fallback path often only gets exercised by a small minority of real users (or none, until a browser update changes support), so regressions in the fallback tend to go unnoticed for a long time. Progressive enhancement flips the risk: the baseline is exercised by everyone, all the time, so it is far more likely to be correct and to stay correct.

Recommended mindset
Default to progressive enhancement for durable, resilient websites. Ship a baseline that works with no advanced CSS at all, verify it actually works, and then layer on enhancements with @supports (see @supports Feature Queries) for browsers that can handle more. It costs a little more up front, but it fails safely — a visitor on an unusual or older browser gets a working page, not a broken one.