prefers-reduced-motion: گاهی اوقات حرکت کمتر بیشتر است

کوئری رسانه‌ای prefers-reduced-motion تشخیص می‌دهد که آیا کاربر از سیستم عامل درخواست کرده است که میزان انیمیشن یا حرکت مورد استفاده خود را به حداقل برساند یا خیر.

همه انیمیشن‌ها یا انتقال‌های تزئینی را دوست ندارند و برخی از کاربران هنگام مواجهه با پیمایش اختلاف منظر، جلوه‌های بزرگنمایی و موارد دیگر، دچار حالت تهوع می‌شوند. کوئری رسانه ترجیحی کاربر prefers-reduced-motion به شما امکان می‌دهد یک نسخه کاهش‌یافته از سایت خود را برای کاربرانی که این ترجیح را ابراز کرده‌اند، طراحی کنید.

Browser Support

  • کروم: ۷۴.
  • لبه: ۷۹.
  • فایرفاکس: ۶۳.
  • سافاری: ۱۰.۱.

Source

حرکت بیش از حد در زندگی واقعی و وب

چند روز پیش، داشتم با بچه‌هایم اسکیت روی یخ بازی می‌کردم. روز خیلی خوبی بود، خورشید می‌درخشید و پیست یخ پر از آدم بود ⛸. تنها مشکلش این بود: من با شلوغی زیاد کنار نمی‌آییم. با این همه هدف متحرک، نمی‌توانم روی هیچ چیز تمرکز کنم و در نهایت گم می‌شوم و احساس می‌کنم که کاملاً گیج شده‌ام، تقریباً مثل اینکه به لانه مورچه‌ها خیره شده‌ام 🐜.

انبوهی از مردم که در حال اسکیت روی یخ بودند.
اضافه بار بصری در زندگی واقعی

Occasionally, the same can happen on the web: with flashing ads, fancy parallax effects, surprising reveal animations, autoplaying videos, and more, the web sometimes can be quite overwhelming … Happily, unlike in real life, there is a solution to that. The CSS media query prefers-reduced-motion lets developers create a variant of a page for users who, well, prefer reduced motion. This can consist of anything from refraining from having autoplaying videos to disabling certain purely decorative effects, to completely redesigning a page for certain users.

قبل از اینکه به این ویژگی بپردازم، اجازه دهید یک قدم به عقب برگردم و به این فکر کنم که انیمیشن‌ها در وب برای چه مواردی استفاده می‌شوند. اگر مایل باشید، می‌توانید از اطلاعات پس‌زمینه صرف نظر کنید و مستقیماً به جزئیات فنی بپردازید .

انیمیشن در وب

انیمیشن اغلب برای ارائه بازخورد به کاربر استفاده می‌شود، به عنوان مثال، برای اینکه به آنها اطلاع دهد که عملی دریافت شده و در حال پردازش است. به عنوان مثال، در یک وب‌سایت خرید، می‌توان یک محصول را به صورت انیمیشنی به داخل یک سبد خرید مجازی که به صورت یک آیکون در گوشه بالا سمت راست سایت نمایش داده می‌شود، پرتاب کرد.

مورد استفاده دیگر شامل استفاده از حرکت برای هک کردن درک کاربر با استفاده از ترکیبی از صفحات اسکلتی، ابرداده‌های زمینه‌ای و پیش‌نمایش‌های تصویر با کیفیت پایین است تا زمان زیادی از کاربر را اشغال کند و کل تجربه را سریع‌تر جلوه دهد. ایده این است که به کاربر زمینه‌ای از آنچه در حال وقوع است ارائه شود و در عین حال، موارد در سریع‌ترین زمان ممکن بارگذاری شوند.

Finally, there are decorative effects like animated gradients, parallax scrolling, background videos, and several others. While many users enjoy such animations, some users dislike them because they feel distracted or slowed down by them. In the worst case, users may even suffer from motion sickness as if it were a real life experience, so for these users reducing animations is a medical necessity .

اختلال طیف دهلیزی ناشی از حرکت

Some users experience distraction or nausea from animated content . For example, scrolling animations can cause vestibular disorders when elements other than the main element associated with the scrolling move around a lot. For example, parallax scrolling animations can cause vestibular disorders because background elements move at a different rate than foreground elements. Vestibular (inner ear) disorder reactions include dizziness, nausea, and migraine headaches, and sometimes require bed rest to recover.

