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 { ... }
Few CSS properties are not supported in some browsers, thus it is required to check whether a CSS property & its value are supported in the current browser. We can find it using JavaScript using CSS. supports() method.
The @supports CSS at-rule lets you specify CSS declarations that depend on a browser's support for CSS features. Using this at-rule is commonly called a feature query. The rule must be placed at the top level of your code or nested inside any other conditional group at-rule.
Which browser supports almost all the CSS properties? Chrome. 4 - 36 supported.
Partial support in CSS means when only some of the CSS values are supported by the browsers. For example, if we consider a CSS property “user-select”. You must know this property allows us to double-click and select the text on a website. So, we can set our preference with the help of user-select property.
@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).
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 */
}
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With