A11Y: disable non-essential CSS animations for reduced-motion users (#23571)

This commit is contained in:
Kris 2023-09-14 17:31:43 -04:00 committed by GitHub
parent 4a1621c677
commit 98c8dcecba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 131 additions and 41 deletions

View File

@ -15,6 +15,8 @@
} }
#custom_emoji.highlighted { #custom_emoji.highlighted {
background: var(--tertiary-very-low); background: var(--tertiary-very-low);
animation: background-fade-highlight 2.5s ease-out; @media (prefers-reduced-motion: no-preference) {
animation: background-fade-highlight 2.5s ease-out;
}
} }
} }

View File

@ -1,3 +1,6 @@
.admin-report-chart { .admin-report-chart {
animation: fadein 2s; animation: fadein 2s;
@media (prefers-reduced-motion) {
animation-duration: 0s;
}
} }

View File

@ -29,6 +29,9 @@
.dialog-overlay { .dialog-overlay {
background: rgba(var(--always-black-rgb), 0.65); background: rgba(var(--always-black-rgb), 0.65);
animation: fade-in 250ms both; animation: fade-in 250ms both;
@media (prefers-reduced-motion) {
animation-duration: 0s;
}
} }
.dialog-content { .dialog-content {
@ -36,9 +39,12 @@
z-index: z("modal", "content"); z-index: z("modal", "content");
position: relative; position: relative;
background-color: var(--secondary); background-color: var(--secondary);
animation: fade-in 250ms both;
box-shadow: var(--shadow-card); box-shadow: var(--shadow-card);
min-width: 40vw; min-width: 40vw;
animation: fade-in 250ms both;
@media (prefers-reduced-motion) {
animation-duration: 0s;
}
} }
.dialog-body { .dialog-body {

View File

@ -47,19 +47,21 @@
} }
} }
.placeholder-animation { @media (prefers-reduced-motion: no-preference) {
animation-duration: 4s; .placeholder-animation {
animation-fill-mode: forwards; animation-duration: 4s;
animation-iteration-count: infinite; animation-fill-mode: forwards;
animation-name: placeHolderShimmer; animation-iteration-count: infinite;
animation-timing-function: linear; animation-name: placeHolderShimmer;
background: var(--primary-very-low); animation-timing-function: linear;
background: linear-gradient( background: var(--primary-very-low);
to right, background: linear-gradient(
var(--primary-very-low) 10%, to right,
var(--primary-low) 18%, var(--primary-very-low) 10%,
var(--primary-very-low) 33% var(--primary-low) 18%,
); var(--primary-very-low) 33%
);
}
} }
// Base Elements // Base Elements

View File

@ -48,6 +48,9 @@
align-items: center; align-items: center;
height: 100%; height: 100%;
animation: fadein 0.5s; animation: fadein 0.5s;
@media (prefers-reduced-motion) {
animation-duration: 0s;
}
// min-width acts as a placeholder if the small logo takes a while to load // min-width acts as a placeholder if the small logo takes a while to load
// it prevents topic title from shifting after the small logo loads // it prevents topic title from shifting after the small logo loads
// it's set to match the #site-logo height so square small logos don't resize when titles dock // it's set to match the #site-logo height so square small logos don't resize when titles dock
@ -276,6 +279,9 @@
overflow: hidden; overflow: hidden;
width: 100%; width: 100%;
animation: fadein 0.5s; animation: fadein 0.5s;
@media (prefers-reduced-motion) {
animation-duration: 0s;
}
} }
.title-wrapper { .title-wrapper {
display: grid; display: grid;

View File

@ -99,6 +99,9 @@
.modal-backdrop, .modal-backdrop,
.modal-backdrop.fade.in { .modal-backdrop.fade.in {
animation: fade 0.3s; animation: fade 0.3s;
@media (prefers-reduced-motion) {
animation-duration: 0s;
}
opacity: 0.9; opacity: 0.9;
filter: alpha(opacity=90); filter: alpha(opacity=90);
} }

View File

@ -935,6 +935,9 @@ iframe.vimeo-onebox {
position: absolute; position: absolute;
width: calc(100% - 40px); width: calc(100% - 40px);
animation: 0.5s fadeIn; animation: 0.5s fadeIn;
@media (prefers-reduced-motion) {
animation-duration: 0s;
}
} }
} }

View File

@ -28,8 +28,10 @@
background: var(--tertiary-very-low); background: var(--tertiary-very-low);
} }
.topic-body.highlighted { .topic-body.highlighted {
.cooked { @media (prefers-reduced-motion: no-preference) {
animation: current-user-background-fade-highlight 2.5s ease-out; .cooked {
animation: current-user-background-fade-highlight 2.5s ease-out;
}
} }
} }
} }
@ -69,8 +71,10 @@
.topic-body.highlighted { .topic-body.highlighted {
animation: none; animation: none;
.cooked { @media (prefers-reduced-motion: no-preference) {
animation: background-fade-highlight 2.5s ease-out; .cooked {
animation: background-fade-highlight 2.5s ease-out;
}
} }
} }

View File

