CSS - Feature Queries (@supports)

Excluding Microsoft Edge's old CSS Grid implementation with feature queries

The challenge is Microsoft Edge, the only modern browser that, as of this writing, still uses the old grid specification. It returns true for @supports (display: grid) {}, even though its grid support is spotty and non-standard. Most relevant for our example is the lack of support for the grid-template-areas and grid-area properties and for the minmax() function. As a result, a feature query targeting display: grid would not exclude Microsoft Edge, and users of this browser would be served a broken layout. To resolve this issue and serve up grid layouts to Microsoft Edge only when the browser gets full support for the specification, target one of the unsupported features instead:

Code language: CSS

@supports (grid-area: auto) {}

Is it really safe to start using CSS Grid Layout?

The really short version? Absolutely. Slightly longer version:

Grid is new! Surely it has terrible browser support?

CSS Grid Layout shipped into Chrome, Firefox, Opera and Safari in March of this year. Microsoft Edge currently have an updated Version of Grid available behind a flag in Preview builds. At the time of writing, Can I Use indicates a global availability of CSS Grid Layout of 65.64%, rising to 70.75% if you include the prefixed version in IE10, 11 and current Edge. This is a rate of adoption we’ve never seen before for such a huge feature. It isn’t surprising that people don’t realise how many visitors will have support.

[…]

And non-supporting browsers?

CSS has the solution for you. To start with, defined in the Grid and Flexbox specifications are exactly how those specifications overwrite older layout methods.

Therefore if you want to use floats, inline-block, multiple-column layout, flexbox or even display: table as a fallback for your grid layout then the spec has you covered. You can overwrite those methods in a safe and predictable way. I made a cheatsheet explaining the fallbacks. I also cover several of these in my talk which was recorded at Render Conference earlier this year.

CSS also has Feature Queries. These have really great browser support, and the nice thing about Feature Queries is that you don’t need to concern yourself with the browsers that don’t support feature queries. There is no browser supporting Grid Layout and not supporting Feature Queries.

[…]

Generally you will then have a few things in the fallback CSS that will “leak through” to the grid layout. This is often widths on items as we need to assign widths to items in legacy layout to fake something that looks like it is using a grid. Therefore we use a simple feature query, checking for support of Grid Layout, and there we perhaps set widths back to auto.

Old browsers are not your fault, but they are your responsibility

The fact old browsers exist is not your fault. Don’t start these discussions by acting as if it is your failing that you can’t get the site looking identical in all browsers released in the last 10 years, while using technology only released this year. It’s not your fault, but it is your problem. It is your problem, your responsibility as a web professional to get yourself into a position where you can take the right course of action for each project.

The limits of @supports

@supports may be very useful, but it can only tell you so much, especially in the case of browsers that will return true, technically supporting the feature, but having a buggy implementation. This is a case where we can often assume too much about a browser based on a reductive test that isn’t guaranteed to tell us what we think it does. PPK explains:

If a mobile browser doesn’t support background-attachment: fixed in practice, what happens when you do this?

Code language: CSS

@supports(background-attachment: fixed) {
	// CSS
}

Does it return false because the mobile browser doesn’t support it? Or does it return true because its desktop version supports it? With my background-attachment test data in hand I could now answer this question.

All mobile browsers return true for both fixed and local. Only 3 out of 23 browsers speak the truth here. See the test case and the inevitable table for more details.

[…]

What’s clear from these tests is that @supports is only useful when you’re detecting entire CSS modules such as flexbox. So the check below makes sense.

Code language: CSS

@supports (display: flex) {
	// flexbox layout
}
 
@supports not(display: flex) {
	// float layout
}

This example is likely safe. If a browser decides to support flexbox, display: flex is the first item on the agenda, so detecting it makes perfect sense. (It’s theoretically possible, though, that a browser fakes display: flex support in order to end up on the right side of some support detects. But as far as I know this is not the case today.)

On the other hand, if a browser has flaky support for, I don’t know, justify-content, a more precise check like this may or may not work, depending on how the CSS parser is written:

Code language: CSS

@supports (justify-content: space-around) {
	// may or may not fire correctly in case
	// of a browser bug
}

So this example is unsafe. Don’t use @supports for such detailed compatibility questions.