diff --git a/app/assets/stylesheets/common/admin/admin_emojis.scss b/app/assets/stylesheets/common/admin/admin_emojis.scss index adfc27f2955..d6c600fe0f3 100644 --- a/app/assets/stylesheets/common/admin/admin_emojis.scss +++ b/app/assets/stylesheets/common/admin/admin_emojis.scss @@ -15,6 +15,8 @@ } #custom_emoji.highlighted { 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; + } } } diff --git a/app/assets/stylesheets/common/admin/admin_report_chart.scss b/app/assets/stylesheets/common/admin/admin_report_chart.scss index 91fcb073d52..be3c79eeea0 100644 --- a/app/assets/stylesheets/common/admin/admin_report_chart.scss +++ b/app/assets/stylesheets/common/admin/admin_report_chart.scss @@ -1,3 +1,6 @@ .admin-report-chart { animation: fadein 2s; + @media (prefers-reduced-motion) { + animation-duration: 0s; + } } diff --git a/app/assets/stylesheets/common/base/dialog.scss b/app/assets/stylesheets/common/base/dialog.scss index b57f3521a53..f8c5d9fbbb8 100644 --- a/app/assets/stylesheets/common/base/dialog.scss +++ b/app/assets/stylesheets/common/base/dialog.scss @@ -29,6 +29,9 @@ .dialog-overlay { background: rgba(var(--always-black-rgb), 0.65); animation: fade-in 250ms both; + @media (prefers-reduced-motion) { + animation-duration: 0s; + } } .dialog-content { @@ -36,9 +39,12 @@ z-index: z("modal", "content"); position: relative; background-color: var(--secondary); - animation: fade-in 250ms both; box-shadow: var(--shadow-card); min-width: 40vw; + animation: fade-in 250ms both; + @media (prefers-reduced-motion) { + animation-duration: 0s; + } } .dialog-body { diff --git a/app/assets/stylesheets/common/base/discourse.scss b/app/assets/stylesheets/common/base/discourse.scss index 80175967e73..0d465316fd5 100644 --- a/app/assets/stylesheets/common/base/discourse.scss +++ b/app/assets/stylesheets/common/base/discourse.scss @@ -47,19 +47,21 @@ } } -.placeholder-animation { - animation-duration: 4s; - animation-fill-mode: forwards; - animation-iteration-count: infinite; - animation-name: placeHolderShimmer; - animation-timing-function: linear; - background: var(--primary-very-low); - background: linear-gradient( - to right, - var(--primary-very-low) 10%, - var(--primary-low) 18%, - var(--primary-very-low) 33% - ); +@media (prefers-reduced-motion: no-preference) { + .placeholder-animation { + animation-duration: 4s; + animation-fill-mode: forwards; + animation-iteration-count: infinite; + animation-name: placeHolderShimmer; + animation-timing-function: linear; + background: var(--primary-very-low); + background: linear-gradient( + to right, + var(--primary-very-low) 10%, + var(--primary-low) 18%, + var(--primary-very-low) 33% + ); + } } // Base Elements diff --git a/app/assets/stylesheets/common/base/header.scss b/app/assets/stylesheets/common/base/header.scss index 536e861cec5..e14cacbe9b9 100644 --- a/app/assets/stylesheets/common/base/header.scss +++ b/app/assets/stylesheets/common/base/header.scss @@ -48,6 +48,9 @@ align-items: center; height: 100%; 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 // 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 @@ -276,6 +279,9 @@ overflow: hidden; width: 100%; animation: fadein 0.5s; + @media (prefers-reduced-motion) { + animation-duration: 0s; + } } .title-wrapper { display: grid; diff --git a/app/assets/stylesheets/common/base/modal.scss b/app/assets/stylesheets/common/base/modal.scss index abb67544f4c..5e3e15880e2 100644 --- a/app/assets/stylesheets/common/base/modal.scss +++ b/app/assets/stylesheets/common/base/modal.scss @@ -99,6 +99,9 @@ .modal-backdrop, .modal-backdrop.fade.in { animation: fade 0.3s; + @media (prefers-reduced-motion) { + animation-duration: 0s; + } opacity: 0.9; filter: alpha(opacity=90); } diff --git a/app/assets/stylesheets/common/base/onebox.scss b/app/assets/stylesheets/common/base/onebox.scss index 6355f5c092d..ce14beaa49e 100644 --- a/app/assets/stylesheets/common/base/onebox.scss +++ b/app/assets/stylesheets/common/base/onebox.scss @@ -935,6 +935,9 @@ iframe.vimeo-onebox { position: absolute; width: calc(100% - 40px); animation: 0.5s fadeIn; + @media (prefers-reduced-motion) { + animation-duration: 0s; + } } } diff --git a/app/assets/stylesheets/common/base/personal-message.scss b/app/assets/stylesheets/common/base/personal-message.scss index a1337db954f..6100b246617 100644 --- a/app/assets/stylesheets/common/base/personal-message.scss +++ b/app/assets/stylesheets/common/base/personal-message.scss @@ -28,8 +28,10 @@ background: var(--tertiary-very-low); } .topic-body.highlighted { - .cooked { - animation: current-user-background-fade-highlight 2.5s ease-out; + @media (prefers-reduced-motion: no-preference) { + .cooked { + animation: current-user-background-fade-highlight 2.5s ease-out; + } } } } @@ -69,8 +71,10 @@ .topic-body.highlighted { animation: none; - .cooked { - animation: background-fade-highlight 2.5s ease-out; + @media (prefers-reduced-motion: no-preference) { + .cooked { + animation: background-fade-highlight 2.5s ease-out; + } } } diff --git a/app/assets/stylesheets/common/base/topic-admin-menu.scss b/app/assets/stylesheets/common/base/topic-admin-menu.scss index 251747a038a..6a9243afd7e 100644 --- a/app/assets/stylesheets/common/base/topic-admin-menu.scss +++ b/app/assets/stylesheets/common/base/topic-admin-menu.scss @@ -17,6 +17,9 @@ } } animation: slideUp 0.3s; + @media (prefers-reduced-motion) { + animation-duration: 0s; + } } .mobile-view & { diff --git a/app/assets/stylesheets/common/base/topic-post.scss b/app/assets/stylesheets/common/base/topic-post.scss index 49504acf2c6..ead71f41f10 100644 --- a/app/assets/stylesheets/common/base/topic-post.scss +++ b/app/assets/stylesheets/common/base/topic-post.scss @@ -21,7 +21,9 @@ position: relative; overflow: hidden; &:before { - animation: placeHolderShimmer 4s linear infinite forwards; + @media (prefers-reduced-motion: no-preference) { + animation: placeHolderShimmer 4s linear infinite forwards; + } position: absolute; left: 0; content: ""; @@ -444,7 +446,9 @@ nav.post-controls { } .has-like .d-icon.heart-animation { - animation: heartBump 0.4s; + @media (prefers-reduced-motion: no-preference) { + animation: heartBump 0.4s; + } } @keyframes slideout { @@ -486,7 +490,9 @@ aside.quote { margin-top: 0; .expanded-quote { overflow: hidden; - animation: slideout 1s ease-in-out; + @media (prefers-reduced-motion: no-preference) { + animation: slideout 1s ease-in-out; + } &.icon-only { text-align: center; font-size: var(--font-up-4); @@ -944,8 +950,10 @@ aside.quote { border-top: 1px solid var(--primary-low); padding-top: 0.5em; } - &.highlighted { - animation: background-fade-highlight 2.5s ease-out; + @media (prefers-reduced-motion: no-preference) { + &.highlighted { + animation: background-fade-highlight 2.5s ease-out; + } } .deleted & { // Disable so the deleted background is visible immediately diff --git a/app/assets/stylesheets/common/base/topic-summary.scss b/app/assets/stylesheets/common/base/topic-summary.scss index 781f8ddc37b..f8fdd1ec506 100644 --- a/app/assets/stylesheets/common/base/topic-summary.scss +++ b/app/assets/stylesheets/common/base/topic-summary.scss @@ -103,9 +103,14 @@ } &.show { animation: appear 0.5s cubic-bezier(0.445, 0.05, 0.55, 0.95) 0s forwards; + @media (prefers-reduced-motion) { + animation-duration: 0s; + } } - &.blink { - animation: blink 0.5s cubic-bezier(0.55, 0.085, 0.68, 0.53) both; + @media (prefers-reduced-motion: no-preference) { + &.blink { + animation: blink 0.5s cubic-bezier(0.55, 0.085, 0.68, 0.53) both; + } } } &__generating-text { @@ -118,7 +123,9 @@ } &__indicator-dot { 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) { animation-delay: -1.6s; } diff --git a/app/assets/stylesheets/common/components/conditional-loading-section.scss b/app/assets/stylesheets/common/components/conditional-loading-section.scss index c5c1b4e8f0a..2c182df5d09 100644 --- a/app/assets/stylesheets/common/components/conditional-loading-section.scss +++ b/app/assets/stylesheets/common/components/conditional-loading-section.scss @@ -16,6 +16,9 @@ &:not(.is-loading) { animation: fadein 0.5s; + @media (prefers-reduced-motion) { + animation-duration: 0s; + } } @keyframes fadein { diff --git a/app/assets/stylesheets/common/components/d-lightbox.scss b/app/assets/stylesheets/common/components/d-lightbox.scss index 56a0ebfcfb3..5f50bf06e38 100644 --- a/app/assets/stylesheets/common/components/d-lightbox.scss +++ b/app/assets/stylesheets/common/components/d-lightbox.scss @@ -714,7 +714,9 @@ html.has-lightbox { .d-lightbox { &.is-visible &__content { @extend %lightbox-animation-base; - animation-name: lightbox-fade-in-scale; + @media (prefers-reduced-motion: no-preference) { + animation-name: lightbox-fade-in-scale; + } } &__backdrop, @@ -725,6 +727,9 @@ html.has-lightbox { &__main-title { @extend %lightbox-animation-base; animation-name: lightbox-fade-in; + @media (prefers-reduced-motion) { + animation-duration: 0s; + } } &__loading-spinner { @@ -734,6 +739,9 @@ html.has-lightbox { &.will-close &__content { animation-name: lightbox-fade-out; + @media (prefers-reduced-motion) { + animation-duration: 0s; + } } } diff --git a/app/assets/stylesheets/common/components/user-card.scss b/app/assets/stylesheets/common/components/user-card.scss index 3c9a807ca49..e5108cf42b7 100644 --- a/app/assets/stylesheets/common/components/user-card.scss +++ b/app/assets/stylesheets/common/components/user-card.scss @@ -18,7 +18,9 @@ position: relative; overflow: hidden; &:before { - animation: placeHolderShimmer 4s linear infinite forwards; + @media (prefers-reduced-motion: no-preference) { + animation: placeHolderShimmer 4s linear infinite forwards; + } position: absolute; left: 0; content: ""; diff --git a/app/assets/stylesheets/common/foundation/base.scss b/app/assets/stylesheets/common/foundation/base.scss index 3c24bbeb093..0a68f0d2f6c 100644 --- a/app/assets/stylesheets/common/foundation/base.scss +++ b/app/assets/stylesheets/common/foundation/base.scss @@ -146,8 +146,10 @@ tbody { .topic-list-item, tr { border-bottom: 1px solid var(--primary-low); - &.highlighted { - animation: background-fade-highlight 2.5s ease-out; + @media (prefers-reduced-motion: no-preference) { + &.highlighted { + animation: background-fade-highlight 2.5s ease-out; + } } } diff --git a/app/assets/stylesheets/common/input_tip.scss b/app/assets/stylesheets/common/input_tip.scss index d429858b6e9..48e4453c3f7 100644 --- a/app/assets/stylesheets/common/input_tip.scss +++ b/app/assets/stylesheets/common/input_tip.scss @@ -15,7 +15,9 @@ position: absolute; z-index: z("composer", "dropdown") + 1; cursor: pointer; - animation: 0.15s slidein 3; + @media (prefers-reduced-motion: no-preference) { + animation: 0.15s slidein 3; + } &.bad { background: var(--danger-medium); diff --git a/app/assets/stylesheets/desktop/compose.scss b/app/assets/stylesheets/desktop/compose.scss index 5b9b4e1cbe2..d77e91064ce 100644 --- a/app/assets/stylesheets/desktop/compose.scss +++ b/app/assets/stylesheets/desktop/compose.scss @@ -290,6 +290,9 @@ a.toggle-preview { animation-delay: 1.5s; animation-direction: reverse; animation-fill-mode: forwards; + @media (prefers-reduced-motion) { + animation-duration: 0s; + } position: fixed; left: 50%; top: 10%; diff --git a/app/assets/stylesheets/desktop/modal.scss b/app/assets/stylesheets/desktop/modal.scss index 294c8551c7d..8f7092cb9ff 100644 --- a/app/assets/stylesheets/desktop/modal.scss +++ b/app/assets/stylesheets/desktop/modal.scss @@ -11,6 +11,9 @@ .modal.in { animation: fade 0.25s; + @media (prefers-reduced-motion) { + animation-duration: 0s; + } } .modal-footer .btn.right { diff --git a/app/assets/stylesheets/mobile/components/user-card.scss b/app/assets/stylesheets/mobile/components/user-card.scss index f114ed1647e..04507db528b 100644 --- a/app/assets/stylesheets/mobile/components/user-card.scss +++ b/app/assets/stylesheets/mobile/components/user-card.scss @@ -105,4 +105,7 @@ width: 100vw; background-color: rgba(black, 0.5); animation: fadein 0.2s; + @media (prefers-reduced-motion) { + animation-duration: 0s; + } } diff --git a/app/assets/stylesheets/mobile/header.scss b/app/assets/stylesheets/mobile/header.scss index 84832353ea6..e83acd1130e 100644 --- a/app/assets/stylesheets/mobile/header.scss +++ b/app/assets/stylesheets/mobile/header.scss @@ -47,6 +47,9 @@ // Fade in header avatar + icons if topic title is not visible in mobile header .panel { animation: fadein 0.5s; + @media (prefers-reduced-motion) { + animation-duration: 0s; + } } // A rendering bug in safari causes header SVGs to jitter after animations. // translateZ() forces gpu rendering which fixes the issue. diff --git a/app/assets/stylesheets/wizard.scss b/app/assets/stylesheets/wizard.scss index 45a6656da36..96ffe21c33f 100644 --- a/app/assets/stylesheets/wizard.scss +++ b/app/assets/stylesheets/wizard.scss @@ -144,8 +144,10 @@ body.wizard { &__field.invalid input { outline: 0; border: 3px solid var(--danger); - animation: bump 0.25s ease-in-out; - animation-iteration-count: 2; + @media (prefers-reduced-motion: no-preference) { + animation: bump 0.25s ease-in-out; + animation-iteration-count: 2; + } } &__field label { diff --git a/plugins/chat/assets/stylesheets/common/chat-composer-button.scss b/plugins/chat/assets/stylesheets/common/chat-composer-button.scss index 1df21c340b0..3a818c87d03 100644 --- a/plugins/chat/assets/stylesheets/common/chat-composer-button.scss +++ b/plugins/chat/assets/stylesheets/common/chat-composer-button.scss @@ -56,7 +56,9 @@ } .chat-composer.is-sending & { - animation: sendingScales 1s infinite linear; + @media (prefers-reduced-motion: no-preference) { + animation: sendingScales 1s infinite linear; + } } .d-icon { diff --git a/plugins/chat/assets/stylesheets/common/chat-replying-indicator.scss b/plugins/chat/assets/stylesheets/common/chat-replying-indicator.scss index 5f3c2cce24d..b71cd1e319e 100644 --- a/plugins/chat/assets/stylesheets/common/chat-replying-indicator.scss +++ b/plugins/chat/assets/stylesheets/common/chat-replying-indicator.scss @@ -24,7 +24,9 @@ .chat-replying-indicator__dot { 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) { animation-delay: -1.6s; } diff --git a/plugins/chat/assets/stylesheets/common/chat-selection-manager.scss b/plugins/chat/assets/stylesheets/common/chat-selection-manager.scss index 2d3e4bab323..d4ab08890aa 100644 --- a/plugins/chat/assets/stylesheets/common/chat-selection-manager.scss +++ b/plugins/chat/assets/stylesheets/common/chat-selection-manager.scss @@ -20,6 +20,9 @@ &__copy-success { animation: chat-quote-message-background-fade-highlight 2s ease-out 3s; + @media (prefers-reduced-motion) { + animation-duration: 0s; + } animation-fill-mode: forwards; background-color: var(--success-low); color: var(--primary); diff --git a/plugins/chat/assets/stylesheets/common/chat-skeleton.scss b/plugins/chat/assets/stylesheets/common/chat-skeleton.scss index c487474def3..adcd57d5a3f 100644 --- a/plugins/chat/assets/stylesheets/common/chat-skeleton.scss +++ b/plugins/chat/assets/stylesheets/common/chat-skeleton.scss @@ -125,7 +125,9 @@ rgba(var(--chat-skeleton-animation-rgb), 0.3) 50%, 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: ""; } diff --git a/plugins/chat/assets/stylesheets/mobile/chat-message.scss b/plugins/chat/assets/stylesheets/mobile/chat-message.scss index 3e66d09af4a..e6f74555963 100644 --- a/plugins/chat/assets/stylesheets/mobile/chat-message.scss +++ b/plugins/chat/assets/stylesheets/mobile/chat-message.scss @@ -24,9 +24,10 @@ .chat-message-container { transition: transform 400ms; transform: scale(1); - - &.-active { - animation: scale-animation 400ms; + @media (prefers-reduced-motion: no-preference) { + &.-active { + animation: scale-animation 400ms; + } } } diff --git a/plugins/discourse-presence/assets/stylesheets/presence.scss b/plugins/discourse-presence/assets/stylesheets/presence.scss index 80121102745..4235f17ac49 100644 --- a/plugins/discourse-presence/assets/stylesheets/presence.scss +++ b/plugins/discourse-presence/assets/stylesheets/presence.scss @@ -26,7 +26,9 @@ .dot { display: inline-block; - animation: wave 1.8s linear infinite; + @media (prefers-reduced-motion: no-preference) { + animation: wave 1.8s linear infinite; + } &:nth-child(2) { animation-delay: -1.6s;