@ -17,6 +17,9 @@
} }
} }
animation: slideUp 0.3s; animation: slideUp 0.3s;
@media (prefers-reduced-motion) {
animation-duration: 0s;
}
} }
.mobile-view & { .mobile-view & {

View File

@ -21,7 +21,9 @@
position: relative; position: relative;
overflow: hidden; overflow: hidden;
&:before { &:before {
animation: placeHolderShimmer 4s linear infinite forwards; @media (prefers-reduced-motion: no-preference) {
animation: placeHolderShimmer 4s linear infinite forwards;
}
position: absolute; position: absolute;
left: 0; left: 0;
content: ""; content: "";
@ -444,7 +446,9 @@ nav.post-controls {
} }
.has-like .d-icon.heart-animation { .has-like .d-icon.heart-animation {
animation: heartBump 0.4s; @media (prefers-reduced-motion: no-preference) {
animation: heartBump 0.4s;
}
} }
@keyframes slideout { @keyframes slideout {
@ -486,7 +490,9 @@ aside.quote {
margin-top: 0; margin-top: 0;
.expanded-quote { .expanded-quote {
overflow: hidden; overflow: hidden;
animation: slideout 1s ease-in-out; @media (prefers-reduced-motion: no-preference) {
animation: slideout 1s ease-in-out;
}
&.icon-only { &.icon-only {
text-align: center; text-align: center;
font-size: var(--font-up-4); font-size: var(--font-up-4);
@ -944,8 +950,10 @@ aside.quote {
border-top: 1px solid var(--primary-low); border-top: 1px solid var(--primary-low);
padding-top: 0.5em; padding-top: 0.5em;
} }
&.highlighted { @media (prefers-reduced-motion: no-preference) {
animation: background-fade-highlight 2.5s ease-out; &.highlighted {
animation: background-fade-highlight 2.5s ease-out;
}
} }
.deleted & { .deleted & {
// Disable so the deleted background is visible immediately // Disable so the deleted background is visible immediately

View File

@ -103,9 +103,14 @@
} }
&.show { &.show {
animation: appear 0.5s cubic-bezier(0.445, 0.05, 0.55, 0.95) 0s forwards; animation: appear 0.5s cubic-bezier(0.445, 0.05, 0.55, 0.95) 0s forwards;
@media (prefers-reduced-motion) {
animation-duration: 0s;
}
} }
&.blink { @media (prefers-reduced-motion: no-preference) {
animation: blink 0.5s cubic-bezier(0.55, 0.085, 0.68, 0.53) both; &.blink {
animation: blink 0.5s cubic-bezier(0.55, 0.085, 0.68, 0.53) both;
}
} }
} }
&__generating-text { &__generating-text {
@ -118,7 +123,9 @@
} }
&__indicator-dot { &__indicator-dot {
display: inline-block; display: inline-block;
animation: ai-summary__indicator-wave 1.8s linear infinite; @media (prefers-reduced-motion: no-preference) {
animation: ai-summary__indicator-wave 1.8s linear infinite;
}
&:nth-child(2) { &:nth-child(2) {
animation-delay: -1.6s; animation-delay: -1.6s;
} }

View File

@ -16,6 +16,9 @@
&:not(.is-loading) { &:not(.is-loading) {
animation: fadein 0.5s; animation: fadein 0.5s;
@media (prefers-reduced-motion) {
animation-duration: 0s;
}
} }
@keyframes fadein { @keyframes fadein {

View File

@ -714,7 +714,9 @@ html.has-lightbox {
.d-lightbox { .d-lightbox {
&.is-visible &__content { &.is-visible &__content {
@extend %lightbox-animation-base; @extend %lightbox-animation-base;
animation-name: lightbox-fade-in-scale; @media (prefers-reduced-motion: no-preference) {
animation-name: lightbox-fade-in-scale;
}
} }
&__backdrop, &__backdrop,
@ -725,6 +727,9 @@ html.has-lightbox {
&__main-title { &__main-title {
@extend %lightbox-animation-base; @extend %lightbox-animation-base;
animation-name: lightbox-fade-in; animation-name: lightbox-fade-in;
@media (prefers-reduced-motion) {
animation-duration: 0s;
}
} }
&__loading-spinner { &__loading-spinner {
@ -734,6 +739,9 @@ html.has-lightbox {
&.will-close &__content { &.will-close &__content {
animation-name: lightbox-fade-out; animation-name: lightbox-fade-out;
@media (prefers-reduced-motion) {
animation-duration: 0s;
}
} }
} }

View File

@ -18,7 +18,9 @@
position: relative; position: relative;
overflow: hidden; overflow: hidden;
&:before { &:before {
animation: placeHolderShimmer 4s linear infinite forwards; @media (prefers-reduced-motion: no-preference) {
animation: placeHolderShimmer 4s linear infinite forwards;
}
position: absolute; position: absolute;
left: 0; left: 0;
content: ""; content: "";

View File

@ -146,8 +146,10 @@ tbody {
.topic-list-item, .topic-list-item,
tr { tr {
border-bottom: 1px solid var(--primary-low); border-bottom: 1px solid var(--primary-low);
&.highlighted { @media (prefers-reduced-motion: no-preference) {
animation: background-fade-highlight 2.5s ease-out; &.highlighted {
animation: background-fade-highlight 2.5s ease-out;
}
} }
} }

View File

@ -15,7 +15,9 @@
position: absolute; position: absolute;
z-index: z("composer", "dropdown") + 1; z-index: z("composer", "dropdown") + 1;
cursor: pointer; cursor: pointer;
animation: 0.15s slidein 3; @media (prefers-reduced-motion: no-preference) {
animation: 0.15s slidein 3;
}
&.bad { &.bad {
background: var(--danger-medium); background: var(--danger-medium);

View File

@ -290,6 +290,9 @@ a.toggle-preview {
animation-delay: 1.5s; animation-delay: 1.5s;
animation-direction: reverse; animation-direction: reverse;
animation-fill-mode: forwards; animation-fill-mode: forwards;
@media (prefers-reduced-motion) {
animation-duration: 0s;
}
position: fixed; position: fixed;
left: 50%; left: 50%;
top: 10%; top: 10%;

View File

@ -11,6 +11,9 @@
.modal.in { .modal.in {
animation: fade 0.25s; animation: fade 0.25s;
@media (prefers-reduced-motion) {
animation-duration: 0s;
}
} }
.modal-footer .btn.right { .modal-footer .btn.right {

View File

@ -105,4 +105,7 @@
width: 100vw; width: 100vw;
background-color: rgba(black, 0.5); background-color: rgba(black, 0.5);
animation: fadein 0.2s; animation: fadein 0.2s;
@media (prefers-reduced-motion) {
animation-duration: 0s;
}
} }

View File

@ -47,6 +47,9 @@
// Fade in header avatar + icons if topic title is not visible in mobile header // Fade in header avatar + icons if topic title is not visible in mobile header
.panel { .panel {
animation: fadein 0.5s; animation: fadein 0.5s;
@media (prefers-reduced-motion) {
animation-duration: 0s;
}
} }
// A rendering bug in safari causes header SVGs to jitter after animations. // A rendering bug in safari causes header SVGs to jitter after animations.
// translateZ() forces gpu rendering which fixes the issue. // translateZ() forces gpu rendering which fixes the issue.

View File

@ -144,8 +144,10 @@ body.wizard {
&__field.invalid input { &__field.invalid input {
outline: 0; outline: 0;
border: 3px solid var(--danger); border: 3px solid var(--danger);
animation: bump 0.25s ease-in-out; @media (prefers-reduced-motion: no-preference) {
animation-iteration-count: 2; animation: bump 0.25s ease-in-out;
animation-iteration-count: 2;
}
} }
&__field label { &__field label {

View File

@ -56,7 +56,9 @@
} }
.chat-composer.is-sending & { .chat-composer.is-sending & {
animation: sendingScales 1s infinite linear; @media (prefers-reduced-motion: no-preference) {
animation: sendingScales 1s infinite linear;
}
} }
.d-icon { .d-icon {

View File

@ -24,7 +24,9 @@
.chat-replying-indicator__dot { .chat-replying-indicator__dot {
display: inline-block; display: inline-block;
animation: chat-replying-indicator__wave 1.8s linear infinite; @media (prefers-reduced-motion: no-preference) {
animation: chat-replying-indicator__wave 1.8s linear infinite;
}
&:nth-child(2) { &:nth-child(2) {
animation-delay: -1.6s; animation-delay: -1.6s;
} }

View File

@ -20,6 +20,9 @@
&__copy-success { &__copy-success {
animation: chat-quote-message-background-fade-highlight 2s ease-out 3s; animation: chat-quote-message-background-fade-highlight 2s ease-out 3s;
@media (prefers-reduced-motion) {
animation-duration: 0s;
}
animation-fill-mode: forwards; animation-fill-mode: forwards;
background-color: var(--success-low); background-color: var(--success-low);
color: var(--primary); color: var(--primary);

View File

@ -125,7 +125,9 @@
rgba(var(--chat-skeleton-animation-rgb), 0.3) 50%, rgba(var(--chat-skeleton-animation-rgb), 0.3) 50%,
rgba(var(--chat-skeleton-animation-rgb), 0.5) 100% rgba(var(--chat-skeleton-animation-rgb), 0.5) 100%
); );
animation: shimmer 1.25s infinite; @media (prefers-reduced-motion: no-preference) {
animation: shimmer 1.25s infinite;
}
content: ""; content: "";
} }

View File

@ -24,9 +24,10 @@
.chat-message-container { .chat-message-container {
transition: transform 400ms; transition: transform 400ms;
transform: scale(1); transform: scale(1);
@media (prefers-reduced-motion: no-preference) {
&.-active { &.-active {
animation: scale-animation 400ms; animation: scale-animation 400ms;
}
} }
} }

View File

@ -26,7 +26,9 @@
.dot { .dot {
display: inline-block; display: inline-block;
animation: wave 1.8s linear infinite; @media (prefers-reduced-motion: no-preference) {
animation: wave 1.8s linear infinite;
}
&:nth-child(2) { &:nth-child(2) {
animation-delay: -1.6s; animation-delay: -1.6s;