Understanding CSS Fallback Behavior

Updated Aug 15, 2021#css#guides

CSS is forgivable. If a browser encounters a declaration or rule it doesn’t understand, it just skips it completely without applying it or throwing an error.

This might be frustrating for you and your users if such a mistake slips through to production code, but at least it means the whole site doesn’t come crashing down because of one error, and if used cleverly you can use it to your advantage.

Not everybody on the web is using the same operating system, web browser, or even physical hardware. Providing fallbacks is the perfect solution for compromising with your many unique visitors.

There are two mainstream strategies to provide CSS fallbacks: progressive enhancement and graceful degradation.

Layout features aren’t as easy to provide graceful fallbacks for as color, shadow, or gradient simple properties. If layout properties are ignored, your entire design will likely fall to pieces.

Because of this, you need to use CSS feature queries (@supports) to detect whether visiting browsers support those layout features, and selectively apply different layouts depending on the result.

CSS feature queries let you specify declarations that depend on a browser’s support for one or more specific CSS features. The rule may be placed at the top level of your code or nested inside any other conditional group at-rule.

@supports (display: grid) {
  div {
    display: grid;
  }
}

If the browser understands display: grid, then all of the styling inside the brackets will be applied. Otherwise all of that styling will be skipped.

Progressive Enhancement

Progressive enhancement is a strategy in web design that puts emphasis on web content first. Basic content and functionality should be accessible to all web browsers. Enhanced behavior is provided progressively. - Wikipedia

In CSS, progressive enhancement can be applied to fallback strategy, starting out with mostly basic widely-supported CSS features, then adding newer ones progressively.

You provide a baseline experience that works for all users, regardless of support or failures, and then enhance the user experience for more modern browsers.

This is a a useful technique that allows web developers to focus on developing the best possible websites while making those websites work on multiple unknown user agents.

Floats are well-supported way back to IE4, Flexbox is well-supported in modern browsers but has problems in older browsers like IE, Grids are way newer than Flexbox.

Well, not all browsers support feature queries. And the browsers that do not understand feature queries will skip all blocks of code inside. That’s probably bad. You want to structure your code knowing that the oldest browsers won’t support feature queries or the feature you are testing for.

/* fallback code for older browsers */

@supports (display: grid) {
  /*
    code for newer browsers
    including overrides of the code above, if needed
  */
}

One thing can make progressive enhancement easier is that the design doesn’t require to look exactly the same everywhere, it can be simplified in old or mobile browsers, more complicated and fancier in modern desktop browsers to take advantages of modern powerful CSS features.

Is your business critical to support a tiny amount of users using IE? If not, then you’ll be amazed how few fallbacks you need to write.

This strategy doesn’t work well when you’re uncertain about number of old browsers you want to support, it’s time consuming when writing tons of fallbacks using old technologies that you might not need at all. In this case consider using graceful degradation instead.

Graceful Degradation

Graceful degradation is a design philosophy that centers around trying to build a modern web site/application that will work in the newest browsers, but falls back to an experience that while not as good still delivers essential content and functionality in older browsers. - MDN

In CSS, graceful degradation can be applied to fallback strategy, starting out with mostly latest cutting-edge CSS features to develop the best possible websites, then adding fallbacks to support old/unknown browsers gracefully.

CSS degrade gracefully by design, using an unknown CSS property might not break the whole site, but there is a good chance some parts won’t work as expected for some users.

A website design that is built to gracefully degrade is designed first with modern browsers in mind. That site is created to take advantage of the features of these modern web browsers.

If the browser doesn’t understand display: grid, then all of the styling inside the brackets will be applied. Otherwise all of that styling will be skipped.

/* using grid for modern browsers */

@supports not (display: grid) {
  /*
    default code for browsers don't support grid
    including overrides of the code above, if needed
  */
}

Well, not all browsers support feature queries. And the browsers that do not understand feature queries will skip all blocks of code inside. That’s probably bad. We can’t create a fallback by checking for browsers which do not have support feature queries using graceful degradation.

Graceful degradation can be used more easily as a patch for an already existing product, it’s not perfect but requires less initial work.

Conclusion

Theoretically we may still end up in exactly the same place when using either above strategies, but whether we start with the basic experience or the enhanced one by default is considered synonymous with our priorities.

If you prioritize everyone, then go for progressive enhancement. If you prioritize the privileged few who use the latest browsers then go for graceful degradation.

Graceful degradation and progressive enhancement have the same objective to create robust, accessible and broad-reaching solutions that work for everyone no matter their choice of browser.

One question that many web developers have is how far back in terms of browser versions should you support? There is no cut-and-dry answer to this question. It depends on the site itself.