حذف حرکت در سیستم عامل ها

Many operating systems have had accessibility settings for specifying a preference for reduced motion for a long time. The following screenshots show macOS Mojave's Reduce motion preference and Android Pie's Remove animations preference. When checked, these preferences cause the operating system to not use decorative effects like app launching animations. Applications themselves can and should honor this setting, too, and remove all unnecessary animations.

صفحه تنظیمات macOS که کادر انتخاب «کاهش حرکت» علامت خورده است.
صفحه تنظیمات اندروید که کادر «حذف انیمیشن‌ها» علامت خورده است.

حذف حرکت در وب

Media Queries Level 5 brings the reduced motion user preference to the web as well. Media queries allow authors to test and query values or features of the user agent or display device independent of the document being rendered. The media query prefers-reduced-motion is used to detect if the user has set an operating system preference to minimize the amount of animation or motion it uses. It can take two possible values:

  • no-preference : نشان می‌دهد که کاربر هیچ ترجیحی در سیستم عامل اصلی ایجاد نکرده است. مقدار این کلمه کلیدی در متن بولی، false ارزیابی می‌شود.
  • reduce : نشان می‌دهد که کاربر ترجیحی برای سیستم عامل تعیین کرده است که نشان می‌دهد رابط‌ها باید حرکت یا انیمیشن را به حداقل برسانند، ترجیحاً تا جایی که تمام حرکات غیرضروری حذف شوند.

کار با کوئری مدیا از زمینه‌های CSS و جاوا اسکریپت

همانند تمام کوئری‌های رسانه‌ای، prefers-reduced-motion می‌توان از یک زمینه CSS و از یک زمینه جاوا اسکریپت بررسی کرد.

To illustrate both, assume I have an important sign-up button that I want the user to click. I could define an attention-catching "vibrate" animation, but as a good web citizen I will only play it for those users who are explicitly OK with animations, but not everyone else, which can be users who have opted out of animations, or users on browsers that don't understand the media query.

/*
  If the user has expressed their preference for
  reduced motion, then don't use animations on buttons.
*/
@media (prefers-reduced-motion: reduce) {
  button {
    animation: none;
  }
}

/*
  If the browser understands the media query and the user
  explicitly hasn't set a preference, then use animations on buttons.
*/
@media (prefers-reduced-motion: no-preference) {
  button {
    /* `vibrate` keyframes are defined elsewhere */
    animation: vibrate 0.3s linear infinite both;
  }
}

To illustrate how to work with prefers-reduced-motion with JavaScript, imagine I have defined a complex animation with the Web Animations API . While CSS rules will be dynamically triggered by the browser when the user preference changes, for JavaScript animations I have to listen for changes myself, and then manually stop my potentially in-flight animations (or restart them if the user lets me):

const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
mediaQuery.addEventListener('change', () => {
  console.log(mediaQuery.media, mediaQuery.matches);
  // Stop JavaScript-based animations.
});

توجه داشته باشید که پرانتزهای اطراف کوئری رسانه‌ای اصلی الزامی هستند:

نکن
window.matchMedia('prefers-reduced-motion: reduce');
انجام دهید
window.matchMedia('(prefers-reduced-motion: reduce)');

کار با کوئری رسانه از زمینه‌های <picture>

یک مورد استفاده جالب، وابسته کردن پخش یک فایل متحرک AVIF، WebP یا GIF به ویژگی media است. اگر (prefers-reduced-motion: no-preference) برابر با true باشد، نمایش نسخه متحرک بی‌خطر است، در غیر این صورت نسخه ثابت نمایش داده می‌شود:

<picture>
  <!-- Animated versions. -->
  <source
    srcset="nyancat.avifs"
    type="image/avif"
    media="(prefers-reduced-motion: no-preference)"
  />
  <source
    srcset="nyancat.gif"
    type="image/gif"
    media="(prefers-reduced-motion: no-preference)"
  />
  <!-- Static versions. -->
  <img src="nyancat.png" alt="Nyan cat" width="250" height="250" />
</picture>

