By Craig Buckler

Native CSS Feature Detection With @supports

By Craig Buckler

Consider the following CSS snippet:

 .blur-text { color: transparent; text-shadow: 0 0 5px #000; } 

Any element with a class of blur-text will render a burred text effect:

CSS3 Blurred Text

Lovely. Unfortunately, not all browsers support text-shadow. IE9 and below apply the transparent color but do not display the shadow — the text becomes invisible. We needed to rely on JavaScript solutions such Modernizr or our own text-shadow detection code to detect CSS support and react accordingly.

Using JavaScript to detect CSS3 properties is awful. It’ll fail if JavaScript’s disabled and feels dirty. I have to bathe in disinfectant every time I do it. Fortunately, another solution has arrived in native CSS: the @supports rule. The basic syntax:

 @supports <condition> { /* rules */ } 

We’d use the following code for our blurred text:

 @supports (text-shadow: 0 0 5px #000) { .blur-text { color: transparent; text-shadow: 0 0 5px #000; } } 

You can use logical AND, OR and NOT, e.g.

 @supports ( (display: table-cell) and (display: list-item) ) { /* styles */ } 

as well as check for vendor-specific prefixes:

 @supports ( (-webkit-transform: rotate(90deg)) or (-moz-transform: rotate(90deg)) or (-ms-transform: rotate(90deg)) or (-o-transform: rotate(90deg)) or (transform: rotate(90deg)) ) { /* styles */ } 

Older browsers which don’t understand @support will not render the styles — but they’re unlikely to understand the properties you’re attempting to use.

Unfortunately, @supports has fairly limited browser compatibility. At the time of writing, only Opera 12.1 features it as standard. It’s available in Firefox 17 if the layout.css.supports-rule.enable about:config setting is changed to true. It should also be implemented in Chrome 24 but it may be some time before @support arrives in IE and Safari.

That said, @supports is promising and the days of having to use Modernizr-like JavaScript style detection are numbered.

  • Is it always necessary to specify the exact declaration you want to use for the @support query?

    So @supports (text-shadow: 0 0 5px #000), rather than just @supports (text-shadow)?

    • As I understand, you’ll need to add a value but it need not be the exact one you’re using. In some cases you should, though e.g. a browser may be able to rotate by 90 degrees but not 27 degrees.

  • Great article, thank you Craig. Sad to know its compatibility is so poor at the moment.

  • On Firefox 18, ‘layout.css.supports-rule.enable’ preference value is ‘true’ by default.

  • Erick G

    The title is misleading a little bit, isn’t it? In these days, a feature that is only available to Opera is almost… an error! :-P

  • McBenny

    I didn’t get into deep in the CSS3 specs but that @support instruction is a kind of “if” statement. Is there any kind of “else” statement?
    I guess the need to test the entire declaration (property AND value) is necessary, maybe not for integer value but mostly for keywords value (think to start position in gradients for example).
    May be CSS will become a real programming language?

    • You shouldn’t really need an else since everything outside the squiggly brackets should be parsed by every browser.

      CSS is receiving an increased number of programming-like constructs. It makes me feel a little uncomfortable, but they’re very useful!

  • Hmmmm… all that extra markup for two browsers (three in a few weeks) to check for things they should support since they’re the latest versions and should be rocking the latest in standards support?

    Since just about every browser out there aside from the latest from two (almost three) vendors supports this, one would still need fallback markup for those browsers that don’t, so no code is being replaced, only a bunch more rather heavy code is added, meaning you could just degrade gracefully across all browsers and avoid using this markup as @support will be ignored for the most part.

    The markup saved by avoiding @support would most likely be less than that of a custom build of Modernizr targetting only the features you need to support, and Modernizr would be of value across all browsers, not just the few that are releasing versions supporting it.

    Maybe a few years down the line this will be great, but for now, I don’t see if being of much value for everyday use.

    Craig, what are your thoughts on this angle? I understand you feel dirty using JS to get this done, but I feel fat using @support, lol.

    • Given that @supports is arriving in Chrome shortly, it’s likely to appear in the next version of Safari. Within a few months, it’ll just be IE we’re waiting for and I’d hope Microsoft can patch it into IE10 quickly. Once that happens, @supports should be viable 90% of the time — after all, you’ll be restricting styles in the older versions of IE and perhaps mobile browsers.

      But I agree that Modernizr-like JavaScript solutions will remain necessary for a while yet.

  • it is ok, thank you Craig but I don’t think it could run every browser example: ie, safari, opera.

  • Kim

    @supports …

  • I am a bit confused…so is it supposed to work this way:

    @support (text-shadow 0 0 5px #00) { .blur-text { …your styles for supported browsers… } }

    /* then down here you write your blur text styles for unsupported browsers… */

    .blur-text {…your styles for unsupported browsers…}

    Is this the idea…

  • Ya its a good feature, but only if three browsers supports it then most probably we cant even use it when developing mobile sites only.
    But good to see that new functiaonlity are being added to CSS3 family.

  • Hi Craig,
    Thanks for sharing the tips.
    Good to see that new functionality being added to CSS3 family. Hopefully it will be compatible with more browsers in near future.

Get the latest in Front-end, once a week, for free.