While it's nice to not need Modernizr, or JavaScript at all, it's generally only useful for features added <i>after</i> the @supports support landed. As others have mentioned, there's also the problem of false positives, and you could end up with a lorra lorra @supports statements if you include vendor prefixing as well — not a problem JavaScript has to put up with, because you can just define a prefixing function and save many lines of code.<p>Here's the problem vis-á-vis compatibility. CSS Animations are supported back to Safari 4; @supports landed in Safari 9.<p>For instance:<p><pre><code> @supports (-webkit-animation-name: blink){
.cursor {
-webkit-animation-name: onoff;
-webkit-animation-duration: .9s;
-webkit-animation-timing-function: cubic-bezier(.4,0,.2,1);
-webkit-animation-iteration-count: infinite;
}
}
</code></pre>
That's actually damaging, because there won't be a browser that supports @supports <i>and doesn't</i> support CSS animation. This statement will activate the animation only in Safari 9+, despite the feature enjoying support beforehand. By conditioning the animation on support for <i>animation-name</i>, we're actually preventing the feature from showing up where it ought to.<p>Of course, @supports is very useful for bleeding edge stuff like animation-play-state, which just landed in Chrome (and I dare say Firefox) as a byproduct of the Web Animations API.<p><i>animation-play-state</i> let's us control whether an animation (let's say an infinite one) is paused or playing. So, if you imagine a scrolling marquee (for the sake of irony), for instance, you could conditionally pause the marquee on hover by setting:<p><pre><code> @supports (animation-play-state: paused){
.marquee:hover {
animation-play-state: paused
}
}
</code></pre>
You may be thinking "that's effing ridiculous, I could just add that CSS property anyway and if it's not supported it won't work, simple" — and you'd be right to say so.<p>It would be equally pointless to write this:<p><pre><code> @supports (will-change: transform){
.element { will-change: transform; }
}
</code></pre>
because if the property is not supported, it simply won't do anything, and it will not affect anything else or prevent CSS parsing. @supports is pointless as a mere wrapper because there's no need for containment.<p>However, @supports is not for applying potentially unsupported properties only; it's for conditionally activating/altering entire aspects of your website based on there being support for a <i>crucial</i> feature.<p>More useful code might look like this example:<p><pre><code> @supports (animation-play-state: paused){
.marquee {
white-space: nowrap;
animation-name: marquee;
animation-duration: 20s;
animation-timing-function: linear;
animation-delay: 1s;
animation-fill-mode: forwards;
will-change: transform;
}
.marquee:hover {
animation-play-state: paused;
}
}
</code></pre>
This would be useful if, for instance, it would harm usability to have an unstoppable marquee of images/products, so with this sort of code you could have that marquee display as something more mundane, like a grid of items, and if the ability to pause the animation is supported, then convert it into a scrolling marquee gallery of items.<p>It's also potentially useful for things like <i>mix-blend-mode</i>, if you want to apply some kind of fancy effects with a fallback to a simple, one colour overlay:<p><pre><code> .overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: radial-gradient(rgba(31,10,25,.2), rgba(3,81,176,.6));
}
@supports (mix-blend-mode: difference){
.overlay {
mix-blend-mode: difference;
background: radial-gradient(rgba(31,10,25,.2), rgba(176, 109, 3, 0.6));
}
}
</code></pre>
See, if you wanted to apply the difference blending mode but have a similar colour theme, the background of the overlay would need to be basically the opposite, so you can use a @supports block to conditionally change the colour to suit whatever the blending-mode requires.