Problem

With all the shiny new frontend stuff we're exposing users to, there are more animated elements on pages. Those animations can cause motion sickness reactions on some people. See child issues.

For those curious here is an article from the guardian about ios issues and some more details from wikipedia's motion sickness page.

a11y is a core gate, we have to find a suitable solution that allows us to remove/reduce all animations in core and contrib. I'll paste text from a reply of Charles Belov in the tour animation issue:

In my mind it would be part of core, just as the iPhone offers a "Minimize animation" setting in its native settings. The idea is that Drupal 8 will be accessible out of the box.

The other advantage of putting it in core - aside from Tour being accessible out of the box - would be that it would encourage contibs that utilize animation to query that setting and respect it. If Minimize Animation was in and of itself a contrib, that would greatly reduce the likelihood of other contribs querying it.

Proposed solution

The plan is to add a sitewide and user-level setting to toggle animations. This setting will do:

  1. jQuery.fx.off = true;
  2. Add no-animate.css file containing: .no-animate * {transition:none !important}
  3. There will be a new setting available for core and contrib JS: drupalSettings.noAnimate. That way code can do if (drupalSettings.noAnimate) {} directly and we don't have to add this when animations are on (which is by default).
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

nod_’s picture

Issue tags: +Accessibility
tim.plunkett’s picture

Version: 8.x-dev » 8.0.x-dev
Charles Belov’s picture

Nod, thank you for creating this meta issue and stating it so well.

Thinking about it, one additional advantage of having it in core, and having animation be accomplished through CSS, is that it might even be possible for contrib writers not even have to think about it. If the contrib code does animation through CSS, core could provide override CSS automatically to disable it for those who need it.

Of course, then it might be neccessary to provide a means to override the setting where animation is critical to understanding. But the idea is that this would have to be a concious decision that the "minimize animation" be overridden for a particular feature rather than having to think about enabling disabling the animation.

Even then, it might be that if the visitor or user has "minimize animation" set, they would still need to press a button to view the animation rather than have the animation activate on page load.

Again, if this "view animation" button for important animations were implemented as a core feature that contribs wouldn't have to code from scratch, that would go a long way to ensuring its appropriate minimal and consistent use.

mgifford’s picture

Version: 8.0.x-dev » 8.1.x-dev

I'd love to address this, but we don't have a patch or even a list of problematic animations at this time.

Can we get a list of where the animations might cause problems, and see if we can address them in a patch for 8.1?

Charles Belov’s picture

The one that is causing me problems is recorded in #2312805: Tour does not support turning off animation, animated tour.

The tiny Ajax timers don't bother me, but I can't speak for everyone. I would accept a non-animated Ajax marker on Reduce Animation, just to be consistent.

Aside from that, I don't know where the animations are in Drupal 8.

nod_’s picture

Version: 8.1.x-dev » 8.0.x-dev

We can and should do something about this in 8.0.x

The plan is to add a sitewide and user-level setting to toggle animations. This setting will do:

  1. jQuery.fx.off = true;
  2. There will be a new default setting available for core and contrib JS: drupalSettings.animate (true by default).
  3. add an animate class to the body (or html element) that all CSS rules with animations must be prefixed with.

As a bonus we could even have that setting stored in localStorage so that anon users can turn it off as well but that's a bonus, don't want to have to deal with the UI for that yet.

I'm updating the IS.

nod_’s picture

Issue summary: View changes
nod_’s picture

Title: [Meta] animation and a11y » Provide a way to disable animations for a11y
Status: Active » Needs work
FileSize
7.42 KB

Here is a quick patch to show what it looks like without animations (it still looks good).

Now we need to add the user/site preference thing.

LewisNyman’s picture

Issue tags: +Usability
nod_’s picture

Issue summary: View changes
nod_’s picture

As pointed out by Lewis, using .no-animate is easier on everyone. New (and better) patch.

nod_’s picture

