Tracking issue for Media Feature "prefers-reduced-motion"
Originally accepted at W3C TPAC, October 2014:
https://lists.w3.org/Archives/Public/www-style/2014Oct/0527.html
More recently discussed in February 2016 thread:
https://lists.w3.org/Archives/Public/www-style/2016Feb/0037.html
For spec:
https://drafts.csswg.org/mediaqueries/
Allows certain views to remove or tone down animations. Platform preference is shipping on iOS, macOS, watchOS, and tvOS.
For example:
Customers regularly mention to us that common web site patterns (e.g. horizontal carousels or scroll-jacking animations) cause vestibular issues such as dizziness or vertigo. Web developers ought to be able to achieve a similar solution that app developers can achieve natively.
Some background:
http://simplyaccessible.com/article/balance-awareness/
Example calls for this support from the web development community:
https://twitter.com/zeldman/status/492805247455072256
https://twitter.com/webaxe/status/489159894860197888
Examples of vestibular trigger usage on sites:
Zoom while scrolling: http://www.nytimes.com/projects/2013/tomato-can-blues/
Spinning parallax starfield: http://cuberto.com
Update 2016-09-30: Desktop version only (simulated 3D zoom and spin triggers)
http://www.nytimes.com/interactive/2016/09/30/opinion/penn-station-reborn.html?_r=0
Site teams like @nytdesign could use this media feature via a standard CSS @ media block:
@media (prefers-reduced-motion) { /* reduce animation */ }
Or via JavaScript:
if (window.matchMedia('(prefers-reduced-motion)').matches) {
/* reduce animation */
}
Update 2016-10-05: Another example:
http://qz.com/se/map-of-the-internet/
Update 2016-12-07: Video Podcast (~1 hour) by Microsoft Edge contributor detailing a variety of problematic web examples: "Infinite Canvas 6: Vestibular Disorders and Accessible Animation"
https://www.youtube.com/watch?v=QhnIZh0xwk0
Changing these user settings don't change the rendering of anything. It just conveys a user preference that allows the frameworks, native apps, or web apps to adjust for this user preference/desire/need.
I should also note these proposed names don't fit well within the "none or truthy" pattern of some existing media features. It'd be awkward to specify that prefers-reduced-motion: none
means "user is okay with animation." The none value here may be open to misinterpretation, so considering a default
or no-preference
value that behaves like none
for boolean comparisons.
prefers-reduced-motion: [ default | reduce ];
prefers-reduced-motion: [ no-preference | reduce ];
If using 'none' is a pattern we want to maintain, then we could rename the prefers-* properties:
reduced-motion-preference: [ none | reduce ]
reduce-motion-preference: [ none | reduce ]
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.
Authors should ensure a reduction in motion does not negatively affect the usability of the interface. If movement was used to convey information (such as an action or relationship between two UI elements), the reduced motion variant should retain the same level of understandability.
For example, if a _queuing_ action was conveyed by "moving the object into a queue position", then removing the animation entirely could result in the user not knowing the item had been successfully queued. It may be appropriate to draw the user's eye to the queued position using a different design metaphor, such as a badge or or variant of the fade technique.
Vestibular triggers for animation include:
From @frivoal suggestion in #443, this could be
reduce-motion-preference: [ none | prefer | forced ]
none
: no preferenceprefer
: web page author responsible for reducing animations or movement appropriately to avoid vestibular triggers or otherwise excessive motion.forced
: motion (CSS animations, etc) prevented by the UA. Note: as far as I know, no platform or browser supports a setting like this, but I suppose it could happen.PS. The none
pattern still seems misleading in this context. It's silly that reduce-motion-preference: none
means "user is okay with motion."
Drop the -preference
. It's long and makes things harder to understand. (reduce-motion: none)
says "don't reduce any motion". ^_^
Then (reduce-motion: prefer)
works well too. (reduce-motion: forced)
doesn't read _quite_ as well, but I'm okay with it.
Why not keep adjectives:
(reduce-motion: none)
(reduce-motion: preferred)
(reduce-motion: forced)
or(reduce-motion: requested)
or (reduce-motion: required)
@cookiecrook reading that list makes me wonder if the property could become more fine grained in future (reduce-motion: loading-none fade-none zoom-none animation-none)
Another question would be if the users could in future have different levels of motion-animations (say 0-100%) and if the media query property should catch that?
"preferred" is above my comfortable "easy spelling" threshold; we try to keep CSS with as simple English as we can. (In general, past tense suffers from that, given the inconsistent end-consonant doubling.)
"required" doesn't quite communicate what's happening; it feels like a stronger version of "prefer", when actually it means something _entirely different_ - it means that, in some way, the OS is turning off motion, and you better adapt to that lack.
What about:
(motion: all)
(motion: prefer-reduced)
or (motion: reduced)
(motion: none)
or (motion: disabled)
I prefer the names that make it clear that these media queries are about detecting user preferences, not about imperatives that affect animation behavior. "force" sounds too much like the latter.
@smfr thats the reason I suggested just motion above which can take "disabled" as a value.
I agree with @inoas that reduced
should be in the value, not the property name. My suggestion is:
motion-pref: none
motion-pref: reduce
motion-pref: block
or motion-pref: disable
Not a fan of the (short)cut (out of my mind I can't site a single css property that is a short-cut; also non-english speakers my not instantly know what it means).
Also motion-pref: none
is ambiguous. Does it mean you have no preference or does it mean you that your preference is set to "no motion"?
So I suggest
(motion: all)
(motion: reduced) or (motion: prefer-reduced)
(motion: none)
or
(motion-preference: all)
(motion-preference: reduced)
(motion-preference: disabled)
@inoas wrote:
(motion: none)
none
is reserved for non-truthy matching (e.g. no match for (motion)
) meaning the default value, so this won't work. How about this instead:
(prefers-reduced-motion: default) /* 'default' should be a non-truthy boolean match like 'none' */
(prefers-reduced-motion: reduce)
So that that authors could use the valueless shorthand:
@media (prefers-reduced-motion) { /* disable excess motion */ }`
And future preference-based media features could use the prefix pattern "prefers-" to distinguish the difference between these types:
prefers-reduced-motion
)monochrome
)Regarding @frivoal's proposal for a forced
value, I think it's highly unlikely any UA would ever disable all motion, as it's ambiguous to determine which transitions or animations would be vestibular triggers. Even if it's possible to disable all motion at the platform level, doing so would be likely to break the user experience more than it helps.
If none is reserved what about motion: off
, edit, e.g.:
(motion: all)
(motion: reduced) or (motion: prefer-reduced)
(motion: off) or (motion: disabled)
or
(motion-preference: all)
(motion-preference: reduced)
(motion-preference: disabled)
or
(prefers-motion: all)
(prefers-motion: reduced)
(prefers-motion: off)
@cookiecrook Not a fan of the shorthand, but the idea with the prefers- prefix seems to be a good one!
Prototype implementation in WebKit https://trac.webkit.org/r207173
Even though WebKit has started to implement, I’d also love to see this framed in the positive if possible. My experience that been that double negatives (e.g. prefers-reduced-motion: none
) tend to trip people up much more often, especially if they are non-native English speakers.
While that necessarily makes the valueless shorthand less useful, I think the increased clarity is worthwhile.
I like the idea of a prefers-*
convention for these, too, so I’d suggest something similar to @inoas:
(prefers-motion: yes) or (prefers-motion: all) or (prefers-motion: default)
(prefers-motion: reduced)
(Side note: thanks @cookiecrook and @grorg for pushing this forward; I’m really looking forward to having access to this, regardless of the naming it winds up with in the end :)
@Mr0grog Last suggestion breaks the Boolean context. For example, this would mean the opposite of what it appears to mean.
@media (prefers-motion) { /* does not prefer motion */ }
@media not (prefers-motion) { /* does want motion */ }
Not certain I understand the double negative concern.
You wrote:
(E.g. prefers-reduced-motion: none
)
…but that is not being proposed. The current implementation and spec value is 'default' (not 'none') which was intended to remove the negative ambiguity in all the other suggestions.
Last suggestion breaks the Boolean context.
Sorry, I was under the assumption that if there was no none
value, the valueless shorthand wouldn’t work, hence my comment “that necessarily makes the valueless shorthand less useful.” I may have understood this.
Can you define what is “truthy” for the valueless version? I admit to not having dug through the media query spec to understand this better, but your earlier comment about default
makes it sound like you can. (Or did you just mean there would still be a none
value that is equivalent to default
?)
If so, why wouldn’t yes/all/whatever
be the “truthy” value in the boolean context instead of reduced
? Apologies if my unfamiliarity with the real specifics of this part of media queries may have led me to a bad suggestion.
Not certain I understand the double negative concern. You wrote:
(E.g. prefers-reduced-motion: none)
…but that is not being proposed.
Ah! Somehow I had misunderstood that that was where this landed since there was lots of none
discussion after your initial comment. I may have been reacting to @tabatkins’s comment:
(reduce-motion: none)
says "don't reduce any motion"
…which I did not find to be clear and triggered my double negative concern. On a closer reading of your comments, I’m not sure we actually disagree very much here :)
At the end of the day, though, I still look at a feature marked prefers-reduced-motion
as conceptually saying please-dont-give-me-motion: yes | no
. We both agree none
for the “no” value is pretty confusing. I’m not sure default
is wonderful because it reads to me more like auto
or initial
—that it’s saying “whatever you’d normally do” rather than explicitly “give me motion”—but I agree it’s much better than none
. I can’t really think of something else better, though, since we are fundamentally talking about finding a value that communicates “no, give me motion.”
ON THE OTHER HAND (watch me talk myself out of this whole thing, ha!)
The more I think about this, the more I realize I may have subconsciously been looking for this:
/* Simple styles for all my stuff */
@media (prefers-motion: yes) { /* sprinkle in fancy transitions and animations, etc. */ }
instead of:
/* Fancy styles ~and motion~ for all my stuff */
@media (prefers-reduced-motion) { /* negate all the motion stuff I did above */ }
However, that first scenario is actually entirely impractical. Since any query involving an unknown property results in a non-match, that means a user-agent that doesn’t support this feature at all (either because it’s old or hasn’t implemented for another reason) would never give you any way (in plain CSS, at least) to add your motion. @media not (prefers-motion)
and @media (prefers-motion)
would both evaluate to false
and there’s no way to check a media feature in an @supports
rule (as I understand it, at least), which is a real practical problem.
So… I think I rescind my whole concern anyway, because the practical issue here is _much_ bigger than my vague double-negative concern. Sorry for all the wasted breath :\
Yeah, a prefers-motion: yes
media feature would not be backwards compatible, so probably a non-starter. Even so, everyone is open to a better naming convention if one arises. Please keep the suggestions coming.
@inoas suggested these as potential default values:
(motion: all)
(motion-preference: all)
(prefers-motion: all)
None of these are backwards compatible, and all
as a falsey value feels awkward to me.
@inoas and @frivoal suggested these as potential forced-all-animations-off values:
reduce-motion-preference: forced
motion-preference: disabled
motion-preference: block
I think the concept of a forced-all-animations-off value is unlikely to be implemented well due to it breaking too many interactions, but let's agree to keep the syntax open to this idea if needed. I believe the current proposal in PR #586 does so:
prefers-reduced-motion: default | reduce; /* future potential for forced-no-motion, etc. */
@inoas also mentioned:
@cookiecrook Not a fan of the shorthand, but the idea with the prefers- prefix seems to be a good one!
I'm glad you liked the prefix. I'm not which shorthand you were referring to. @grorg's PR #586 used prefers-reduced-motion: default | reduce
@inoas suggested these as potential default values:
I came up with these suggestions you name, but I discarded them in this PR https://github.com/w3c/csswg-drafts/pull/778
The idea there is: motion-preference: default | reduce | disable
As for the prefix, this could also work: prefers-motion: default | reduced | disabled
I do believe that it is good to detect a user preference to reflect the desire to have no motions at all. Thus I do believe the disable/d value in a media query is a good thing. However it could easily work without.
prefers-reduced-motion
however has the issue that the media-feature itself already carries a value, aka reduced
. I don't see the reason to do so and it leads to many issues around "negative" value of the feature not being clear if they reset the filter to default or whatever they do:
prefers-reduced-motion: none; // does the user not prefer motion? Does the user not prefer reduced motion?
prefers-reduced-motion: auto; // does the user prefer reduced motion or not?
prefers-reduced-motion: disabled; // does the user prefer reduced motion or not?
The feature name itself just makes it hard to make sense out of it once it gets into dichotomy states, e.g. "user wants default animations, user wants maximum animations, user wants minimum animations, user wants no animations".
So instead of having: prefers-FEATURE: default
we have to have prefers-reduced-motion: unknown
. If the UA/App does not map through a feature preference - or if it is not set - it is safe to assume to use defaults anyway. However prefers-reduced-motion: default
is not clear again. Does the user prefer reduced animations? Or does he not and wants to take defaults?
As for FEATURE-preference
vs prefers-FEATURE
nomenclature, both work even with other features, say contrast-preference: high
vs prefers-contrast: high
fine so I don't care which one it is.
@inoas
As for the prefix, this could also work:
prefers-motion: default | reduced | disabled
@media (prefers-motion)
would then mean the opposite of the intention.
Would this work for you and @frivoal?
prefers-reduced-motion: default | prefers-reduced-motion | forced-no-motion
We don't plan to implement forced-no-motion
unless other browsers pick it up, but we could add a note that made it clear other tokenized values could be added later.
I don't like the suffix variant as much, but I could live with:
motion-preference: no-preference | reduce
Then at least the boolean context wouldn't mean the opposite of what was intended. @media (motion-preference)
is ambiguous, but could be discouraged (or disallowed) in favor of @media (motion-preference: reduce)
or @media (motion-preference: reduce-all)
.
And if anyone were to pick up @frivoal's idea of forced-all-animations-off, a forced-no-motion
value could be added at a later time:
@media (motion-preference: forced-no-motion)
But the concept of disabling entirely seems better as a standard MQ (animation: disabled
) than one that indicates a preference. By design, preferences should convey prefs to the author, not change the page.
👍 for the valueless form to be not allowed because of its inherent ambiguity.
But the concept of disabling entirely seems better as a standard MQ (animation: disabled) than one that indicates a preference.
👍 for having the option for motion: disabled
when the client has those disabled entirely (battery settings, CPU/GPU power/features, rigid user-preferences, anti-Epilepsy, etc.)
But this probably depends a lot on the device vendors if they allow the setting to be hard (disabled
, reduced
), soft (prefers-disabled
, prefers-reduced
) or any combination of those, for example reduced & prefers-disabled
.
(all of these could be caught by one single feature called motion
which for now could only accept the values prefer-reduce
/prefer-reduce-all
and default
)
It seems like we've got @inoas on board with:
motion-preference: no-preference | reduce
…with potential to expand later (if any UA conveys intent) for the hard setting as a non-preference feature name ~ motion:disabled
or as a preference value motion-preference: forced-no-motion
Will that edit appease @tabatkins and @frivoal?
Not sure if it’s entirely germane, but if people think there’s a strong likelihood that a future user-agent might have a hard setting, I think it would be a much better to just have one feature and have the hard setting be a different value. (This is how I read @inoas's comment, too, but I could have misunderstood.)
I think that keeps things conceptually simpler, but, more critically, it allows authors to express a query for the condition "prefers reduced motion OR has motion turned off." With two feature names, an author might try and write something like this, but it wouldn’t work on platforms that don’t yet support both (because any query using an unrecognized feature evaluates to false
):
@media (motion-preference: reduce), (motion: disabled) { ... }
So it’d be much better to shoot for something like:
@media (motion-preference: reduce), (motion-preference: no-motion) { ... } /* or */
@media (motion: reduced), (motion: disabled) { ... }
Naming is hard. Here's an attempt at justifying my own biases^H^H^H^H^H^H^H^H^H^H finding semi-objective criteria to evaluate these names.
@media (mq-name)
is nicer than @media not (mq-name)
none
or 0
. Reusing that would be good. If that's not practical, making up a new one is better than using confusing naming. But the new one is only to make things clearer, so it should not itself be misleading. For instance, unknown
suggests we'd be using the 3-value logic with true/false/unknown states described in https://drafts.csswg.org/mediaqueries/#evaluating, and default
doesn't sound falsy.So, with that in mind, let me try to rate the values proposals that have been put forward. Ratings are :white_check_mark: for good, :no_entry_sign: for bad, :warning: for OK but not great. The keyword(s) marked with * is(are) the falsy one(s), if any. Within this table, I think the first 3 columns are important, and the last 2 are nice to have, but not deal breakers.
| | 1. potential "forced off" value works | 2. omitting value makes sense | 3. non misleading falsy value name (important), preferably reusing none
(nice to have) | 4. short names | 5. no repetition |
---|---|---|---|---|---
motion-preference: no-preference* | reduce
|⚠️|🚫|✅|⚠️| 🚫
prefers-reduced-motion: default* | reduce
|⚠️|✅|⚠️|🚫|🚫
prefers-reduced-motion: no-preference* | reduce
|⚠️|✅|✅|🚫|🚫
reduced-motion-preference: none* | reduce
|⚠️|✅|⚠️|🚫|🚫
reduce-motion-preference: none* | reduce
|⚠️|✅|⚠️|🚫|🚫
reduce-motion-preference: none* | prefer | forced
|⚠️|✅|⚠️|🚫|🚫
reduce-motion: none* | prefer | forced
|âś…|âś…|đźš«|âś…|âś…
reduce-motion: default* | prefer | forced
|✅|✅|⚠️|✅|✅
reduce-motion: unknown* | prefer | forced
|✅|✅|⚠️|✅|✅
reduce-motion: no* | prefer | forced
|âś…|âś…|âś…|âś…|âś…
reduce-motion: no-preference* | prefer | forced
|✅|✅|✅|⚠️|✅
motion: none* | all | prefer-reduced
|âś…|đźš«|âś…|âś…|âś…
motion: none* |all | reduced
|âś…|đźš«|âś…|âś…|âś…
motion: all | prefer-reduced* | disabled*
|✅|⚠️|⚠️|✅|✅
motion: all | reduced* | disabled*
|✅|⚠️|⚠️|✅|✅
motion: all | prefer-reduced | disabled
|âś…|đźš«|đźš«|âś…|âś…
motion: all | reduced | disabled
|âś…|đźš«|đźš«|âś…|âś…
motion-preference: all | reduced | disabled
|⚠️|🚫|🚫|✅|✅
motion-preference: default | reduce | disable
|⚠️|🚫|🚫|✅|✅
prefers-motion: all | reduced* | off*
|⚠️|⚠️|⚠️|✅|✅
prefers-motion: default | reduced* | off*
|⚠️|⚠️|⚠️|✅|✅
Now, my eyes are bleeding and none of these words look like real words anymore. But overall, I feel like
none
is a counter intuitive name of the falsy value.So my preference goes to something like:
reduce-motion: no* | prefer | force
or
reduce-motion: no-preference* | prefer | force
or
reduced-motion: no* | prefer | forced
The rest of the series would look something like that:
invert colors: no | prefer | forced
save-ink: no | prefer | forced
reduce-transparency: no | prefer | forced
Thanks @frivoal. This is very thorough.
Note: Despite the length, I like the more explicit falsy value because no
is too easily inverted (no motion or no preference?). Let's go with the less ambiguous no-preference
as the falsy value.
I feel I need to explain another distinction I value that did not make it into your grid.
I'm not convinced we should use the same media feature to mix exposed-preference values with what you're calling forced values. The forced values are just standard media features that allow the author to account for what has already changed:
Perhaps the distinction is unimportant to others, but I've been thinking of these as a new user preference type ("Author, please change this on behalf of the user") where no change is made without explicit author adoption. If the author is willing and able to adopt my preference, great! If not, render the page as you normally would. The benefit would not be limited to accessibility cases:
If that distinction is valuable to others, add two more deal-breaker columns:
Col 6: The media feature name needs to clearly convey that, unlike most media features, it's the type that requires author adoption. So far, only the prefers-*
and the *-preference
suggestions do so.
Col 7: Values must be expandable. The prefers
and forced
values would suffice for very few user preferences, so values could be whatever type is appropriate for the media feature. As a few trivially contrived examples: temperature-unit-preference: no-preference | fahrenheit | celsius
or font-weight-preference: no-preference | bold
With this added criteria, these seem like better solutions.
motion-preference: no-preference | reduce; /* possible expansion: reduce-rotation, etc. */
prefers-reduced-motion: no-preference | reduce;
While I do think that a positive named feature without any value implication in the feature-variable name is the least confusing and best to use, this (while perfectly fine on itself) makes it hard to use:
@Mr0grog: because any query using an unrecognized feature evaluates to false
If we consider this issue a designer's and browser vendors job, e.g. to write the default css declarations WITH motions for quite some time, and then use the motion MQ feature just to reduce things FOR SOME TIME until there is a broader adoption of the feature name at least, then @media (motion)
makes the most sense IMHO.
Later on media queries like this would both work and make sense, even without a value:
@media (motion) { } /* declarations for default motions */
@media not (motion) { } /* declarations for no motions */
@media (motion: prefer-reduced) { } /* declarations where users prefer little motion */
@media not (motion: reduced) { } /* declarations where the device will not reduce motions */
motion: all | reduced | prefer-none* | prefer-reduced | none* (* = falsey)
The default value would be all
Animations could be binary-off say for
It would be up to the vendor of the device/os if to implement hard (no or reduced capability), soft (obligatory or prefered), or both settings, for all the different types of motions (zooming, fading, smooth/scrolling, bouncing, rotation, etc) and if and how to make those settings configurable by the end user.
Edit: @cookiecrook just read your last comment. If you guys are sure that it is a good idea to separate user-preferences/author-adoption from system-capabilities then motion-preference: no-preference | reduce;
makes a lot of sense. It is easily extendable into other preferences, like you show, and it reads perfectly fine.
reduce
evaluate to false
or true
in the light of having a disabled
value?@cookiecrook
I'm not convinced we should use the same media feature to mix exposed-preference values with what you're calling forced values. The forced values are just standard media features that allow the author to account for what has already changed.
Right, that's definitely a possibility. The reason I think they are useful to join in a single query is that you may often want to react in the same way. Once you have designed a variant of your page that does not use animations yet works well (or without transparency, or using less ink) to cater to users that have expressed that preference, it makes perfect sense to also use that variant when the browser would forcibly try to apply the same effect, to avoid the side effects of a probably more blunt way of during things off and to provide the desired alternative. So you'd use the query in a boolean context, without much concern for whether you were merely requested to turn transparency off, or if you wouldn't get transparency anyway:
@media (reduce-transparency) { /* good opaque variant of your design*/ }
At the same time, from this list of things we've considered so far, the only that has a "prefers" mode in one OS and a "forced" mode in another is invert-colors, and that's the one that is least suited to applying the same styles in both case. ink-saving is "forced" on all OSes/UAs, while motion and transparency are "prefers" when they exist. I think there were a few other MQs that were discussed along the way, but IIRC they were theoretical. So maybe I'm wrong.
Col 6: The media feature name needs to clearly convey that, unlike most media features, it's the type that requires author adoption. So far, only the prefers-* and the *-preference suggestions do so.
This one largely contradictory to goes against my Col 1. I'm still on the fence, as I think there is some merit to the idea of prefers | forced, but I am less sure than I used to, so maybe you're right.
Col 7: Values must be expandable. The prefers and forced values would suffice for very few user preferences, so values could be whatever type is appropriate for the media feature. As a few trivially contrived examples:
temperature-unit-preference: no-preference | fahrenheit | celsius
orfont-weight-preference: no-preference | bold
I think this actually overlapps quite a bit with my Col.2. Col 2 sorts of boils down to:
You don't really need the boolean context / falsy / truthy aspect for your Col 7 criteria, but if we set things up that way, it will work for your purpose as well. Especially if we have a naming that makes your Col 6 happy.
With this added criteria, these seem like better solutions.
motion-preference: no-preference | reduce; /* possible expansion: reduce-rotation, etc. */
prefers-reduced-motion: no-preference | reduce;
I don't like the first one, because it works poorly in a boolean context@media (motion-preference) {}
does not give you a good sense of what it is supposed to mean.
The second one is verbose and uses repeats the prop name in the value, but if we accept your Col 6 over my Col 1, it gets the semantics right.
@inoas I think the transition period is going to be too long to make it practical to have the boolean value oriented the way you suggest, and even after the support is universal, authors often think of the full fledged design first, and of adaptations later, making the "prefer reduce" (no matter what it's called) the better option for a naked boolean query.
motion: all | reduced | prefer-none* | prefer-reduced | none*
(* = falsey)
This gives the same boolean value to 'all' and to 'prefer-reduced', which I don't think is good. Did you mean to make 'prefer-reduced' falsey as well?
@frivoal wrote:
…you'd use the query in a boolean context, without much concern for whether you were merely requested to turn transparency off, or if you wouldn't get transparency anyway:
@media (reduce-transparency) { /* good opaque variant of your design*/ }
Assuming we have one or more vendors shipping a combination of both forced "capability-features" and non-forced "preference-features", it'd be less ambiguous (though admittedly more verbose) to join two separate media features in a query:
@media (transparency-preference: reduce) or (transparency: disabled) {
/* good opaque variant of your design */
}
Edit: A practical example for avoiding combined forced and prefers media features is that some implementations of those are not easily reconcilable. For example, Microsoft Windows' forced "high contrast" mode is radically different from Apple's macOS ~"prefers increase contrast UI" feature.
@inoas wrote:
Would
motion-preference
require a value?
I could be convinced to go either way. Technically, a boolean (motion-preference)
is clear: there is a preference, but it may not be apparent to the author what that means. Requiring a value seems heavy-handed but also would ensure a unambiguous best practice with lower risk of the author breaking someone's view. I could be convinced to forego the boolean usage.
Would
motion-preference: reduce
evaluate to false or true in the light of having a disabled value?
true
though again I think any forced value like disabled
should be in a separate media feature if there is implementor interest in such a thing.
motion: all | reduced | prefer-none* | prefer-reduced | none* (* = falsey)
This gives the same boolean value to 'all' and to 'prefer-reduced', which I don't think is good. Did you mean to make 'prefer-reduced' falsey as well?
I considered but my train of thought was that falsey means nullish, nihilo, no existing. And a reduction means there is most likely something left (else it would be called an extinction, disabling, etc).
Beyond that nitpicking however, this would work as well:
motion: all | reduced | prefer-none* | prefer-reduced* | none* (* = falsey)
@inoas I think the transition period is going to be too long to make it practical to have the boolean value oriented the way you suggest, and even after the support is universal, authors often think of the full fledged design first, and of adaptations later, making the "prefer reduce" (no matter what it's called) the better option for a naked boolean query.
However as far as I understood you want @media (MG-name) to evaluate to false.
I do think it is a non issue if user agents don't support it. It is mostly a "nice" feature anyway, as long as it is not about system capabilities. It is a feature to be nice to the user and respect his preferences. Great stuff, but if it doesn't work (evaluates to false because the mq-feature name is not known) the world won't break.
In the context of hybrid web-apps you can most likely know up-front if the machine supports the new mq-feature and then design your software/css differently knowing about the os/hw capabilities.
BIAS: I am personally in the camp of: HTML and CSS will live a very long life and because of that, long term design is much more important than short term design. They may be here with us when we walk to our graves and maybe even when our children do. Who knows.
People did desktop first and (some/many) are doing mobile first. People are doing online-first and they will do offline-first because of connectivity and seamless work flows. And people may do full-fledged design (colors, contrast, animations) first now... but they may (or may not) do accessibility-first / lo-fi first.
My poor brain is unable to process all the words above. Can someone please state what the current proposal with the most agreement is?
We've already added prefers-reduced-motion to WebKit. I'll change it as soon as there is an agreement here. However, the longer we take to make a decision, the more likely it is that a version of Safari will ship publicly with this syntax, putting pressure on us to support it forever. (Yes, I understand waiting for CR, but I'm not willing to hold an extremely valuable and simple feature back over naming issues, especially when we agree on the technical meaning)
Current diff is:
prefers-reduced-motion: default | reduce
@frivoal wants to combine what I'm referring to as "preference features" (author optional; does not trigger a UI change by default) with "forced features" (which allows an author to respond to a change that has already been made) like all other standard media features. It's a great idea conceptually, but I see value in keeping these separate because implementation of forced features related to user prefs varies greatly across platforms. For example, native "forced" contrast settings on Windows, Android, iOS and macOS seem irreconcilable. Adding a preference-based value and all the variant forced values into a single media feature seems like an impossible task. Furthermore a prefixed ("prefers-") or suffixed ("-preference") naming convention could more clearly convey which features require author adoption. I don't think any of the other name proposals (including @inoas's last one in the previous comment) work because of this mixing.
I'm feeling more and more strongly that standard media features should convey "UI matches this state. Author MAY adapt." (monochrome, etc.) and the preference media features should convey "User wants author to match this preference. Author SHOULD adapt." (prefers-reduced-motion or motion-pref[erence], etc.)
@inoas doesn't like that the current name ("prefers" and "reduced") implies a value. I think it's useful for the boolean context but agreed I could live without a boolean context:
motion-pref: no-preference | reduce /* or reduce-all */
motion-preference: no-preference | reduce /* or reduce-all */
/* syntax is open to future granularity: reduce-rotation, reduce-scaling, etc. */
My impression is that @inoas and @frivoal are warming to this last suggestion, but have not committed. @tabatkins doesn't like the longer suffix but has not commented in a while.
So @tabatkins, @frivoal, and @inoas, could you live with the last suggestion, without attempting to mix the forced settings and preference setting into a single media feature?
Before you answer, remember that W3C Staff is #thankful for those who have let their own great design be replaced by the eventual consensus ;-)
I'm feeling more and more strongly that standard media features should convey "UI matches this state. Author MAY adapt." (monochrome, etc.) and the preference media features should convey "User wants author to match this preference. Author SHOULD adapt." (prefers-reduced-motion or motion-pref[erence], etc.)
If this above is not standardized, and the group of stand-alone user-preference MQs starting with (reduced)-motion gets in, that sounds good 👍 , so that that discourse doesn't from zero next time.
Edit: If what you say above isn't standardized yet,..., it sounds good to include it in the spec, so that this discussion won't be required again.
my POV:
motion-preference
+ motion
would make sense.prefers-reduced-?????
would also imply that there is always at least an ordinal scale for any future preference features and their values, say about ink, color, contrast, transparency, etc. to have a consistent naming. If you prefer not to see green+red on the same page, that's hardly qualifying under ordinal scales ;). In consequence we will have tons of different MQ names for capabilities and/or preferences, some having reduce in it word, others increase, maybe swap, or whatever transformation you can think of.motion-preference: no-preference | reduce /* or reduce-all */
... looks good to me 👍. It is clear, allows to add disabled
if there is the will/desire, allows future granularity and doesn't imply that it is only about reduction (it could, say, have the value double
for speedier motions) in future and allows future and consistent preference detection.
The question I've left: Is the split between preference and capability a good one?
@inoas wrote:
If you want preference and capability detection be side by side (where it makes sense) in future, it would be helpful for users, if they were worded similarly. E.g. motion-preference + motion would make sense.
Yes, that, and your last point about non-ordinal prefs is what brought me around to the "-preference" suffix. For clarity and consistency, I also prefer the expanded "-preference" over the shorter "-pref"…
That "Close Issue" button is way too easy to press accidentally.
@grorg
My poor brain is unable to process all the words above. Can someone please state what the current proposal with the most agreement is?
There's not clear consensus yet, but @cookiecrook is probably closest in agreeing with you, and I've grown warmer to the idea of separating the preference and the forced things, so either #586 or the same thing with a different word (no-preference
?) for the falsey value is probably fine.
On the other hand, I don't like names like motion-preference
which don't indicate which ways things go, as it makes the feature inconvenient to use in a boolean context, which I think would be bad to lose. I guess that means @inoas and I aren't close to agreeing.
@frivoal
EDIT: My argument for -preference
instead of prefers-
is that it would allow more flexibility in future values, such as the following (just examples, to show the issue at hand):
increased-contrast-preference: decrease; /* say night mode */
reduced-motion-preference: double; /* say motions are okay but I want them to be very fast */
reduced-ink-usage-preference: high-quality; /* instead of ink-usage-preference: high-quality */
... /* better examples here */
Edit: E.g. wouldn't that lead to the requirement to introduce a new MQ feature, vs just a new value, every time the value implications set by the MQ feature name make strong assumptions about the variable scale (non, ordinal, interval, ratio), default value and boolean association - that do not match a possible value (see above)?
Edit: What I am saying is, if a new class of MQ features is setup, those of user preferences as they are already named in all the PRs, could we make these consistent and open-ended in its naming and design scheme?
@frivoal wrote:
…I've grown warmer to the idea of separating the preference and the forced things, so either #586 or the same thing with a different word (
no-preference
?) for the falsey value is probably fine.
I agree that no-preference
is better than default
On the other hand, I don't like names like motion-preference which don't indicate which ways things go, as it makes the feature inconvenient to use in a boolean context, which I think would be bad to lose.
I also would rather keep prefers-reduced-motion
over motion-preference
for the sake of the boolean context.
prefers-reduced-motion: no-preference | reduce
@inoas wrote:
… what would you do about these:
increased-contrast-preference: decrease; /* say night mode */
reduced-motion-preference: double; /* say motions are okay but I want them to be very fast */
You suggested: increased-contrast-preference: decrease; /* night mode */
Given the broad range of contrast settings across implementations, I doubt we'll ever be able to standardize a single generic "increase contrast" setting. If anything, it's likely to be several more granular such as prefers-reduced-transparency
, prefers-minimum-contrast-ratio
, etc. It also seems likely that a "night-mode" media feature could be separate.
You suggested: reduced-motion-preference: double; /* motion okay but I want them very fast */
This again seems unlikely to me, but if needed, seems better as a timing preference specific to transitions, rather than all motion. Maybe prefers-minimum-transitions: no-preference | immediate | fast
? (Note: Not an endorsement.)
Edit: prefers-minimum-contrast-ratio
isn't a great name but hopefully the point was clear: indication of a specific and measurable preference rather than a generally ambiguous "I want higher contrast."
Edit: removed "straw man" comment that was overly dismissive. My apologies to @inoas.
That's very concrete. The examples I brought up where not endorsements either. They should just reflect the issue of having the scale/value-implication in the MQ feature name/variable.
A) It is not about straw men here, but where the whole set of user-preferences MQ features is heading towards. The current design seems to just concern the current issue at hand. I have not seen an answer to this yet:
E.g. wouldn't that lead to the requirement to introduce a new MQ feature, vs just a new value, every time the value implications set by the MQ feature name make strong assumptions about the variable scale (non, ordinal, interval, ratio), default value and boolean association - that do not match a possible value (see above)?
B) From the other side of the argument: What is the really big benefit of having a default value that evaluates to boolean context?
To say it in other words: Are you certain that having the scale/value-implication within the mq-feature name _(which could potentially create a mess of mq-features, because feature names similar to "prefers-reduced-motion" transport too much information about the value sets as pointed out and explained above)_ is worth having a boolean default context?
If you are certain then prefers-reduced-motion: no-preference | reduce
should work, despite that it is already painful in my mind to write prefers-reduced-motion: disabled
.
@frivoal Devil's advocate example in favor of @inoas's -preference
suffix: preferences where a non-default numeric value does not imply a specific direction:
minimum-font-size-preference: no-preference | <font-size>
@inoas
I think there is no advantage to having
motion-preference: no-preference | reduced | increased
instead of
prefers-reduced-motion: no-preference | reduced
prefers-increased-motion: no-preference | increased
In usage, you need to write either:
@ media (motion-preference: reduced) {}
or
@ media (prefers-reduced-motion) {}
and the following is useless:
@ media (motion-preference) {}
prefers-reduced-motion: no-pref | reduce
is extensible, but only towards things that go in the same direction. e.g:
prefers-reduced-motion: no-pref | reduce | reduce-motion-sickness | reduce-vibrations | reduce-rotations
You can be specific as to the kind of motion you want to reduce, but you can also use it as a blunt tool, in a boolean context without specifying which kind of motion you care to reduce, and its still works.
Or, turning the argument around: because authors will use things in a boolean context if we make it possible, we should either not make it possible, or make sure that any value added later is compatible the original semantics. I think you're arguing for the former. I think it is possible, but does not bring any improvement over doing it as separate queries, and takes away the possibility of having multiple refinements expressed via boolean semantics.
@frivoal It is not about the usage, sure having a boolean context is nice to have, but does not having it block anything?
prefers-reduced-motion: no-pref | reduce
is extensible, but only towards things that go in the same direction. e.g:
Exactly, that is already the problem. For this MQ feature and for any MQ features to come that don't want to follow this path or cannot (say minimum-font-size-preference
).
You already pointed out yourself that you would need prefers-increased-motion
- but sometimes things don't go into directions.
Or, turning the argument around: because authors will use things in a boolean context if we make it possible, we should either not make it possible, or make sure that any value added later is compatible the original semantics.
What is the big benefit of using the boolean context?
I think you're arguing for the former. I think it is possible, but does not bring any improvement over doing it as separate queries
I don't have a problem with multiple/separate queries.
Do you see any problems having having scale/direction/value implications within the MQ feature name (a variable name!), in so far that it requires to create very similar MQ feature names in future just to be able to also set other values?
All those MQ features then first have to be supported and it takes probably a lot longer than just new values?
I don't see the benefit of having a blunt tool
-option (boolean context), yet?!
, and takes away the possibility of having multiple refinements expressed via boolean semantics.
@frivoal Can you show an example on where @media (motion-preference)
would take away the possibility of having multiple refinements?
Anyway, if can confirm that you are certain that trading off the requirement of implicit default scales/values/directions _(possibly also for future user preference MQs)_ vs just a valid boolean-context, is worth it, then my argument closes here.
All those MQ features then first have to be supported and it takes probably a lot longer than just new values?
I don't think new value vs new MQ would make any difference to how long it takes to get it implemented.
I don't see the benefit of having a boolean context
Can you show an example on where
@media (motion-preference)
would take away the possibility of having multiple refinements?
Calling the MQ motion-preference
doesn't prevent you from adding any number of refinment values to it, but it does get in the way of using it without a value (i.e. in a boolean context) like @media (motion-preference)
because it doesn't tell you anything actionable: there's a preference, but a preference for what: more motion, less motion, different motion? You can't know, so either you don't use it, or you assume one kind and force the hand of future spec additions despite a property name that didn't suggest that particular meaning.
https://trac.webkit.org/r209842
prefers-reduced-motion: reduce | no-preference
Note that it is "no-preference" not "no-pref"
no-preference
still a lot better than ambiguous none
👍 thanks @cookiecrook !
Available here: https://drafts.csswg.org/mediaqueries-5/#prefers-reduced-motion
After reading all these, I want to suggest this:
Motion-reduction: none | preferred | all
I don't mind the "preferred" being past tense. It just feels more natural that way. It is easy to type because it is easy to remember and say in that form. p.s. Sorry, the github client I am using can't type carriage returns without submitting.
@bradkemper With what semantics? what does the all
value mean?
As we've already argued back and forth on this a lot, I am not all that excited about reopening the naming side of this discussion. Especially now that apple has shipped it. Doesn't mean we cannot consider it, but you're going to have to be pretty convincing :)
Yeah, I arrived at this a little too late, it seems. Oh, well, I can deal with it, if that's the case. I'm just throwing it out there because it is what seems most natural and simple to me, and I think should be easy to remember and understand.
My values would mean this:
Motion-reduction: none = Normal, no preference indicated one way or the other, or user chose to not have motion reduced. The default.
Motion-reduction: preferred = User expressed a preference for reduced motion. Author should oblige.
Motion-reduction: all = user expressed a preference to let the UA decide how to reduce motion (blocking all animation and transitions involving position, margin, etc., for instance). Author writes rules to deal with this more severe situation.
@bradkemper well we went through most of that...
motion-reduction: none
is ambiguous without knowing what the specs author's intention was. motion-reduction: no-preference
would work there.
Motion-reduction: preferred
was deemed to by too hard to type here https://github.com/w3c/csswg-drafts/issues/442#issuecomment-248352927
Motion-reduction: all
There was no dominant voices wanting the MQ feature to be able to detect a user preference that communicates disabled motions. I really wanted this in. However then the whole MQ feature name makes no sense as long as it implies reduce
or reduction
. TBH it seemed to me that both, the Google/Android and the Apple/iOS teams, did not want to be able to specify zero-animations (for whatever product/design/marketing reasons). Bad for the user (choice, epilepsy, speediness, battery) though.
Anyway, not being able to detect either disabled motion or the preference for no motion (which are two different things) is really bad about this MQ spec.
@frivoal well the bad choices aside (sorry) the best to work with now is the MQ feature name as it exists and then adding new or more fine grained values.
prefers-reduced-motion
could have prefer-disabled
and hardware-disabled
where first would mean the user made that preference/choice and 2nd would mean either the firmware/hardware is not capable or the user disabled animations deliberately.
However this could also flow into a separate MQ feature if that makes more sense, like say platform-motions
or similar.
Right. While I don't think the naming we landed is perfect, the proposals made here have already been litigated, and don't really bring anything new to the debate.
If you insist, we could bring this to the group for further discussion, but I'd rather leave it at rest.
Most helpful comment
https://trac.webkit.org/r209842
prefers-reduced-motion: reduce | no-preference
Note that it is "no-preference" not "no-pref"