Comments (22)
This is definitely a more complex problem than it initially seems as has been stated above. In my research so far I haven't found a blanket solution that isn't without issues. But trying for a "least risky" option to include in this reset could provide a decent starting point. (And help spread knowledge that such a media query exists.)
Most have been mentioned in this thread already, but here's a summary based on my research so far that might be helpful for this decision:
The almost 0s duration:
animation-duration: 0.001s !important;
transition-duration: 0.001s !important;
- It seems that some 0s duration animations and transitions don't play at all in Safari based on my tests so far, but 0.001s is very close to 0s and still too fast to be perceivable in most cases. (It does result in "blips" of motion in other browsers in some cases though.)
- Animations are (almost) instantly advanced to their end state/keyframe.
- Some keyframe animations without an
animation-fill-mode
offorwards
orboth
may never be visible. (Ananimation-fill-mode:forwards !important
could be added, but would also have its own potential issues.) - Any animations or transitions that end with an
opacity
of 0, or positioned out of view, would never be visible . - It assumes that the end of the animation contains the most significant meaning of the animated content and that it doesn't interfere with other content.
Based on this test, animation events still fire, but the timing of when they fire may still be an issue for some uses.
This nearly 0s duration approach might be an acceptable way to go for this project. It’s not without issues or risks, but if it can be assume that this base stylesheet is being implemented at the beginning of a project, the author could be encouraged to compose all CSS-based animations with this reduced rule in mind from the start. (Admittedly, that is still a big assumption.)
none:
animation: none !important;
transition: none !important;
- In my opinion, the option most likely to cause usability problems when applied to other people’s code
- Removing all animations and transitions potentially results in some content never becoming visible, and/or some content never disappearing and obscuring other content (plus the issues already mentioned above)
Very short duration:
animation-duration: 0.1s !important;
transition-duration: 0.1s !important;
- Animations play at an accelerated speed which might be more harmful/distracting and less desirable overall.
Steps:
transition-timing-function: steps(1, start) !important;
animation-timing-function: steps(1, start) !important;
- Similar results as 0.001s duration on simple animations
- Has less desirable effects on more complex uses of keyframes ( See this example )
Two other points to consider:
Whatever this rule ends up being, it will be favoring stopping all animation by default which can be beyond what is needed in many situations. Both the WebKit blog post on prefers-reduced-motion
and the WCAG point out that not all kinds of animation are potentially triggering, and define criteria for animations that should be reduced when requested.
prefers-reduced-motion
can be respected for JS animation as well, but that would be separate effort. The combination of reduced CSS-based motion and non-reduced JavaScript motion could result in usability problems as well.
from cssremedy.
Here is another variant I have encountered (not tested):
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0s !important;
transition: none !important;
scroll-behavior: auto !important;
}
}
from cssremedy.
Two additional note on the 0.001s
duration idea:
- I didn't take infinitely repeating keyframe animations into account on this. A duration this short would have them in a sort of freak-out mode that would likely be pretty terrible. Since
0s
causes trouble for keyframe animations in Safari, addinganimation-iteration-count: 1 !important
would prevent that repeating freak-out state from happening. - If decimal places are an issue
0.01s
would serve the same purpose and is shorter.
Applying the rule to ::before
and ::after
seems smart. Those are often used in animations.
Related to your button hover example, @jensimmons : It looks like a 0s
duration on transitions still functions in Safari (test here), so the 0.01s
would only be needed for CSS keyframe animations written with implied styles for the 0% (and possibly other) keyframes.
Adjusting for not allowing infinitely repeating animations and the fact that only keyframe animations appear to fail with the 0s
duration in Safari:
animation-duration: 0.01s !important;
animation-iteration-count: 1 !important;
transition-duration: 0s !important;
from cssremedy.
In addition to animations and transitions, I too, think the impact of scroll-behavior: smooth
as suggested by #11 (comment) should be strongly considered.
Also, here's an opinion on parallax motion effect due to background-attachment: fixed
from
https://alistapart.com/article/accessibility-for-vestibular/:
there are no words to describe just how bad a simple parallax effect, scrolljacking, or even
background-attachment: fixed
would make me feel. I would rather jump on one of those 20-G centrifuges astronauts use than look at a website with parallax scrolling.
So perhaps:
*,
::before,
::after {
background-attachment: initial !important;
}
from cssremedy.
Was there an explicit decision made not to include scroll-behavior: auto !important;
? Disabling potential scroll-behavior: smooth
occurrences could be just as important (if not more so, particularly on long pages) than perhaps other types of motion through animation/transition/background-attachment.
from cssremedy.
@Malvoz good catch, see PR #55
from cssremedy.
@tigt
It won't just break animations using the FLIP model. It would break anything using a transitionEnd
or animationEnd
event.
For instance: to detect from the JavaScript side when an element has changed state of one of its properties; or to detect that it has just switched from invisible to visible/rendered state.
The second in particular is a necessity for a few complicated solutions. Including some strategies used to polyfill or provide fallback solutions for the ResizeObserver
API. You don't want to mess with this by specifying !important
styles and start off a specificity war...
from cssremedy.
For animation, what if the duration was set to a really large value instead of a really small value to effectively pause it? On that note, animation-play-state: paused
will do this.
@media (prefers-reduced-motion: reduce) {
* {
animation-play-state: paused !important;
transition: none !important;
}
}
animation: none
will break is related to a project I’m working on a project now. It leverages CSS animations for spacial, not time, based events. A paused state would be ideal to not break animations used to display things that aren’t time based. A similar technique could be used to blend two CSS variables like tint a primary color (pause an animation between var(--primary)
and white
).
This still may run into the case of animations that start by hiding content through opacity: 0
or off screen. Therefore pausing the content in an unavailable state.
from cssremedy.
Thoughts on this? I’m liking @valhead’s direction but modified with a delay to fast forward the animation.
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-delay: -1s !important;
animation-duration: 1s !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01s !important;
}
}
example here: https://codepen.io/scottkellum/pen/YogBVM?editors=1100
from cssremedy.
If you have to choose the lesser of two evils; you can make a significantly less evil, lesser evil:
*, ::before, ::after {
animation-delay: -1ms !important;
animation-duration: 1ms !important;
...
}
That should still produce a net 0s
duration except for bugged Safari, where a 1ms
duration is still far more acceptable than a 1s
duration.
from cssremedy.
I found the tweets I snagged this code from... by @scottjehl
https://twitter.com/scottjehl/status/1086287082031583232
https://twitter.com/scottjehl/status/1085600505299111936
from cssremedy.
The Media Queries 5 spec defines prefers-reduced-motion
here:
https://drafts.csswg.org/mediaqueries-5/#descdef-media-prefers-reduced-motion
The issue where this CSS feature was created is here:
w3c/csswg-drafts#442
There's a bit of discussion about enforcing this with the browser itself, but that idea was set aside:
The core reason this needs to expose a user preference rather than change something about the view is because UI varies greatly. There's no way a UA can reliably reduce or stop motion on behalf of the user and still guarantee an understandable interface. Exposing the pref gives authors a way to do this appropriately within the context of their own interfaces.
Reading the debate in the CSSWG issue is a good way to think about the use cases and options.
I'm left thinking we should include this in Remedy, not because the CSSWG "got it wrong", but because this is a good default for all of the web developers (Authors) who don't bother thinking about prefers-reduced-motion
at all. It gives people who need animations eliminated or reduced what they need. And while this might potentially 'break' some UX, developers can easily fix those less-frequent cases by overriding Remedy's code.
Now if we could only make this apply to all the auto-play video/gif/animated advertisements. (UA's should enforce this by turning all gifs and videos into NOT autoplaying. Can we do that in the CSSWG @frivoal @fantasai ?)
Oh, which still leaves the question of how.... (I just also want to consider if, for a bit, too / think about why the CSSWG didn't put the burden of this on the browser to enforce.)
from cssremedy.
How about this?
transition-timing-function: steps(1, start) !important;
animation-timing-function: steps(1, start) !important;
from cssremedy.
No, CSS does not have control over autoplay.
Setting both transition/animation to none and transition/animation-duration to 0 seems redundant?
from cssremedy.
Setting transition/animation: none
might break animations using the FLIP model, so *-duration: 0s
would be more robust in light of that.
That said, an at-the-time WebKit engineer cautioned me against this sort of CSS when I mentioned it on Twitter 2 years ago:
Both of those are likely overkill, and depending on the context, could cause usability problems.
So this might be a thornier issue than it first seems.
from cssremedy.
Thank you Val.
So, to be clear,
animation-duration: 0s !important;
transition-duration: 0s !important;
is likely a bad solution, because in certain browsers, the state change will never happen. So, for example, if someone has applied a fade to a hover color, instead of immediately getting the hover color (rather than a fade), with a 0 duration, the user might get no hover color — things just staying without a color change at all.
So that's off the table. It's good to know why.
Seems to me like we should do this:
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.001s !important;
transition-duration: 0.001s !important;
}
}
and nothing else is required. (Unlike the recent code in the project that was more complex.
There are many, many situation where that won't work, but it's also likely that 90% of websites only use animations at this point for things like hover color transitions, and other slight details. Hopefully anyone building more complex animations will know to think through what happens when prefers-reduced-motion: reduce
is applied.
In fact, the alarm that people might have from us doing this might generate enough buzz and conversation that the message will get around. Pay attention to prefers-reduced-motion: reduce
. Don't just allow the default from Remedy or other similar projects.
The other choice is to not do this at all. To leave it all up to the developers. I just don't like that. I'd rather risk breaking fancy animations than risk no websites bothering to write good code for people who can't take motion very well.
(And I say this as one of those people — motion on websites makes me nauseous. Really any looping motion, like repeating animated gifs in conference presentations. Ugh. Sadly, this setting will not help with the worst problems — ads with motion. Reader Mode is the only solution to that, atm.)
Sadly using !important
will make it hard to override this default. If anyone has ideas about that, let's discuss. If I were a developer planning to do a lot of animation, it's likely I'd fork Remedy, and remove this code in order to not be stuck trying to override an !important statement. Not everyone will have the ability to do that.
I'm going to change the code. Let's keep talking about it.
from cssremedy.
Should the code also apply to ::before
, ::after
, and other pseudo-elements? (Though, I think ::first-line
and friends only accepting certain typography-based styles means they don’t allow transition
and animation
set directly on them.)
from cssremedy.
@valhead What do you think about pseudo-elements?
from cssremedy.
*, ::before, ::after { animation-delay: -1s !important; animation-duration: 1s !important; ... }
As I understand it, the negative animation-delay
is used to break even with the animation-duration
of 1s
, however there's a bug in Safari where negative animation-delay is treated as 0s
, resulting in (I assume) an effective animation-duration
of 1s
and not 0s
- just an FYI. If we have to choose which bug to avoid, I guess it's still better to have a potential 1s
animation-delay than setting animation-delay
(and animation-duration
) to 0s
which would break stuff using transitionEnd
or animationEnd
events in Safari (as suggested in #11 (comment)).
Also I noticed there's no transition-delay: 0s !important
, I don't think that's intentional... is it?
from cssremedy.
@rjgotten I agree.
@mirisuzanne do you mind checking out #11 (comment), and #11 (comment)? Thanks!
from cssremedy.
@Malvoz That all makes sense to me. Do you want to open a PR?
from cssremedy.
This has already been included in the PR above, but for those looking at this thread, make sure to also zero out the transition delay.
from cssremedy.
Related Issues (20)
- High-Contrast Mode HOT 1
- Twitter/social media accounts HOT 1
- vertical-align and alt text HOT 1
- Text Underline position for CJK lang
- height 100% or 100vh on body & html? HOT 11
- Cater for "hidden" attribute HOT 1
- Path to v1.0? HOT 2
- Audio tag without controls should not be `display:block` HOT 1
- `display:block` negates `vertical-align` HOT 6
- `article, etc. {display:block;}` is not enough for oldIE HOT 6
- white-space:pre-wrap vs. overflow:auto for `pre` HOT 2
- Relation to normalize/sanitize.css HOT 1
- Image causes unexpected if used inside intrinsic parent
- svg display attribute ignored HOT 2
- `inert` attribute remedy? HOT 1
- CSS Remedy without specificity HOT 8
- Suggestion: Body centering (with code suggestion) HOT 4
- Opt out of `monospace` font-size quirk
- Preflight img {display: block}
- Is this project dead? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cssremedy.