احترام تفضيلات الحركة للمستخدمين
نشرت: 2022-03-10prefers-reduced-motion
المفضل بدعم ممتاز في جميع المتصفحات الحديثة التي تعود إلى بضع سنوات. في هذه المقالة ، تشرح ميشيل باركر سبب عدم وجود سبب لعدم استخدامه اليوم لتسهيل الوصول إلى مواقعك.عند العمل باستخدام الحركة على الويب ، من المهم مراعاة أنه ليس كل شخص يستخدمها بنفس الطريقة. ما قد يبدو سلسًا وملمسًا بالنسبة للبعض قد يكون مزعجًا أو مشتتًا للآخرين - أو الأسوأ من ذلك ، أن يتسبب في الشعور بالمرض ، أو حتى يسبب النوبات. قد يكون لمواقع الويب ذات الحركة الكبيرة أيضًا تأثير أكبر على عمر بطارية الأجهزة المحمولة ، أو تتسبب في استخدام المزيد من البيانات (يتطلب تشغيل مقاطع الفيديو تلقائيًا ، على سبيل المثال ، بيانات المستخدم أكثر من الصورة الثابتة). هذه فقط بعض الأسباب التي تجعل المواقع ذات الحركة الثقيلة غير مرغوبة للجميع.
تمكّن معظم أنظمة التشغيل الجديدة المستخدم من تعيين تفضيلات الحركة في إعدادات مستوى النظام. يسمح لنا الاستعلام عن الوسائط prefers-reduced-motion
(جزء من مواصفات استعلامات الوسائط من المستوى 5) باكتشاف تفضيلات الحركة على مستوى النظام للمستخدمين ، وتطبيق أنماط CSS التي تحترم ذلك.
الخياران لتفضيل prefers-reduced-motion
هما reduce
أو no-preference
. يمكننا استخدامه بالطريقة التالية في CSS الخاص بنا لإيقاف تشغيل الرسوم المتحركة لعنصر ما إذا كان المستخدم قد حدد تفضيلًا صريحًا للحركة المخفضة :
.some-element { animation: bounce 1200ms; } @media (prefers-reduced-motion: reduce) { .some-element { animation: none; } }
على العكس من ذلك ، لا يمكننا ضبط الرسوم المتحركة إلا إذا لم يكن لدى المستخدم تفضيل للحركة. يتميز هذا بميزة تقليل مقدار الكود الذي نحتاج إلى كتابته ، ويعني أنه من غير المرجح أن ننسى تلبية تفضيلات الحركة للمستخدمين:
@media (prefers-reduced-motion: no-preference) { .some-element { animation: bounce 1200ms; } }
هناك ميزة إضافية تتمثل في أن المتصفحات القديمة التي لا تدعم prefers-reduced-motion
ستتجاهل القاعدة وستعرض فقط العنصر الأصلي الخالي من الحركة.
أي قاعدة؟
على عكس استعلامات الوسائط min-width
و max-width
، حيث يكون الإجماع الأكثر أو أقل هو الجوّال أولاً (وبالتالي يفضل min-width
) ، لا توجد طريقة واحدة "صحيحة" لكتابة أنماط الحركة المخفضة. أميل إلى تفضيل المثال الثاني (تطبيق الرسوم المتحركة فقط إذا كان prefers-reduced-motion: no-preference
صحيحًا) ، للأسباب المذكورة أعلاه. كتبت تاتيانا ماك هذه المقالة الممتازة التي تغطي بعض الأساليب التي قد يفكر المطورون في اتباعها ، بالإضافة إلى الكثير من النقاط الرائعة الأخرى ، بما في ذلك الأسئلة الرئيسية التي يجب طرحها عند التصميم باستخدام الحركة على الويب.
كما هو الحال دائمًا ، يعد الاتصال الجماعي والاستراتيجية المتسقة عاملين أساسيين لضمان تغطية جميع القواعد عندما يتعلق الأمر بإمكانية الوصول إلى الويب.
الاستخدام العملي: تطبيق prefers-reduced-motion
سلوك التمرير
prefers-reduced-motion
العديد من التطبيقات بخلاف تطبيق (أو عدم تطبيق) حركات الإطارات الرئيسية أو الانتقالات. أحد الأمثلة على ذلك هو التمرير السلس. إذا قمنا بتعيين scroll-behaviour: smooth
على عنصر html
الخاص بنا ، فعندما ينقر المستخدم على رابط الربط في الصفحة ، سيتم تمريره بسلاسة إلى الموضع المناسب على الصفحة ( غير مدعوم حاليًا في Safari ):
html { scroll-behavior: smooth; }
لسوء الحظ ، في CSS ليس لدينا سيطرة كبيرة على هذا السلوك في الوقت الحالي. إذا كانت لدينا صفحة طويلة من المحتوى ، فإن الصفحة يتم تمريرها بسرعة كبيرة ، مما قد يكون تجربة غير سارة لشخص لديه حساسية للحركة. من خلال تغليفه في استعلام وسائط ، يمكننا منع تطبيق هذا السلوك في الحالات التي يكون فيها المستخدم لديه تفضيل reduced-motion
:
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
تقديم الطعام لتفضيلات الحركة في جافا سكريبت
نحتاج أحيانًا إلى تطبيق الحركة في JavaScript بدلاً من CSS. يمكننا بالمثل اكتشاف تفضيلات حركة المستخدم باستخدام JS ، باستخدام matchMedia
. دعونا نرى كيف يمكننا تنفيذ سلوك التمرير السلس بشكل مشروط في كود JS الخاص بنا:
/* Set the media query */ const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)') button.addEventListener('click', () => { /* If the media query matches, set scroll behavior variable to 'auto', otherwise set it to 'smooth' */ const behavior = prefersReducedMotion.matches ? 'auto' : 'smooth' /* When the button is clicked, the user will be scrolled to the top */ window.scrollTo({ x: 0, y: 0, behavior }) })
يمكن استخدام نفس المبدأ لاكتشاف ما إذا كان سيتم تنفيذ واجهات مستخدم غنية بالحركة باستخدام مكتبات JS - أو حتى ما إذا كان سيتم تحميل المكتبات نفسها.
في مقتطف الشفرة التالي ، ترجع الوظيفة مبكرًا إذا كان المستخدم يفضل الحركة المنخفضة ، وتجنب الاستيراد غير الضروري لتبعية كبيرة - وهو فوز أداء للمستخدم. إذا لم يكن لديهم مجموعة تفضيلات الحركة ، فيمكننا عندئذٍ استيراد مكتبة الرسوم المتحركة Greensock ديناميكيًا وتهيئة الرسوم المتحركة الخاصة بنا.
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)') const loadGSAPAndInitAnimations = () => { /* If user prefers reduced motion, do nothing */ if (prefersReducedMotion.matches) return /* Otherwise, import the GSAP module and initialize animations */ import('gsap').then((object) => { const gsap = object.default /* Initialize animations with GSAP here */ }) } loadGSAPAndInitAnimations()
reduced-motion
لا تعني عدم وجود حركة
عند التصميم لتفضيلات الحركة المخفضة ، من المهم أن نستمر في تزويد المستخدم بمؤشرات هادفة ويمكن الوصول إليها عن وقت حدوث الإجراء. على سبيل المثال ، عند إيقاف تشغيل حالة التمرير التي تشتت الانتباه أو كثيفة الحركة للمستخدمين الذين يفضلون تقليل الحركة ، يجب أن نحرص على توفير نمط بديل واضح عندما يحوم المستخدم فوق العنصر.
يُظهر العرض التوضيحي التالي انتقالًا مفصلاً عندما يقوم المستخدم بالتمرير أو التركيز على عنصر المعرض إذا لم يكن لديه مجموعة تفضيلات الحركة. إذا كانوا يفضلون تقليل الحركة ، فسيكون الانتقال أكثر دقة ، ومع ذلك لا يزال يشير بوضوح إلى حالة التمرير:
لا تعني الحركة المنخفضة بالضرورة إزالة جميع التحويلات من صفحة الويب الخاصة بنا أيضًا. على سبيل المثال ، من غير المحتمل أن يتسبب الزر الذي يحتوي على رمز سهم صغير يتحرك بضع بكسلات عند التمرير في حدوث مشكلات لشخص يفضل تجربة حركة منخفضة ، ويوفر مؤشرًا أكثر فائدة لتغيير الحالة من اللون وحده.
أرى أحيانًا مطورين يطبقون أنماط حركة مخفضة بالطريقة التالية ، مما يلغي جميع الانتقالات والحركات على جميع العناصر:
@media screen and (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; scroll-behavior: auto !important; } }
يمكن القول إن هذا أفضل من تجاهل تفضيلات الحركة للمستخدمين ، لكنه لا يسمح لنا بتصميم العناصر بسهولة لتوفير انتقالات أكثر دقة عند الضرورة.
في مقتطف الشفرة التالي ، لدينا زر ينمو في الحجم عند التمرير . نحن بصدد نقل الألوان والمقياس ، لكن المستخدمين الذين يفضلون الحركة المنخفضة لن يحصلوا على أي انتقال على الإطلاق:
button { background-color: hotpink; transition: color 300ms, background-color 300ms, transform 500ms cubic-bezier(.44, .23, .47, 1.27); } button:hover, button:focus { background-color: darkviolet; color: white; transform: scale(1.2); } @media screen and (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; scroll-behavior: auto !important; } button { /* Even though we would still like to transition the colors of our button, the following rule will have no effect */ transition: color 200ms, background-color 200ms; } button:hover, button:focus { /* Preventing the button scaling on hover */ transform: scale(1); } }
تحقق من هذا العرض لمعرفة التأثير. ربما لا يكون هذا مثاليًا ، لأن تبديل اللون المفاجئ بدون انتقال قد يكون أكثر تنافرًا من انتقال بضع مئات من الألف من الثانية. هذا هو أحد الأسباب التي تجعلني ، بشكل عام ، أفضل أسلوب تقليل الحركة على أساس كل حالة على حدة.
إذا كنت مهتمًا ، فهذا هو نفس العرض التوضيحي المعاد تصميمه للسماح بتخصيص الانتقال عند الضرورة. يستخدم خاصية مخصصة لمدة الانتقال ، مما يسمح لنا بتبديل نطاق الانتقال وإيقافه دون الحاجة إلى إعادة كتابة الإعلان بالكامل.
عندما تكون إزالة الرسوم المتحركة أفضل
يثير إريك بيلي النقطة التي مفادها أنه "ليس كل جهاز يمكنه الوصول إلى الويب يمكنه أيضًا عرض الرسوم المتحركة ، أو عرض الرسوم المتحركة بسلاسة" في مقالته ، "إعادة النظر تفضل الحركة المنخفضة ، استعلام الوسائط ذات الحركة المنخفضة". بالنسبة للأجهزة ذات معدل التحديث المنخفض ، والتي يمكن أن تسبب رسومًا متحركة سيئة ، فقد يكون من الأفضل في الواقع إزالة الرسوم المتحركة . يمكن استخدام ميزة وسائط update
لتحديد ذلك:
@media screen and (prefers-reduced-motion: reduce), (update: slow) { * { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; } }
تأكد من قراءة المقالة الكاملة لتوصيات إريك ، لأنه شخص من الدرجة الأولى يجب اتباعه في مجال إمكانية الوصول.
مجموع كل الأجزاء
من المهم أن تضع في اعتبارك التصميم العام للصفحة عند التركيز بشدة على CSS على مستوى المكون. ما قد يبدو رسمًا متحركًا غير ضار إلى حد ما على مستوى المكون قد يكون له تأثير أكبر بكثير عند تكراره في جميع أنحاء الصفحة ، وهو أحد الأجزاء المتحركة العديدة.
في مقال تاتيانا ، تقترح تنظيم الرسوم المتحركة (مع prefers-reduced-motion
المفضلة) في ملف CSS واحد ، والذي يمكن تحميله فقط إذا كان تقييم (prefers-reduced-motion: no-preference)
صحيحًا. يمكن أن يكون لرؤية المجموع الكلي لجميع الرسوم المتحركة لدينا فائدة إضافية تتمثل في مساعدتنا في تصور تجربة زيارة الموقع ككل ، وتصميم أنماط الحركة المخفضة وفقًا لذلك.
تبديل الحركة الصريحة
على الرغم من أن prefers-reduced-motion
مفيدة ، إلا أن لها عيبًا يتمثل في تلبية احتياجات المستخدمين الذين هم على دراية بالميزة الموجودة في إعدادات النظام الخاصة بهم. يفتقر الكثير من المستخدمين إلى المعرفة بهذا الإعداد ، بينما قد يستخدم الآخرون جهاز كمبيوتر مستعارًا ، دون الوصول إلى الإعدادات على مستوى النظام. ومع ذلك ، قد يكون الآخرون سعداء بالحركة بالنسبة للغالبية العظمى من المواقع ، لكنهم يجدون مواقع ذات استخدام كثيف للحركة يصعب تحملها.
قد يكون من المزعج أن تضطر إلى تعديل تفضيلات النظام لمجرد زيارة موقع واحد. لهذه الأسباب ، في بعض الحالات ، قد يكون من الأفضل توفير تحكم صريح على الموقع نفسه للتبديل بين تشغيل وإيقاف الحركة . يمكننا تنفيذ هذا مع JS.
يحتوي العرض التوضيحي التالي على عدة دوائر تنجرف حول الخلفية. يتم تحديد أنماط الرسوم المتحركة الأولية من خلال تفضيلات نظام المستخدم (مع تفضيلات prefers-reduced-motion
) ، ومع ذلك ، فإن المستخدم لديه القدرة على تبديل الحركة أو إيقاف تشغيلها عبر زر. هذا يضيف فئة إلى body
، والتي يمكننا استخدامها لتعيين الأنماط اعتمادًا على التفضيل المحدد. على سبيل المكافأة ، يتم الاحتفاظ أيضًا باختيار تفضيل الحركة في التخزين المحلي - لذلك "يتم تذكره" عند زيارة المستخدم التالية.
خصائص مخصصة
تتمثل إحدى الميزات في العرض التوضيحي في أن التبديل يعيّن خاصية مخصصة ، --playState
، والتي يمكننا استخدامها لتشغيل الرسوم المتحركة أو إيقافها مؤقتًا. قد يكون هذا مفيدًا بشكل خاص إذا كنت بحاجة إلى إيقاف عدد من الرسوم المتحركة مؤقتًا أو تشغيلها مرة واحدة. بادئ ذي بدء ، قمنا بتعيين حالة التشغيل على paused
:
.circle { animation-play-state: var(--playState, paused); }
إذا قام المستخدم بتعيين تفضيل لتقليل الحركة في إعدادات النظام الخاصة به ، فيمكننا ضبط حالة التشغيل على running
:
@media (prefers-reduced-motion: no-preference) { body { --playState: running; } }
ملاحظة: تعيين هذا على body
، على عكس العنصر الفردي ، يعني أنه يمكن توريث الخاصية المخصصة.
عندما ينقر المستخدم على زر التبديل ، يتم تحديث الخاصية المخصصة في النص body
، مما يؤدي إلى تبديل أي حالات يتم استخدامها فيها:
// This will pause all animations that use the `--playState` custom property document.body.style.setProperty('--playState', 'paused')
قد لا يكون هذا هو الحل المثالي في جميع الحالات ، ولكن إحدى الميزات هي أن الرسوم المتحركة تتوقف مؤقتًا عندما ينقر المستخدم على زر التبديل ، بدلاً من القفز مرة أخرى إلى حالتها الأولية ، الأمر الذي قد يكون مزعجًا للغاية.
شكر خاص لسكوت أوهارا لتوصياته لتحسين إمكانية الوصول إلى زر التبديل. لقد جعلني أدرك أن بعض برامج قراءة الشاشة لا تعلن عن نص الزر المحدث ، والذي يتم تغييره عندما ينقر المستخدم على الزر ، واقترح role="switch"
على الزر بدلاً من ذلك ، مع on
أو off
تشغيل خيار aria-checked
عند النقر.
مكون الفيديو
في بعض الحالات ، قد يكون تبديل الحركة على مستوى المكون خيارًا أفضل. خذ صفحة ويب بها خلفية فيديو يتم تشغيلها تلقائيًا. يجب أن نتأكد من عدم تشغيل الفيديو تلقائيًا للمستخدمين الذين يفضلون تقليل الحركة ، ولكن لا يزال يتعين علينا توفير طريقة لهم لتشغيل الفيديو فقط إذا اختاروا ذلك . (قد يجادل البعض بأنه يجب علينا تجنب تشغيل مقاطع الفيديو تلقائيًا ، لكننا لا نفوز دائمًا في تلك المعركة!) وبالمثل ، إذا تم تعيين مقطع فيديو على التشغيل التلقائي للمستخدمين بدون تفضيل معلن ، فيجب علينا أيضًا توفير طريقة لهم للقيام بذلك وقفة الفيديو.
يوضح هذا العرض التوضيحي كيف يمكننا تعيين سمة التشغيل التلقائي عندما لا يكون لدى المستخدم أي تفضيل محدد للحركة ، مع تنفيذ زر تشغيل / إيقاف مؤقت مخصص للسماح له أيضًا بتبديل التشغيل ، بغض النظر عن التفضيل:
(لقد عثرت لاحقًا على هذا المنشور بواسطة Scott O'Hara ، الذي يوضح بالتفصيل حالة الاستخدام هذه بالضبط.)
استخدام عنصر <picture>
كتب كريس كويير مقالًا مثيرًا للاهتمام يجمع بين عدة تقنيات لتحميل مصادر وسائط مختلفة اعتمادًا على تفضيلات حركة المستخدم. هذا أمر رائع ، لأنه يعني أنه بالنسبة للمستخدمين الذين يفضلون تقليل الحركة ، فلن يتم تنزيل ملف GIF الأكبر بكثير. الجانب السلبي ، بقدر ما أستطيع أن أرى ، هو أنه بمجرد تنزيل الملف ، لا توجد طريقة للمستخدم للعودة إلى البديل الخالي من الحركة.
أقوم بإنشاء نسخة معدلة من العرض التوضيحي الذي يضيف هذا الخيار. (قم بتشغيل reduced-motion
في تفضيلات النظام لديك لرؤيتها أثناء العمل.) لسوء الحظ ، عند التبديل بين الخيارات المتحركة والخالية من الحركة في Chrome ، يبدو أن ملف GIF يتم تنزيله من جديد في كل مرة ، وهذا ليس هو الحال في متصفحون اخرون:
ومع ذلك ، تبدو هذه التقنية وكأنها طريقة أكثر احترامًا لعرض صور GIF ، والتي يمكن أن تكون مصدر إحباط للمستخدمين.
دعم المتصفح والأفكار النهائية
prefers-reduced-motion
دعمًا ممتازًا في جميع المتصفحات الحديثة التي تعود إلى بضع سنوات. كما رأينا ، من خلال اتباع نهج تقليل الحركة أولاً ، فإن المتصفحات غير الداعمة ستحصل ببساطة على احتياطي reduced-motion
. لا يوجد سبب لعدم استخدامه اليوم لجعل الوصول إلى مواقعك أكثر سهولة.
من المؤكد أن أدوات التبديل المخصصة لها مكان ، ويمكنها تحسين تجربة المستخدمين الذين ليسوا على دراية بهذا الإعداد أو ما يفعله. الجانب السلبي للمستخدم هو عدم الاتساق - إذا اضطر كل مطور إلى التوصل إلى حل خاص به ، يحتاج المستخدم إلى البحث عن تبديل الحركة في مكان مختلف على كل موقع ويب.
يبدو أن الطبقة المفقودة هنا هي المتصفحات . أود أن أرى المتصفحات تنفذ تبديلًا reduced-motion
، في مكان ما يسهل على المستخدم الوصول إليه ، حتى يعرف الناس مكان العثور عليه بغض النظر عن الموقع الذي يتصفحونه. قد يشجع المطورين على قضاء المزيد من الوقت في ضمان إمكانية الوصول إلى الحركة أيضًا.
موارد ذات الصلة
- مواصفات استعلامات الوسائط من المستوى 5 ، اتحاد شبكة الويب العالمية (W3C)
-
prefers-reduced-motion
، MDN Web Docs ، Mozilla - تصميم مع حركة مخفضة لحساسيات الحركة ، Val Head ، مجلة Smashing
- اتباع نهج عدم الحركة أولاً للرسوم المتحركة ، تاتيانا ماك
- تقنية الصور المتحركة المخفضة ، خذ 2 ، كريس كويير ، CSS-Tricks
-
prefers-reduced-motion
إعادة النظر إلى الحركة المنخفضة ، استعلام وسائط الحركة المخفضة ، إريك بيلي ، CSS-Tricks - تقليل الحركة لتحسين إمكانية الوصول ، ليندسي كوباتش