6

Following Eric Bidelman's Google I/O presentation yesterday, which touched on the subject of @supports, I figured I'd start playing with it in Chrome Canary. However, it's raised the obvious question:

What is the best way to check whether a browser supports @supports using only CSS?


I'm currently toying with it by simply checking whether display: block is supported. This method works, obviously, but I'm not sure if this is the most practical approach:

body { background:#fff; font-family:Arial; }
body:after { content:'Ek! Your browser does not support @supports'; }

@supports (display:block) {
    body { background:#5ae; }
    body:after { color:#fff; content:'Your browser supports @supports, yay!'; }
}

Here is a JSFiddle demo of this in action.

These attempts do not work (in Chrome Canary, at least):

@supports (@supports) { ... }
@supports () { ... }
@supports { ... }

3 Answers 3

5

@supports currently only tests property/value combinations, and nothing else. Your other options don't work because none of them are valid (including the last one with just the at-keyword followed by the opening brace!). The property/value pair requirement is dictated by the grammar for @supports, which you can find in the spec.

Simply test for a property/value pair that you know is guaranteed to work across all user agents whether or not @supports is implemented. This (sort of) eliminates the possibility that you'll run into a user agent that implements @supports but not that property/value combination, focusing on its support for @supports instead.

Your given example of display: block will suffice. Your use of the cascade to check if a browser does not implement @supports by overriding declarations within a @supports rule for browsers that do support it is also acceptable (being the only obvious way to do it anyway).

Sign up to request clarification or add additional context in comments.

11 Comments

Could there be a situation where display: block isn't included in a CSS implementation? If so, would it be more logical to test against something which would never be part of CSS; something like @supports not (_:_) {}?
@JamesDonnelly @supports not (_:_) {} == @supports not (whateverbutthisdoesntmakeanysenseproprty:5px) {} so if the property value pair is invalid or property is not valid at all, browser will just assume that it is not yet supported
@James Donnelly: Practically speaking, no - I'd rather worry about a browser implementing @supports incorrectly. But if you want, you can do that as well.
@Mr. Alien: Yes. Of course, you do have to make sure that it doesn't break the @supports rule.
Man I need to earn a 3 digit rep with a K to get my answers to be selected as correct ;)
|
2

David walsh blog has a nice tutorial about @supports Link.

Indeed you JsFiddle work perfectly in Chrome Canary.

Valid syntax for @supports are,

@supports(prop:value) {
    /* more styles */
}

/* Negation */
@supports not(prop:value) {
    /* more styles */
}

/* `or` keyword*/
@supports(prop:value) or
         (prop:value){
    /* more styles */
}

/* `and` keyword*/
@supports(prop:value) and
         (prop:value){
    /* more styles */
}

/* `or`, `and` keywords*/
@supports(prop:value) or
         (prop:value) and 
          (prop:value) {
    /* more styles */
}

3 Comments

His question was how to check whether @supports is supported using CSS only and not that how to check which property is supported :)
yup, figured it out lately
@NobalMohan is possible to check pseudo ? like @support @supports .element(:focus-within) { ?
2

This will probably won't work, you cannot check whether @supports is supported or not by CSS only, your example is completely fine here, but there's no option for a straight approach here, for example you are using this :

@supports (@supports) {
   /* Styles */
}

Now that won't actually work, may be for Chrome Canary, this is fine @supports but when it goes ahead to check between parenthesis, it fails, why? It expects a CSS property: value pair inside the parenthesis and not any @ rule, it actually checks whether any property is valid or not, even if you replace that with @supports (@font-face) won't work, further down, I'll explain you with a demo

When you use @supports, it comes with a keyword called not to check whether a specific style is supported by the browser or not, if yes, than apply, else apply other...

Example

@supports (-webkit-border-radius: 6px) {
    div:nth-of-type(1) {
        color: red;
    }
}

@supports not (-moz-border-radius: 6px) {
    div:nth-of-type(2) {
        color: blue;
    }
}

Demo (Note : This works only on chrome canary as of now)

Explanation :

@supports (-webkit-border-radius: 6px) will check in Chrome Canary that whether a property called -webkit-border-radius is supported, if yes than go ahead, change the color of first div to red and it does, cuz Chrome Canary does support -webkit properties while the second will fail as Chrome doesn't support -moz prefixed properties, it will paint blue because I am using not here

@supports not (-moz-border-radius: 6px)
        ---^---

Hopefully FAQ

1) Why none of the styles are applied in browser?

That's because your browser doesn't support @supports yet and hence none will apply as browser will just ignore @supports rules


From the W3C

The ‘@supports’ rule is a conditional group rule whose condition tests whether the user agent supports CSS property:value pairs

5 Comments

The demo doesn't actually explain why @supports (@font-face) doesn't work... it just explains how to use @supports, which as mentioned by the OP is irrelevant to the question.
@BoltClock @supports but when it goes ahead to check between parenthesis, it fails, why? It expects a CSS property: value pair inside the parenthesis and not any @ rule, it actually checks whether any property is valid or not, even if you replace that with @supports (@font-face) won't work How can I provide him with the demo when @supports only work with property value pair?
You're demonstrating the difference between @supports and @supports not - what does that have to do with @supports (@font-face)? Although I guess that is answered by the FAQ bit, but your answer seems pretty confusing.
@BoltClock I shown him the demo that how it only works with properties and not @ rules, further down I explained him how to work with @supports having a valid parameter of property:value combination, certainly @font-face has nothing to do with the demo as it JUST DON'T WORK, so I explained him how it works in the real way so he can't check the way he was trying to, as specified in his question These attempts do not work (in Chrome Canary, at least): @supports (@supports) { ... } the intention was to clear how it works and I created a demo to show that
@BoltClock I guess this is what makes you confused hehe I'll explain you with a demo

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.