The @supports CSS rule
lottejackson.com
lottejackson.com
It does continue to prove that your backend is extremely important too. Delivery is hard.
The thing that I like about progressive enhancement is that it "forces" the HTML documents actually represent the content. I should be able to render any site (excluding web-apps, I guess) with CSS and Javascript disabled, preferably with semantic HTML. This makes that site not only accessible to humans, but machines as well.
I see a bunch of websites that have 2 versions of certain elements (for example, navigation menus) in the HTML that are hidden with @media rules to make the site "responsive". I'm scared that this @supports rule will be used in the same way.
Disclaimer: I am not a frontend web developer, so my understanding of progressive enhancement might be wrong.
https://developer.mozilla.org/en-US/docs/Web/API/CSS/support...
Four years is not really a very long time in the greater scheme of things, the pace of modern web development just makes for an impatient populous with short attention spans.
Here's the problem vis-á-vis compatibility. CSS Animations are supported back to Safari 4; @supports landed in Safari 9.
For instance:
@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;
}
}
That's actually damaging, because there won't be a browser that supports @supports and doesn't 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 animation-name, we're actually preventing the feature from showing up where it ought to.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.
animation-play-state 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:
@supports (animation-play-state: paused){
.marquee:hover {
animation-play-state: paused
}
}
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.It would be equally pointless to write this:
@supports (will-change: transform){
.element { will-change: transform; }
}
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.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 crucial feature.
More useful code might look like this example:
@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;
}
}
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.It's also potentially useful for things like mix-blend-mode, if you want to apply some kind of fancy effects with a fallback to a simple, one colour overlay:
.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));
}
}
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.But yes, your larger point that @supports is easy to misuse when targeting old prefixed stuff is certainly true.
> animation-play-state, which just landed in Chrome (and I dare say Firefox)
animation-play-state has been supported unprefixed in Firefox since Firefox 16, 4 years or so ago.
.foobar {
background: red; /* fallback declaration */
background: poorly-supported; /* preferred declaration */
}
or using platform-specific property prefixes.Personally, I'd rather see the entire definition block for a selector in one place than have to consult multiple conditional declarations.
It looks like @supports has been supported by everything but IE, and also the Android browser (not Chrome for Android) for a while [1].
[1]: https://developer.mozilla.org/en-US/docs/Web/CSS/@supports#B...
That coupled with the fact the features are likely to be non-functional aesthetic elements makes it a very minor flaw imo.
Could you provide a specific example as to how it was broken?
@supports (clip-path: inset(0 50px 0 50px)) {
selector {
clip-path: inset(0 5px 0 50px);
}
}
where the clip path was animated. The @supports block would run, but the clip-path property would give an invalid property error. There was additional code within the @supports block related to displaying the animation. I ended up having to detect FF so that I could disable it, since it behaved differently than Chrome/Safari which use the webkit prefix.