می‌توانید مثال زیر را ببینید. برای مشاهده‌ی تفاوت، تنظیمات حرکتی دستگاه خود را تغییر دهید.

گربه معروف نیان.

تنظیمات برگزیده کاربر را در زمان درخواست کشف کنید

سربرگ راهنمای کلاینت Sec-CH-Prefers-Reduced-Motion به سایت‌ها اجازه می‌دهد تا تنظیمات حرکتی کاربر را به صورت اختیاری در زمان درخواست دریافت کنند و به سرورها اجازه می‌دهد تا CSS مناسب را به دلایل عملکردی درون‌خطی کنند.

نسخه آزمایشی

I have created a little demo based on Rogério Vicente's amazing 🐈 HTTP status cats . First, take a moment to appreciate the joke, it's hilarious and I'll wait. Now that you're back, let me introduce the demo . When you scroll, each HTTP status cat alternatingly appears from either the right or the left side. It's a buttery smooth 60 FPS animation, but as outlined before, some users may dislike it or even get motion sick by it, so the demo is programmed to respect prefers-reduced-motion . This even works dynamically, so users can change their preference on-the-fly, no reload required. If a user prefers reduced motion, the non-necessary reveal animations are gone, and just the regular scrolling motion is left. The following screencast shows the demo in action:

ویدیوی نسخه آزمایشی برنامه prefers-reduced-motion

نتیجه‌گیری

احترام به ترجیحات کاربر برای وب‌سایت‌های مدرن کلیدی است و مرورگرها ویژگی‌های بیشتر و بیشتری را در اختیار توسعه‌دهندگان وب قرار می‌دهند تا این کار را انجام دهند. نمونه دیگری که راه‌اندازی شده است prefers-color-scheme است که تشخیص می‌دهد کاربر طرح رنگی روشن یا تیره را ترجیح می‌دهد. می‌توانید همه چیز در مورد prefers-color-scheme در مقاله من با عنوان «سلام تاریکی، دوست قدیمی من » 🌒 بخوانید.

گروه کاری CSS در حال استانداردسازی پرس‌وجوهای رسانه‌ای بیشتری در مورد ترجیحات کاربر است، مانند prefers-reduced-transparency (تشخیص می‌دهد که آیا کاربر شفافیت کاهش‌یافته را ترجیح می‌دهد)، prefers-contrast (تشخیص می‌دهد که آیا کاربر از سیستم درخواست افزایش یا کاهش میزان کنتراست بین رنگ‌های مجاور را کرده است) و inverted-colors (تشخیص می‌دهد که آیا کاربر رنگ‌های معکوس را ترجیح می‌دهد).

(امتیاز ویژه) کاهش اجباری حرکت در تمام وب‌سایت‌ها

همه سایت‌ها prefers-reduced-motion استفاده نمی‌کنند، یا شاید به اندازه کافی برای سلیقه شما مناسب نباشد. اگر به هر دلیلی می‌خواهید حرکت را در همه وب‌سایت‌ها متوقف کنید، در واقع می‌توانید. یک راه برای تحقق این امر، تزریق یک برگه سبک با CSS زیر به هر صفحه وبی است که بازدید می‌کنید. چندین افزونه مرورگر وجود دارد (با مسئولیت خودتان استفاده کنید!).

@media (prefers-reduced-motion: reduce) {
  *,
  ::before,
  ::after {
    animation-delay: -1ms !important;
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    background-attachment: initial !important;
    scroll-behavior: auto !important;
    transition-duration: 1ms !important;
    transition-delay: -1ms !important;
  }
}

The way this works is that the previous CSS overrides the durations of all animations and transitions to such a short time that they are not noticeable anymore. As some websites depend on an animation to be run in order to work correctly (maybe because a certain step depends on the firing of the animationend event ), the more radical animation: none !important; approach wouldn't work. Even the previous hack is not guaranteed to succeed on all websites (for example, it can't stop motion that was initiated using the Web Animations API ), so be sure to deactivate it when you notice breakage.

منابع

تقدیرنامه‌ها

تشکر فراوان از استیون مک‌گروئر که prefers-reduced-motion در کروم پیاده‌سازی کرده و به همراه راب دادسون ، این سند را نیز بررسی کرده‌اند.