שאילתת המדיה prefers-reduced-motion מזהה אם המשתמש ביקש ממערכת ההפעלה לצמצם את כמות האנימציה או התנועה שבה היא משתמשת.
לא כולם אוהבים אנימציות או מעברים דקורטיביים, ויש משתמשים שסובלים מבחילת נסיעה כשהם נתקלים בגלילה עם אפקט פרלקסה, באפקטים של שינוי מרחק התצוגה ועוד. שאילתת המדיה prefers-reduced-motion של העדפת המשתמש מאפשרת לכם לעצב גרסה עם פחות תנועה באתר למשתמשים שהביעו את ההעדפה הזו.
יותר מדי תנועה בחיים האמיתיים ובאינטרנט
לפני כמה ימים החלקתי על הקרח עם הילדים שלי. היה יום מקסים, השמש זרחה, וזירת ההחלקה הייתה מלאה באנשים ⛸. הבעיה היחידה הייתה שאני לא מסתדרת עם קהלים גדולים. בגלל כל כך הרבה מטרות נעות, אני לא מצליח להתמקד בשום דבר, ובסופו של דבר אני מרגיש אבוד ומוצף במידע ויזואלי, כמעט כמו בהתבוננות בקיני נמלים 🐜.
לפעמים זה קורה גם באינטרנט: מודעות מהבהבות, אפקטי פרלקסה מיוחדים, אנימציות מפתיעות של חשיפת מודעות, סרטונים שמופעלים אוטומטית ועוד. לפעמים האינטרנט יכול להיות די מבלבל…
למזלנו, בניגוד למציאות, יש פתרון לבעיה הזו. שאילתת המדיה ב-CSS prefers-reduced-motion מאפשרת למפתחים ליצור גרסה של דף למשתמשים שמעדיפים, ובכן, תנועה מופחתת. השינויים האלה יכולים להיות מכל הסוגים, למשל: הימנעות מהפעלה אוטומטית של סרטונים, השבתה של אפקטים מסוימים שנועדו רק לקישוט, או עיצוב מחדש של דף מסוים עבור משתמשים מסוימים.
לפני שאסביר על התכונה, אקח צעד אחד אחורה ואחשוב למה משמשות אנימציות באינטרנט. אם רוצים, אפשר גם לדלג על מידע הרקע ולעבור ישר לפרטים הטכניים.
אנימציה באינטרנט
לרוב משתמשים באנימציה כדי לספק משוב למשתמש, למשל כדי להודיע לו שפעולה התקבלה ועוברת עיבוד. לדוגמה, באתר קניות, יכול להיות שמוצר יוצג באנימציה כאילו הוא "עף" לתוך עגלת קניות וירטואלית, שמוצגת כסמל בפינה השמאלית העליונה של האתר.
מקרה שימוש נוסף הוא שימוש בתנועה כדי לשנות את תפיסת המשתמש באמצעות שילוב של מסכי שלד, מטא-נתונים הקשריים ותצוגות מקדימות של תמונות באיכות נמוכה, כדי להעסיק את המשתמש למשך זמן רב ולגרום לחוויה כולה להרגיש מהירה יותר. הרעיון הוא לספק למשתמש הקשר לגבי מה שעומד לקרות, ובמקביל לטעון את הדברים במהירות האפשרית.
לבסוף, יש אפקטים דקורטיביים כמו מעברי צבע מונפשים, גלילה עם אפקט פרלקסה, סרטונים ברקע ועוד. הרבה משתמשים נהנים מאנימציות כאלה, אבל יש משתמשים שלא אוהבים אותן כי הן מסיחות את דעתם או גורמות להם להרגיש שהן מאטות את העבודה. במקרה הגרוע ביותר, המשתמשים עלולים לסבול מבחילת נסיעה כאילו מדובר בחוויה מהחיים האמיתיים, ולכן עבור המשתמשים האלה צמצום האנימציות הוא צורך רפואי.
הפרעה וסטיבולרית בספקטרום שמופעלת על ידי תנועה
חלק מהמשתמשים חווים הסחת דעת או בחילה מתוכן מונפש. לדוגמה, אנימציות של גלילה עלולות לגרום להפרעות במערכת שיווי המשקל כשהאלמנטים שאינם האלמנט הראשי שמשויך לגלילה זזים הרבה. לדוגמה, אנימציות של גלילה עם אפקט פרלקסה עלולות לגרום להפרעות במערכת שיווי המשקל, כי רכיבים ברקע זזים במהירות שונה מרכיבים בחזית. תגובות להפרעות במערכת הווסטיבולרית (באוזן הפנימית) כוללות סחרחורת, בחילה וכאבי ראש של מיגרנה, ולפעמים נדרשת מנוחה במיטה כדי להחלים.
הסרת התנועה במערכות הפעלה
במערכות הפעלה רבות יש הגדרות נגישות שמאפשרות לציין העדפה לתנועה מופחתת כבר הרבה זמן. בצילומי המסך הבאים מוצגת ההעדפה הפחתת התנועה ב-macOS Mojave וההעדפה הסרת אנימציות ב-Android Pie. אם מסמנים את התיבה, מערכת ההפעלה לא משתמשת באפקטים דקורטיביים כמו אנימציות של הפעלת אפליקציות. גם האפליקציות עצמן יכולות וצריכות להתחשב בהגדרה הזו ולהסיר את כל האנימציות שלא נחוצות.
הסרת התנועה בגרסה למחשב
Media Queries Level 5 מביא את העדפת המשתמש לגבי הפחתת התנועה גם לאינטרנט. שאילתות מדיה מאפשרות למחברים לבדוק ערכים או תכונות של סוכן המשתמש או של מכשיר התצוגה, או לשלוח להם שאילתות, בלי קשר למסמך שמוצג. שאילתת המדיה
prefers-reduced-motion משמשת כדי לזהות אם המשתמש הגדיר העדפה במערכת ההפעלה לצמצום כמות האנימציה או התנועה שמוצגת לו. הוא יכול לקבל שני ערכים אפשריים:
-
no-preference: מציין שהמשתמש לא הגדיר העדפה במערכת ההפעלה הבסיסית. הערך של מילת המפתח הזו הואfalseבהקשר בוליאני. -
reduce: מציין שהמשתמש הגדיר העדפה במערכת ההפעלה שמציינת שממשקי המשתמש צריכים למזער תנועה או אנימציה, ועדיף עד לרמה שבה כל התנועה הלא חיונית מוסרת.
עבודה עם שאילתת המדיה מהקשרים של CSS ו-JavaScript
כמו בכל שאילתות המדיה, אפשר לבדוק את prefers-reduced-motion מהקשר CSS ומקונטקסט JavaScript.
כדי להמחיש את שתי האפשרויות, נניח שיש לי לחצן חשוב להרשמה שאני רוצה שהמשתמש ילחץ עליו. אני יכול להגדיר אנימציה מושכת של 'רטט', אבל בתור משתמש אחראי באינטרנט, אציג אותה רק למשתמשים שהסכימו במפורש לצפות באנימציות, ולא לכל שאר המשתמשים. למשל, משתמשים שהביעו התנגדות לצפייה באנימציות, או משתמשים בדפדפנים שלא מבינים את שאילתת המדיה.
/*
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;
}
}
כדי להמחיש איך עובדים עם prefers-reduced-motion באמצעות JavaScript, נניח שהגדרתי אנימציה מורכבת באמצעות Web Animations API. כללי CSS יופעלו באופן דינמי על ידי הדפדפן כשהעדפת המשתמש תשתנה, אבל לגבי אנימציות ב-JavaScript, אני צריך להאזין לשינויים בעצמי, ואז לעצור ידנית את האנימציות שפועלות (או להפעיל אותן מחדש אם המשתמש מאפשר לי):
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 client hint מאפשרת לאתרים לקבל את העדפות התנועה של המשתמשים בזמן השליחה של הבקשה (אופציונלי), וכך השרתים יכולים להוסיף את ה-CSS הנכון לשורת הקוד מסיבות שקשורות לביצועים.
הדגמה (דמו)
יצרתי הדגמה קטנה שמבוססת על 🐈 HTTP status cats המדהים של רוגריו ויסנטה. קודם כול, כדאי להקדיש רגע להבנת הבדיחה. היא מצחיקה מאוד, ואני אחכה. עכשיו כשהכול מוכן, הנה ההדגמה. כשגוללים, כל קטגוריית סטטוס HTTP מופיעה לסירוגין מצד ימין או מצד שמאל. זו אנימציה חלקה מאוד של 60 FPS, אבל כמו שצוין קודם, חלק מהמשתמשים עלולים לא לאהוב אותה או אפילו לסבול ממנה מבחילה, ולכן ההדגמה מתוכנתת כך שתכבד את prefers-reduced-motion. ההגדרה הזו פועלת באופן דינמי, כך שהמשתמשים יכולים לשנות את ההעדפה שלהם תוך כדי תנועה, בלי צורך לטעון מחדש את הדף. אם משתמש מעדיף תנועה מופחתת, אנימציות החשיפה שלא נחוצות לא יופיעו, ורק תנועת הגלילה הרגילה תישאר. בסרטון הבא מוצגת ההדגמה בפעולה:
prefers-reduced-motion הדמו
של האפליקציה
מסקנות
התחשבות בהעדפות המשתמשים היא דבר חשוב מאוד באתרים מודרניים, והדפדפנים חושפים יותר ויותר תכונות שמאפשרות למפתחי אתרים לעשות זאת. דוגמה נוספת שהושקה היא prefers-color-scheme, שמאפשרת לזהות אם המשתמש מעדיף ערכת צבעים בהירה או כהה. במאמר שלי Hello Darkness, My Old Friend 🌒 אפשר לקרוא את כל הפרטים על 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;
}
}
השיטה הזו פועלת כך שקובץ ה-CSS הקודם מבטל את משכי הזמן של כל האנימציות והמעברים, ומקצר אותם כל כך עד שלא ניתן להבחין בהם יותר. יש אתרים שפועלים בצורה תקינה רק אם מופעלת בהם אנימציה (למשל, כי שלב מסוים תלוי בהפעלת האירוע animationend). במקרים כאלה, הגישה הקיצונית יותר animation: none !important; לא תעבוד. גם הפתרון הקודם לא מבטיח הצלחה בכל האתרים (לדוגמה, הוא לא יכול לעצור תנועה שהופעלה באמצעות Web Animations API), לכן חשוב להשבית אותו כשמבחינים בבעיה.
משאבים
- הטיוטה האחרונה של העורך של המפרט Media Queries Level 5.
prefers-reduced-motionבסטטוס הפלטפורמה של Chrome.-
prefers-reduced-motionChromium bug. - Blink Intent to Implement posting.
תודות
תודה רבה ל-Stephen McGruer על הטמעת prefers-reduced-motion ב-Chrome, ועל בדיקת המסמך הזה יחד עם Rob Dodson.