FileSize
1.86 KB

With the new CSS file.

mgifford’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 12: core-js-animation-2316205-12.patch, failed testing.

LewisNyman’s picture

Issue tags: +CSS
nod_’s picture

Status: Needs work » Needs review
FileSize
4.43 KB

It needs lots of description text work all over the place but I added a new link to admin/config called "Accessbility" which would be a good place to put other a11y stuff we have around.

Also, D8 is much nicer than D7 to create form and pages and stuff.

LewisNyman’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
229.45 KB

This makes sense and works for me. Hovering over the shortcut icon with it enabled has no animation.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Needs the default to be set in the system.site install configuration and needs schema for the new config key. Also

It needs lots of description text work all over the place but I added a new link to admin/config called "Accessbility" which would be a good place to put other a11y stuff we have around.

Does not sound very rtbc.

alexpott’s picture

+++ b/core/includes/theme.inc
@@ -1387,6 +1387,16 @@ function template_preprocess_html(&$variables) {
+  if ($site_config->get('no_animate')) {

let's change the config key to accessibility.disable_animation and default it FALSE. It is nice when config keys have meaning without reading code.

nod_’s picture

Not sure how to do all that so feel free to help people :)

mgifford’s picture

I'm guessing we just need to add no_animate: false to core/modules/system/config/install/system.site.yml

or rather accessibility.disable_animation: false.

I noticed that misc/no-animate.css isn't in the patch. Shouldn't it be added there?

In the Accessibility description: "Change global accessibility options." is a bit vague. What other accessibility options would we want to put here?

I remember having these discussions about Overlay & D7. Do we want this to be site wide or allow users to disable it in their account. Should it be something that could be disabled by anonymous users that are affected by it. Lots of interesting questions.

Overlay's not party of D8 fortunately. There is a tendency to want to set up an accessibility configuration section. Generally that's been resisted. The priority has been on adding in defaults that are good for accessibility rather than configurations that can be enabled to improve accessibility.

I'm just thinking out loud here....

Disable animations should probably have descriptive text. "Some users are affected by 3d animations so we have disabled this for the site".

Charles Belov’s picture

Actually, 2D animations can be just as problematic as 3D animations. The original issue I filed, #2312805: Tour does not support turning off animation, was for a 2D animation.

I would think the hierarchy would be:

If we go with the least-restrictive path:
- Default is that animations are available site-wide
- Authenticated users can set disable animations from their user page (this setting *must* be available)
- Anonymous users get some facility to disable animations, whether site-wide or on a per-page basis (this setting *must* be available)

Most restrictive path:
- Default is that animations are disabled site-wide
- Authenticated users can set enable animations from their user page
- Anonymous users get some facility to enable animations, whether site-wide or on a per-page basis

The big difference between animations and overlay is that, unless a site is designed to have animations on every page, the user can probably get to the place where they can disable animations without having to endure animations. My understanding of overlay was that the per-user disable-overlay setting was not accessible to people who couldn't use the overlay. Is that correct?

Possible wording might be "Some people have negative physical reactions to animation. Disable animation prevents animations from being displayed."

LewisNyman’s picture

nod_ pinged me on IRC to ask if we can drop the webkit transition. I think we can, as long as we test the the unprefixed version also overrides the prefixed version. If contrib does add prefixes by mistake (could easily happen) then we would be a little bit more bullet proof.

Wim Leers’s picture

#22++

I don't think it makes sense to disable animations sitewide. It only makes sense to have it part of the user's settings. … and preferably as part of the user registration form.

mgifford’s picture

Just posting some other articles talking about the pros/cons of this type of design:

http://www.webaxe.org/vestibular-issues-parallax-design/
https://www.iqcomputing.com/support/articles/parallax-scrolling-web-design/

I'm also worried about anonymous users. If this were just Seven then we could assume it was for registered users...

nod_’s picture

The only issue with anon is providing a UI to turn it off. It's trivial to implement if we put the .no-animate CSS rule in system base CSS and add the class based on a user localStorage value.

The issue is to find out how/where we can expose changing this localStorage value for anon users.

LewisNyman’s picture

Urgh, sounds like we're adding a lot of weight to a feature that will rarely be used.. I would prefer a global site wide feature.

nod_’s picture

Status: Needs work » Needs review
FileSize
2.3 KB

Boum. Simplified the whole thing, no more form, no more site setting. I say let contrib deal with the UI.

To test, type in the console:
localStorage.setItem('Drupal.noAnimate', true);

to get rid of it:
localStorage.removeItem('Drupal.noAnimate');

I split the thing in a drupal-init.js file because at some point it'd be great to inline this bit somehow.

mgifford’s picture

From yesterday's 24 ways, an article about animating responsibly.

idebr’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

Patch no longer applies:

error: patch failed: core/core.libraries.yml:48
error: core/core.libraries.yml: patch does not apply
error: patch failed: core/misc/drupal.js:1
error: core/misc/drupal.js: patch does not apply

siva_epari’s picture

Assigned: Unassigned » siva_epari
siva_epari’s picture

Assigned: siva_epari » Unassigned
Status: Needs work » Needs review
FileSize
1.93 KB

Patch is rerolled. Please review

mgifford’s picture

Issue tags: -Needs reroll

For developers with motion sickness, telling them to set localStorage.setItem('Drupal.noAnimate', true); is an option, but that's not the vast majority of folks. How would an editor with motion sickness disable this in D8 through the UI? We do need to expose this feature.

Also, what is the best page to test this on? It applies nicely, but what is the best place to see it working?

DuaelFr’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

This patch does not apply anymore.

I also think that a sitewide setting is not really interesting because if it was needed the themer could disable animations himself. Could we expose a JS function to enable/disable this flag easily to improve DX without making this patch too heavy? We might also document it for themers.

saki007ster’s picture

Re-rolled the patch, not sure what next is to be done here.

saki007ster’s picture

Status: Needs work » Needs review
DuaelFr’s picture

Issue tags: -Needs reroll

Thanks, that could be commited as-is but the discussion about providing or not an UI or helpers for DX is still open.

Status: Needs review » Needs work

The last submitted patch, 35: core-js-animation-2316205-35.patch, failed testing.

Charles Belov’s picture

@DuaelFr #34: This is not for the benefit of the themer, it is for the benefit of site administrators or editors who are distracted or made queasy by involuntary (to the visitor) animation.

If the themer disables animations, then it is turned off for everyone, not just for people who have difficulty tolerating animation. Then it is not available to administrators or editors who benefit from animation (or who simply enjoy it).

DuaelFr’s picture

What I meant was that the only person that could provide a button or a link in the interface to allow the user to turn off animations was the themer. What I am suggesting is to add some functions in the JS API to improve Theming eXperience so they can add that link/button easily.

nod_’s picture

Assigned: Unassigned » nod_

Good point. I scope creeped some stuff into the patch so I'll clean that up too.

Status: Needs work » Needs review
Charles Belov’s picture

mgifford’s picture

@DuaelFr so are you are suggesting that we commit the patch from @saki007ster as is or amend it to include "some functions in the JS API to improve Theming eXperience so they can add that link/button easily."

That could be a separate issue if it is easier. Simply having the ability to disable it in Core is a good step in the right direction. However, ultimately as @Charles Belov states, we want to have this be something that someone can just enable/disable if it bothers them. It shouldn't require a themer.

Not sure if the best approach would be the one we used for #448292: Drag and Drop for table rows is not accessible to screen-reader users to show/hide the table drag.

DuaelFr’s picture

@mgifford I think we could totally commit that patch as-is and open a follow-up issue to add some JS helpers for themers.
In that case, we have no place in the UI to provide a link to disable animations as they can be used anywhere. The idea is only to provide that helpers so themers for whom accessibility matters would be able to easily provide that link to their visitors.

@nod_ you are assigned on that issue. Do you plan to do something new or can we RTBC?

Status: Needs review » Needs work

The last submitted patch, 35: core-js-animation-2316205-35.patch, failed testing.

saki007ster’s picture

Rerolled the patch in #35 attached the interdiff as well. Since system.module.css was broken up into components so added a accessibility.module.css into components folder.

saki007ster’s picture

Status: Needs work » Needs review
mgifford’s picture

Interesting. I guess that makes sense. I just realized that there is also:
core/modules/system/css/components/hidden.module.css

I've got some concerns with separating out the accessibility code from the other code, but that seems like it would be ok here.

Would other accessibility CSS go here, or would it be better to change accessibility.module.css to no-animation.module.css?

To mark this RTBC, we need to manually test that this disables the animation. There's no way for a user to do this at this point through the UI.

Status: Needs review » Needs work

The last submitted patch, 48: core-js-animation-2316205-48.patch, failed testing.

droplet’s picture

I expected all new CORE JS should be API method in future.

So we called Drupal.noAnime, not localStorage.setItem.

Let everybody able to swap it with their own data model system on their client side scripting more easily.

And in future, when we retire localStorage as storage, it need not to update all scripts.

mgifford’s picture

Issue tags: +VIMS

Adding VIMS tag - "visually induced motion sickness" as this is likely to come up again.

Plus another link for more info:
http://www.sciencedirect.com/science/article/pii/S0003687009001574

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

mgifford’s picture

Version: 8.2.x-dev » 8.3.x-dev

The ELMS Learning Network is disabling animations using:

https://github.com/elmsln/elmsln/tree/master/core/dslmcode/shared/drupal...

This is a useful example to build from. I think that user preferences should be stored in a cookie so that a login isn't required to disable them. There is an example from what we added in D7 for #448292: Drag and Drop for table rows is not accessible to screen-reader users.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

mgifford’s picture

Issue tags: +wcag21, +wcag

Just pointing to this WCAG 2.1 page where they are defining the new guideline [edit]:
https://github.com/w3c/wcag21/issues/18

starshaped’s picture

Issue tags: +Needs reroll

The patch in #48 no longer applies.

starshaped’s picture

Rerolled the patch.

starshaped’s picture

Looks like the tests are failing due to the same issue I came across in https://www.drupal.org/node/2781031#comment-12132622, where the test was failing because it was checking that all of system's files were being overridden by Stable, which will not happen because of the backwards compatibility issue. This can be fixed by removing the accessibility.module.css file that was created in #48 and putting that css in an already existing system css file.

starshaped’s picture

Status: Needs work » Needs review
FileSize
1.69 KB
1007 bytes

Moved the css to system.admin.css and removed accessibility.module.css. This SHOULD make the tests pass now.

phenaproxima’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

Thanks, @starshaped! Great work, and thanks for fixing the tests.

Regrettably, I need to kick the patch back for a few reasons:

  1. +++ b/core/core.libraries.yml
    --- /dev/null
    +++ b/core/misc/drupal-init.js
    

    JavaScript in Drupal core is now developed in ES6, using Babel. There are instructions for how to get set up with that at https://www.drupal.org/node/2815083.

  2. +++ b/core/misc/drupal-init.js
    @@ -0,0 +1,23 @@
    +(function (window) {
    

    The closure touches the document object, so it should probably be passed in here.

  3. +++ b/core/misc/drupal-init.js
    @@ -0,0 +1,23 @@
    +  window.Drupal = { behaviors: {}, locale: {} };
    

    This seems very iffy to me, because window.Drupal is defined in core/misc/drupal.js. I'm not sure that we need a separate init script.

  4. +++ b/core/misc/drupal-init.js
    @@ -0,0 +1,23 @@
    +  // Allows users to turn off animations.
    +  var noAnimate = localStorage.getItem('Drupal.noAnimate') === 'true';
    +  // Class indicating that JS is enabled; used for styling purpose.
    +  document.documentElement.className += ' js' + (noAnimate ? ' no-animate' : '');
    +
    +  // Allow other JavaScript libraries to use $.
    +  if (window.jQuery) {
    +    jQuery.noConflict();
    +    jQuery.fx.off = noAnimate;
    +  }
    

    I feel like this should probably be encapsulated in a separate JS behavior (Drupal.behaviors.noAnimate or something like that) that lives in its own file, or possibly just added to drupal.js.

  5. +++ b/core/misc/drupal-init.js
    --- a/core/modules/system/css/system.admin.css
    +++ b/core/modules/system/css/system.admin.css
    

    I'm not sure this is the right place for this CSS. That said, I'm also not sure where would be a *better* place to put it.

    One possibility would be to have the JavaScript set these styles, then we wouldn't have to bike shed on where to put the CSS at all. But I dunno, I suspect that might not be "clean" enough for the JS maintainers :) I think I have to defer to them on this question.

There is also the question of test coverage. Do we need automated tests for this, or would manual testing suffice? I am not sure. I'm marking this issue as needing tests either way. One benefit of taking the "let's disable the animations in JavaScript only, and not add any CSS" approach that I just suggested is that we could easily write an automated test for that.

GrandmaGlassesRopeMan’s picture

@phenaproxima @starshaped

We already have a drupal.init.es6.js, no need to create another. 😀

- #63.1,2,3: Fixed by moving this code to drupal.init.es6.js
- #63.4: It's such a small change I don't know if we want the overhead.
- #63.5: I don't really have any opinion on where this CSS should live, except that it probably shouldn't reside within the JS.

There is also the question of test coverage. Do we need automated tests for this, or would manual testing suffice?

I think it's important that we keep adding tests for new functionality/features.

GrandmaGlassesRopeMan’s picture

Status: Needs work » Needs review
phenaproxima’s picture

Status: Needs review » Needs work
+++ b/core/misc/drupal.init.es6.js
@@ -1,11 +1,18 @@
+// Class indicating that JS is enabled; used for styling purpose.
+document.documentElement.className += ' js';
+
+// Class indicating that no animations should be triggered.
+document.documentElement.className += `${noAnimate ? ' no-animate' : ''}`;

It might be cleaner to use classList here, if that will work (and is allowed)...?

I am fairly sure the committers will kick this back over the placement of the CSS. Unfortunately, I don't know the front-end code base well enough to say where the CSS should live. So I think I have to punt on that one.

Patch looks good otherwise, but I'm marking it NW for tests.

dmsmidt’s picture

Issue tags: +sprint
Wim Leers’s picture

Status: Needs work » Needs review

Patch looks good otherwise, but I'm marking it NW for tests.

How do you propose we test this?

phenaproxima’s picture

How do you propose we test this?

It seems to me that we could have a JS test which asserts the presence, or absence, of the no-animate class.

GrandmaGlassesRopeMan’s picture

Issue tags: -Needs tests

This is probably another instance where having some unit tests would give us some confidence that the correct thing is happening. Having a series of tests for our local storage interface would make this kind of patch trivial.

With our current functional testing environment, we have to 🙏 to PhantomJS that there's some ability to fiddle with local storage and then we could check that the class was attached. This feels like like too much complexity for not enough confidence.

Removing the Needs tests tag for now since I don't really think they should block this.

Wim Leers’s picture

I think this needs two things to reach RTBC:

  1. justification why this is only an API, with no way to actually enable this "minimize animation" mode — you'd need a contrib/custom module to do that
  2. manual testing
nod_’s picture

Status: Needs review » Needs work

Seems to me patch would be better reworked to use the new-ish prefers-reduced-motion. No besopke drupal API needed, just following user browser preferences.

We might even be able to do away with this whole thing if the media query is implemented in corresponding modules' CSS (and a some additional JS in the tour module to get rid of animations if necessary).

Wim Leers’s picture

OOHHHHHHHH 👏👍

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

mgifford’s picture

That is very promising. It's still draft in the W3C, who knows when there will be support in the browsers let-alone user awareness. Still worth watching https://drafts.csswg.org/mediaqueries-5/#prefers-reduced-motion

andrewmacpherson’s picture

WCAG 2.1 introduces Success Criterion 2.2.9 Animation from Interactions. Notably, it's classed at level AAA, so it isn't a blocker for the Drupal core accessibility gate (which targets level AA).

macOS and iOS now have an OS-level user preference, and Safari already implements the CSS5 prefers-reduced-motion media query. The fact that's it's being developed for a W3C rec is encouraging. There are feature request issues to implement it in the other major browsers:

An article on the WebKit blog this summer, Responsive Design for Motion, breaks down different kinds of animation trigger for VIMS with video demonstrations of each one. This is the first easy guide I've seen about assessing animations. A demo page linked at the bottom of the article shows different ways to use the prefers-reduced-motion media query.

@nod, re: #72,

Seems to me patch would be better reworked to use the new-ish prefers-reduced-motion. No besopke drupal API needed, just following user browser preferences.

I wholly agree, at this stage I don't think a Drupal API is the way to go. Supporting platform-level (browser or OS) preferences with prefers-reduced-motion is a much more attractive, robust, and maintainable route to follow.

Again, re: #72,

We might even be able to do away with this whole thing if the media query is implemented in corresponding modules' CSS (and a some additional JS in the tour module to get rid of animations if necessary).

+1 to that - we'd be treating animations as a progressive enhancement, on a per-component basis. In fact not just progressive, but inclusive and considerate enhancement.

Given that:

  • It's coming in a W3C CSS5 rec, and
  • There is already a working implementation in at least one major desktop platform (macOS) and mobile platform (iOS), and
  • Microsoft has shown commitment to building significantly more accessibility features into Windows 10, and
  • Mozilla employs a number of engineers to work on accessibility features, and
  • Addressing the new WCAG 2.1 SC 2.2.9 Animations from Interactions (being level AAA) is NOT critical for our accessibility gate,

Then I think the best way forward is to re-scope this as a [Policy, no patch] issue, to form developer guidelines for the use of animations in Drupal. We can also track the implementation status of the prefers-reduced-motion media query, and use that as a basis to postpone or proceed with specific animation issues in Drupal core.

This issue doesn't have a parent yet, so I think we can bring it under the WCAG 2.1 plan now.

Charles Belov’s picture

+1 on respecting prefers-reduced-motion. If someone has set that setting, its safe to say that animation bothers them/me, they've said they don't want it, and it is respectful to them to just not do it when it's not required, and you don't have to worry about what the animation standards are or anticipate what their (varying) needs might be.

andrewmacpherson’s picture

Maybe we should start an experimental issue to refactor an existing animation to use prefers-reduced-motion.

In the demo from the WebKit blog, "Example 2: Using CSS to disable an ongoing, purely decorative animation", the decoration is similar to the animation we use on batch progress bars, e.g during site install.

The batch progress bars have plenty of of other affordances (simple static length, and text describing progress) that they should work well without animations.

nod_’s picture

We might need to make a new issue. The direction changed significantly and we're already at comment #79.

nod_’s picture

Assigned: nod_ » Unassigned
Status: Needs work » Closed (won't fix)
mgifford’s picture

andrewmacpherson’s picture

Status: Closed (won't fix) » Fixed

Reflectively, I'm changing this from "won't fix" to "actually, we arrived at an achievable strategy to follow up, so that's fixed". The media query has landed in Firefox for Windows, so I'm feeling really optimistic :-)

andrewmacpherson’s picture

Status: Fixed » Closed (fixed)