Thanks to Chrome release notes, I discovered today that there is an update
media feature which accepts values fast
, slow
and print
, to set styles depending on the ability of the device to update the rendering and the speed of it.
As I'm already respecting the user's preference with the prefers-reduced-motion
media feature, I wondered how I could progressively enhance this with the new media feature.
"Testing" media feature support without @supports
Amelia Bellamy-Royds had the answer with a clever trick. Thanks Amelia! 🙏
This is how you can apply styles only if a feature is supported by the browser:
@media (thing: one), not (thing: one) {
…
}
Indeed:
- either the browser doesn't understand
thing: one
and ignores both media queries - or the browser understands
thing: one
and this is eithertrue
orfalse
, so combining both matches all supporting browsers/contexts
Running CSS animations only if both the device (either update: fast
not supported or true
) and the user allow it (prefers-reduced-motion: no-preference
)
Combining this trick with my already existing media queries for the prefers-reduced-motion
media feature requires a bit of code, but it's manageable.
Here's the code I got for the Ken Burns animations running on my photography site (with non relevant selectors cleaned up):
// Without @media update support
// Enable animations if no reduced motion preference
@media (prefers-reduced-motion: no-preference) {
img {
animation-play-state: running;
}
}
// With @media update support
@media (update: fast), not (update: fast) {
// If screen update is fast (neither slow nor print)
@media (update: fast) {
// Enable animations if no reduced motion preference
@media (prefers-reduced-motion: no-preference) {
img {
animation-play-state: running;
}
}
}
// If screen update is NOT fast (either slow or print)
// Disable animations
@media not (update: fast) {
img {
animation-play-state: paused;
}
}
}
Being able to nest media queries is great!
Later update: a simpler solution thanks to Amelia
As Amelia noticed when I shared this (I ❤️ her comment “both awesome & awful” 😅), the code can be much simpler, without media queries inception. 😅
Here's what Amelia suggests to write, and I agree it's much better:
@media (prefers-reduced-motion: no-preference) {
img {
animation-play-state: running;
/* turn animations on if user doesn't mind */
}
}
@media not (update: fast) {
img {
animation-play-state: paused;
/* except, turn them off again if the browser can't draw them effectively anyway */
}
}
I feel so lucky to regularly get great feedback from people with such expertise as Amelia, on many topics. Once with Twitter, I now get this with Mastodon, and it feels even better.
Now… how can I test the different permutations of update
support or not, and actual value? 🤔
Top comments (0)