Supporting and detecting @supports
Opera recently added support for the @supports
feature of the
CSS Conditional Rules Module. Using @supports
offers a native way to
feature-test support for CSS properties and values.
@supports (display: flex){
/* Include flexible box styling here */
}
You can also test for negation, and provide rules for cases when a feature is not supported.
@supports not(display: heffalump){
/* Include not-heffalump styling here */
}
My colleague Chris Mills wrote about the feature for Dev.Opera.
@supports
JavaScript API
Opera supports an earlier version of the JavaScript API with the
window.supportsCSS()
method. Using this method is as simple as passing
a property and value.
var hasFlex = supportsCSS('display','flex');
After landing in Opera, the specification changed to add a window.CSS
object and supports
method instead of window.supportsCSS()
. Future
syntax will probably be as follows.
var hasFlex = CSS.supports('display','flex');
Testing for @supports
support
Of course, this only works when the browser supports @supports
. So how
do we test for that?
The simplest way I've found takes advantage of the CSS Object
Model and its CSSRule interface.
@supports
extends the CSSRule interface to add the SUPPORTS_RULE
constant. In browsers that don't support @supports
, its value will be
undefined.
function hasAtSupports(){
return (window.CSSRule !== undefined) && (window.CSSRule.SUPPORTS_RULE !== undefined);
}
I've also published this as a gist.
Using the above method has its limits, however. It will tell you whether
@supports
is available at all, but cannot be used to detect specific
features. For that, try my
atsupports.js
polyfill (My first polyfill! Please be gentle!), or use
Modernizr. The atsupports.js polyfill adds
window.CSS.supports
to browsers that support @supports
but not its
JavaScript API. It uses window.supportsCSS()
if available. You can see
how this works in
Opera or Firefox (WebKit support is in a very early
stage. Firefox'
window.CSS.supports()
support is in progress).
Modernizr versus @supports
As Bruce wrote recently, native
@supports
will perform better than
JavaScript.
This is true. However, Modernizr offers tests
for JavaScript APIs in addition to CSS3. If you're using newfangled
HTML5 features in addition to the fancier bits of CSS, Modernizr may be
the more prudent choice.