DEV Community

Dom Habersack
Dom Habersack

Posted on • Updated on • Originally published at islovely.co

Progressive enhancement with @supports [video]

Designing beautiful websites is getting easier. Flexbox and grid enable layouts that were impossible before. Transforms and filters add visual effects that would be difficult to build otherwise. Unfortunately, not all browsers support all those cool new features yet.

Internet Explorer is no longer the anchor holding us back. Today’s browsers all support these sometimes experimental features to a different degree. Some support grid, some support backdrop-filter, some support WebP, some support sticky headers. No single browser supports every upcoming feature.

We can approach this situation in several ways, and they all have their drawbacks:

  • We can avoid using the new capabilities until all browsers support them. That could take years.
  • We can go all-in on our favorite browser and ignore all others. Our layouts will look good in a single browser, but break in many of the others.
  • We can use “polyfills” that enable the features in more browsers, usually through a lot of JavaScript. Throwing more code at a problem adds complexity and new points of failure to our products.

Trying to make the exact same design happen in every browser is not worth these tradeoffs. Instead, we can deliver a basic styling that is “good enough” and works everywhere. We can then enhance that version with the new features only for browsers that support them.

With @supports, we can adjust the styling based on which features a browser supports. We could use a plain layout everywhere, and improve it with grid in browsers that understand it.

.my-container {
  display: block;
}

/* test if this browser supports grid */
@supports (display: grid) {
  .my-container {
    display: grid;
  }
}
Enter fullscreen mode Exit fullscreen mode

We can also test if a browser supports custom properties (CSS variables) and only use them when it does. For browsers that don’t support this feature yet, we define fallbacks outside of the @supports-block.

body {
  background-color: #f6f9fc;
  color: #28303f;
}

/* test if this browser supports custom properties */
@supports (--anything: red) {
  body {
    background-color: var(--body-background);
    color: var(--body-text);
  }
}
Enter fullscreen mode Exit fullscreen mode

As soon as a new browser supports a feature, the feature-gated styles will work for it. This is much more future-proof than building IE-only stylesheet like we did a few years ago. @supports is the future.

Top comments (0)