העדפת ערכת צבעים: שלום חושך, חבר שלי

שיווק יתר או צורך אמיתי? כאן תוכלו לקרוא על כל מה שקשור למצב כהה ועל הדרכים לתמוך בו כדי לשפר את חוויית השימוש של המשתמשים.

מבוא

מצב כהה לפני מצב כהה

צג מחשב עם מסך ירוק
מסך ירוק (מקור)

סגרנו מעגל עם מצב כהה. בראשית המחשוב האישי, מצב כהה לא היה עניין של בחירה, אלא עניין של עובדה: צגים מונוכרומטיים מסוג CRT פועלים על ידי הפעלת קרני אלקטרונים במסך פוספורסנטי, והפוספור שהיה בשימוש בצגים מוקדמים מסוג CRT היה ירוק. מאחר שהטקסט הוצג בירוק ושאר המסך היה שחור, למודלים האלה קראו לעיתים קרובות מסכים ירוקים.

עיבוד תמלילים בצבע כהה על רקע לבן
כהה על לבן (מקור)

צגי CRT צבעוניים שהוצגו לאחר מכן הראו כמה צבעים באמצעות שימוש בפוספורים אדומים, ירוקים וכחולים. הם יצרו את הצבע הלבן על ידי הפעלה של כל שלושת הפוספורים בו-זמנית. עם הופעת תוכנות עריכה מתוחכמות יותר מסוג WYSIWYG, הרעיון של יצירת מסמך וירטואלי שדומה לגיליון נייר פיזי הפך לפופולרי.

דף אינטרנט בצבע כהה על רקע לבן בדפדפן WorldWideWeb
דפדפן WorldWideWeb (מקור)

כאן החלה המגמה של כהה על לבן כעיצוב, והמגמה הזו הועברה לאינטרנט המוקדם שמבוסס על מסמכים. הדפדפן הראשון בהיסטוריה, WorldWideWeb (חשוב לזכור שCSS עדיין לא הומצא), הציג דפי אינטרנט בדרך הזו. עובדה משעשעת: הדפדפן השני בהיסטוריה, Line Mode Browser – דפדפן מבוסס-מסוף – היה ירוק על רקע כהה. כיום, דפי אינטרנט ואפליקציות אינטרנט מעוצבים בדרך כלל עם טקסט כהה על רקע בהיר. זוהי הנחת יסוד שמוטמעת גם בקוד של גיליונות סגנונות של סוכנות משתמשים, כולל של Chrome.

שימוש בסמארטפון בזמן שכיבה במיטה
שימוש בסמארטפון במיטה (מקור: Unsplash)

ימי המסכים הקטנים של CRT חלפו מזמן. צריכת התוכן והיצירה שלו עברו למכשירים ניידים עם מסכי LCD עם תאורה אחורית או מסכי AMOLED לחיסכון באנרגיה. מחשבים, טאבלטים וסמארטפונים קטנים יותר שניתן להעביר בקלות הובילו לדפוסי שימוש חדשים. משימות פנאי כמו גלישה באינטרנט, תכנות למטרות בידור ומשחקים מתקדמים מתבצעות לעיתים קרובות אחרי שעות העבודה בסביבה עמומה. אנשים נהנים מהמכשירים שלהם גם במיטה בלילה. ככל שאנשים משתמשים במכשירים שלהם בחושך, כך הרעיון לחזור לשורשים של רקע כהה עם טקסט בהיר נעשה פופולרי יותר.

למה כדאי להשתמש במצב כהה

מצב כהה מסיבות אסתטיות

כששואלים אנשים למה הם אוהבים את מצב האפל או רוצים להשתמש בו, התשובה הנפוצה ביותר היא "קל יותר על העיניים", ואחריה "הוא אלגנטי ויפה". במסמכי העזרה למפתחים בנושא מצב כהה של Apple כתוב במפורש: "הבחירה אם להפעיל מראה בהיר או כהה היא אסתטית עבור רוב המשתמשים, ויכול להיות שהיא לא קשורה לתנאי התאורה בסביבה".

תצוגת CloseView ב-Mac OS System 7 עם
System 7 CloseView (מקור)

מצב כהה ככלי נגישות

יש גם אנשים שזקוקים למצב כהה ומשתמשים בו ככלי נגישות נוסף, למשל משתמשים עם ראייה לקויה. הכלי הראשון שמצאתי עם תכונות נגישות כאלה הוא התכונה CloseView ב-System 7, שכללה מתג להצגת שחור על לבן ולבן על שחור. מערכת System 7 תמכה בצבע, אבל ממשק המשתמש שמוגדר כברירת מחדל עדיין היה בשחור-לבן.

כשהוצג הצבע, נחשפו נקודות החולשה של הטכניקות האלה שמבוססות על היפוך. במחקר של Szpiro et al. על האופן שבו אנשים עם ראייה ירודה ניגשים למכשירי מחשוב, נמצא שכל המשתמשים ששוחחו איתם לא אהבו תמונות הפוכות, אבל רבים מהם העדיפו טקסט בהיר על רקע כהה. כדי להתאים את המכשיר להעדפות של המשתמשים, Apple מציעה את התכונה היפוך צבעים חכם, שמהפכת את הצבעים בתצוגה, מלבד תמונות, מדיה ואפליקציות מסוימות שמשתמשות בסגנונות צבעים כהים.

צורה מיוחדת של ראייה ירודה היא תסמונת ראייה במחשב, שנקראת גם עייפות עיניים דיגיטלית. היא מוגדרת כ'שילוב של בעיות עיניים וראייה שקשורות לשימוש במחשבים (כולל מחשבים נייחים, מחשבים ניידים וטאבלטים) ובמסכים אלקטרוניים אחרים (למשל, סמארטפונים ומכשירי קריאה אלקטרוניים)'. הועלתה השערה ששימוש במכשירים אלקטרוניים על ידי בני נוער, במיוחד בלילה, מוביל לסיכון מוגבר לקיצור משך השינה, להארכת זמן האחזור עד תחילת השינה ולחוסר שינה מוגבר. בנוסף, דווח בהרחבה על כך שחשיפה לאור כחול מעורבבת בוויסות השעון הביולוגי ומחזור השינה, וסביבות תאורה לא סדירות עלולות להוביל לבעיות בשינה, שעשויות להשפיע על מצב הרוח ועל הביצועים במשימות, על פי מחקר של רוזנפלד. כדי להגביל את ההשפעות השליליות האלה, אפשר לצמצם את כמות האור הכחול על ידי שינוי טמפרטורת הצבע של המסך באמצעות תכונות כמו Night Shift ב-iOS או Night Light ב-Android, וגם להימנע מחשיפה לאור בהיר או לאור לא סדיר באופן כללי באמצעות עיצובים כהים או מצבים כהים.

חיסכון באנרגיה במצב כהה במסכים מסוג AMOLED

לסיום, ידוע שמצב כהה חוסך הרבה אנרגיה במסכים מסוג AMOLED. מחקרים מעשיים בנושא Android שהתמקדו באפליקציות פופולריות של Google, כמו YouTube, הראו שאפשר לחסוך עד 60% בצריכת החשמל. בסרטון הבא מפורט מידע נוסף על מקרי המחקר האלה ועל חיסכון האנרגיה בכל אפליקציה.

הפעלת מצב כהה במערכת ההפעלה

אחרי שסיפרתי על הרקע של המצב החשוך והסיבות לכך שהוא כל כך חשוב להרבה משתמשים, נסביר איך אפשר לתמוך בו.

הגדרות המצב הכהה ב-Android Q
הגדרות העיצוב הכהה ב-Android Q

בדרך כלל, במערכות הפעלה שתומכות במצב כהה או בעיצוב כהה יש אפשרות להפעיל אותם במקום כלשהו בהגדרות. ב-macOS X, האפשרות הזו נמצאת בקטע כללי בהעדפות המערכת, והיא נקראת מראה (צילום מסך). ב-Windows 10, האפשרות הזו נמצאת בקטע צבעים, והיא נקראת בחירת צבע (צילום מסך). ב-Android Q, אפשר למצוא אותה בקטע תצוגה כמתג החלפת מצב של עיצוב כהה (צילום מסך). ב-iOS 13, אפשר לשנות את המראה בקטע תצוגה ובהירות בהגדרות (צילום מסך).

שאילתת המדיה prefers-color-scheme

עוד קצת תיאוריה לפני שאמשיך. שאילתות מדיה מאפשרות לכותבים לבדוק ערכים או תכונות של סוכן המשתמש או של מכשיר התצוגה, ולשלוח עליהן שאילתות, ללא קשר למסמך שעבר עיבוד. הן משמשות בכלל @media של CSS כדי להחיל סגנונות על מסמך באופן מותנה, ובהקשרים ובשפות שונים אחרים, כמו HTML ו-JavaScript. Media Queries ברמה 5 כולל את התכונות שנקראות 'תכונות מדיה לפי העדפות המשתמש', כלומר דרך שבה אתרים יכולים לזהות את הדרך המועדפת על המשתמש להצגת תוכן.

התכונה prefers-color-scheme של המדיה משמשת לזיהוי אם המשתמש ביקש שהדף ישתמש בעיצוב בהיר או כהה. הוא פועל עם הערכים הבאים:

  • light: הערה שמציינת שהמשתמש הודיע למערכת שהוא מעדיף דף עם עיצוב בהיר (טקסט כהה על רקע בהיר).
  • dark: מציין שהמשתמש הודיע למערכת שהוא מעדיף דף עם עיצוב כהה (טקסט בהיר על רקע כהה).

תמיכה במצב כהה

איך בודקים אם הדפדפן תומך במצב כהה

מצב כהה מדווח באמצעות שאילתה של מדיה, כך שתוכלו לבדוק בקלות אם הדפדפן הנוכחי תומך במצב כהה על ידי בדיקה אם שאילתה של המדיה prefers-color-scheme תואמת בכלל. שימו לב שלא כללתי ערך כלשהו, אלא בדקתי רק אם שאילתת המדיה תואמת לבד.

if (window.matchMedia('(prefers-color-scheme)').media !== 'not all') {
  console.log('🎉 Dark mode is supported');
}

נכון למועד כתיבת המאמר, יש תמיכה ב-prefers-color-scheme גם במחשבים וגם בניידים (במקרים שבהם התכונה זמינה) בדפדפני Chrome ו-Edge מגרסה 76 ואילך, בדפדפן Firefox מגרסה 67 ואילך ובדפדפן Safari מגרסה 12.1 ב-macOS ומגרסה 13 ב-iOS. בכל הדפדפנים האחרים, אפשר לעיין במאמר האם אפשר להשתמש בטבלאות התמיכה.

איך לקבל מידע על העדפות המשתמש בזמן הבקשה

הכותרת של ההנחיה ללקוח Sec-CH-Prefers-Color-Scheme מאפשרת לאתרים לקבל את העדפות ערכת הצבעים של המשתמש, אם רוצים, בזמן הבקשה, וכך לאפשר לשרתים להטמיע את ה-CSS הנכון בקוד, וכך למנוע הבהוב של ערכת צבעים שגויה.

מצב כהה בפועל

עכשיו נראה איך נראה תמיכה במצב כהה בפועל. בדיוק כמו בHighlander, במצב כהה יכול להיות רק אחד: כהה או בהיר, אבל אף פעם לא גם וגם! למה הזכרתי את זה? כי לעובדה הזו אמורה להיות השפעה על אסטרטגיית הטעינה. אין לאלץ משתמשים להוריד קובצי CSS במסלול הרנדר הקריטי שמיועד למצב שבו הם לא משתמשים כרגע. לכן, כדי לבצע אופטימיזציה של מהירות הטעינה, חילקתי את קובץ ה-CSS של אפליקציית הדוגמה שמציגה את ההמלצות הבאות בפועל לשלושה חלקים, כדי לדחות קוד CSS לא קריטי:

  • style.css שמכיל כללים כלליים שמשמשים באופן אוניברסלי באתר.
  • dark.css שמכיל רק את הכללים הנדרשים למצב כהה.
  • light.css שמכיל רק את הכללים הנדרשים למצב בהיר.

אסטרטגיית טעינה

שני הנכסים האחרונים, light.css ו-dark.css, נטענים באופן מותנה באמצעות שאילתה <link media>. בשלב הראשון, לא כל הדפדפנים יתמכו ב-prefers-color-scheme (ניתן לזהות זאת באמצעות הדפוס שלמעלה). כדי לטפל בבעיה הזו באופן דינמי, אפשר לטעון את קובץ ברירת המחדל light.css באמצעות רכיב <link rel="stylesheet"> שמוחדר באופן מותנה בסקריפט זעיר בתוך שורת קוד (האפשרות 'בהיר' היא בחירה שרירותית, אפשר גם להגדיר את חוויית המשתמש שמוגדרת כברירת מחדל כחוויה כהה). כדי למנוע הצגה קצרה של תוכן ללא עיצוב, מסתירים את תוכן הדף עד ש-light.css נטען.

<script>
  // If `prefers-color-scheme` is not supported, fall back to light mode.
  // In this case, light.css will be downloaded with `highest` priority.
  if (window.matchMedia('(prefers-color-scheme: dark)').media === 'not all') {
    document.documentElement.style.display = 'none';
    document.head.insertAdjacentHTML(
      'beforeend',
      '<link rel="stylesheet" href="/light.css" onload="document.documentElement.style.display = \'\'">',
    );
  }
</script>
<!--
  Conditionally either load the light or the dark stylesheet. The matching file
  will be downloaded with `highest`, the non-matching file with `lowest`
  priority. If the browser doesn't support `prefers-color-scheme`, the media
  query is unknown and the files are downloaded with `lowest` priority (but
  above I already force `highest` priority for my default light experience).
-->
<link rel="stylesheet" href="/dark.css" media="(prefers-color-scheme: dark)" />
<link
  rel="stylesheet"
  href="/light.css"
  media="(prefers-color-scheme: light)"
/>
<!-- The main stylesheet -->
<link rel="stylesheet" href="/style.css" />

הארכיטקטורה של גיליון הסגנונות

אני משתמש בצורה מקסימלית במשתני CSS, כך ש-style.css הכללי יכול להיות כללי, וכל ההתאמה האישית של המצבים הבהירים או כהים מתבצעת בשני הקבצים האחרים, dark.css ו-light.css. בהמשך מופיע קטע מתוך הסגנונות בפועל, אבל הוא אמור להספיק כדי להעביר את הרעיון הכללי. אני מגדיר שני משתנים, -⁠-⁠color ו--⁠-⁠background-color, שבעצם יוצרים עיצוב בסיס של כהה על בהיר ובהיר על כהה.

/* light.css: 👉 dark-on-light */
:root {
  --color: rgb(5, 5, 5);
  --background-color: rgb(250, 250, 250);
}
/* dark.css: 👉 light-on-dark */
:root {
  --color: rgb(250, 250, 250);
  --background-color: rgb(5, 5, 5);
}

לאחר מכן, ב-style.css, משתמשים במשתנים האלה בכלל body { … }. מאחר שהם מוגדרים בפסאודו-סיווג CSS‏ :root – סלקטור שמייצג ב-HTML את האלמנט <html> וזהה לסלקטור html, מלבד רמת הספציפיות הגבוהה יותר שלו – הם מועברים במורד, וזה עוזר לי להצהיר על משתני CSS גלובליים.

/* style.css */
:root {
  color-scheme: light dark;
}

body {
  color: var(--color);
  background-color: var(--background-color);
}

בדוגמת הקוד שלמעלה, כנראה שמתם לב לנכס color-scheme עם הערך light dark שמופרד באמצעות רווחים.

כך הדפדפן יידע אילו נושאי צבעים האפליקציה תומכת בהם, ויוכל להפעיל וריאנטים מיוחדים של גיליון סגנונות של סוכן המשתמש. למשל, כך אפשר לאפשר לדפדפן ליצור תצוגה של שדות טופס עם רקע כהה וטקסט בהיר, לשנות את סרגל הגלילה או להפעיל צבע הדגשה שמותאם לעיצוב. הפרטים המדויקים של color-scheme מפורטים במודול של התאמת צבע ברמה 1 ב-CSS.

כל השאר הוא רק עניין של הגדרת משתני CSS לדברים שחשובים באתר שלי. ארגון סגנונות באופן סמנטי עוזר מאוד כשעובדים במצב כהה. לדוגמה, במקום -⁠-⁠highlight-yellow, כדאי לקרוא למשתנה -⁠-⁠accent-color, כי יכול להיות שהצבע 'צהוב' לא יהיה צהוב במצב כהה, ולהפך. בהמשך מופיעה דוגמה למשתנים נוספים שבהם השתמשתי בדוגמה שלי.

/* dark.css */
:root {
  --color: rgb(250, 250, 250);
  --background-color: rgb(5, 5, 5);
  --link-color: rgb(0, 188, 212);
  --main-headline-color: rgb(233, 30, 99);
  --accent-background-color: rgb(0, 188, 212);
  --accent-color: rgb(5, 5, 5);
}
/* light.css */
:root {
  --color: rgb(5, 5, 5);
  --background-color: rgb(250, 250, 250);
  --link-color: rgb(0, 0, 238);
  --main-headline-color: rgb(0, 0, 192);
  --accent-background-color: rgb(0, 0, 238);
  --accent-color: rgb(250, 250, 250);
}

דוגמה מלאה

בהטמעה הבאה של Glitch תוכלו לראות את הדוגמה המלאה שבה המושגים שלמעלה מוטמעים בפועל. נסו להפעיל או להשבית את המצב הכהה בהגדרות של מערכת ההפעלה ולראות איך הדף מגיב.

ההשפעה של הטעינה

כשתנסו את הדוגמה הזו, תוכלו לראות למה אני טוען את dark.css ו-light.css באמצעות שאילתות מדיה. אפשר לנסות להחליף את מצב התצוגה למצב כהה ולטעון מחדש את הדף: סגנונות הגיליון הספציפיים שלא תואמים כרגע עדיין נטענים, אבל עם רמת העדיפות הנמוכה ביותר, כדי שהם אף פעם לא יתחרו במשאבים הנדרשים לאתר כרגע.

תרשים של טעינת רשת שמראה איך במצב בהיר, קובץ ה-CSS של מצב כהה נטען בעדיפות הנמוכה ביותר
באתר במצב בהיר, קובץ ה-CSS של מצב כהה נטען בעדיפות הנמוכה ביותר.
תרשים של טעינת הרשת שמראה איך במצב כהה, קובצי ה-CSS של מצב בהיר נטענים בעדיפות הנמוכה ביותר
באתר במצב כהה, קובץ ה-CSS של המצב הבהיר נטען בעדיפות הנמוכה ביותר.
תרשים של טעינת רשת שמראה איך במצב בהיר שמוגדרת כברירת מחדל, קובץ ה-CSS של מצב כהה נטען בעדיפות הנמוכה ביותר
אתר במצב בהיר כברירת מחדל בדפדפן שלא תומך ב-prefers-color-scheme טוען את קובץ ה-CSS של מצב כהה בעדיפות הנמוכה ביותר.

תגובה לשינויים במצב כהה

כמו כל שינוי אחר של שאילתה לגבי מדיה, אפשר להירשם לשינויים במצב כהה באמצעות JavaScript. אפשר להשתמש באפשרות הזו, למשל, כדי לשנות באופן דינמי את סמל הדף של דף מסוים או לשנות את הערך של <meta name="theme-color"> שקובע את הצבע של סרגל כתובות ה-URL ב-Chrome. בדוגמה המלאה שלמעלה אפשר לראות את זה בפעולה. כדי לראות את השינויים בצבע העיצוב ובסמל האתר, פותחים את הדמו בכרטיסייה נפרדת.

const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
darkModeMediaQuery.addEventListener('change', (e) => {
  const darkModeOn = e.matches;
  console.log(`Dark mode is ${darkModeOn ? '🌒 on' : '☀️ off'}.`);
});

החל מגרסה 93 של Chromium וגרסה 15 של Safari, אפשר לשנות את הצבע על סמך שאילתה של מדיה באמצעות המאפיין media של אלמנט הצבע של העיצוב meta. המערכת תבחור את האפשרות הראשונה שתתאים. לדוגמה, אפשר להגדיר צבע אחד למצב בהיר וצבע אחר למצב כהה. נכון למועד כתיבת המאמר, אי אפשר להגדיר אותם במניפסט. בעיה בנושא ב-GitHub: w3c/manifest#975

<meta
  name="theme-color"
  media="(prefers-color-scheme: light)"
  content="white"
/>
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="black" />

ניפוי באגים ובדיקה של מצב כהה

הדמיה של prefers-color-scheme ב-DevTools

שינוי ערכת הצבעים של כל מערכת ההפעלה יכול להפוך למטריד מאוד מהר, ולכן עכשיו אפשר להשתמש בכלי הפיתוח של Chrome כדי לחקות את ערכת הצבעים המועדפת על המשתמש, כך שתשפיע רק על הכרטיסייה שמוצגת כרגע. פותחים את תפריט הפקודות, מתחילים להקליד Rendering, מריצים את הפקודה Show Rendering ומשנים את האפשרות יצירת אמולציה של מדיה של CSS עם העדפה לערכת צבעים.

צילום מסך של האפשרות &#39;יצירת אמולציה של מדיה של CSS עם העדפה לערכת צבעים&#39; שנמצאת בכרטיסייה &#39;עיבוד&#39; בכלי הפיתוח ל-Chrome

צילום מסך של prefers-color-scheme באמצעות Puppeteer

Puppeteer היא ספריית Node.js שמספקת ממשק API ברמה גבוהה לצורך שליטה ב-Chrome או ב-Chromium באמצעות פרוטוקול DevTools. ב-dark-mode-screenshot אנחנו מספקים סקריפט של Puppeteer שמאפשר ליצור צילומי מסך של הדפים גם במצב כהה וגם במצב בהיר. אפשר להריץ את הסקריפט הזה באופן חד-פעמי, או להפוך אותו לחלק מחבילת הבדיקות של השילוב המתמשך (CI).

npx dark-mode-screenshot --url https://googlechromelabs.github.io/dark-mode-toggle/demo/ --output screenshot --fullPage --pause 750

שיטות מומלצות לשימוש במצב כהה

הימנעות מלבן טהור

אולי שמתם לב לפריט קטן: אני לא משתמש בלבן טהור. במקום זאת, כדי למנוע הילה ודליפת צבע על התוכן הכהה שמסביב, בוחרים לבן כהה יותר במעט. אפשר להשתמש ב-rgb(250, 250, 250).

שינוי הצבעים והכהיית תמונות סטילס

אם משווים בין שתי צילומי המסך שבהמשך, רואים שהעיצוב הבסיסי השתנה מכהה על בהיר לבהיר על כהה, אבל גם שתמונת ה-Hero נראית שונה במקצת. מחקר המשתמשים שלי הראה שרוב האנשים שנסקרו מעדיפים תמונות קצת פחות עזות ובהירות כשמצב האפל מופעל. אני מכנה את התהליך הזה צביעה מחדש.

התמונה הראשית (Hero) כהתה מעט במצב כהה.
התמונה הראשית (Hero) כהה מעט יותר במצב כהה.
תמונה ראשית רגילה במצב בהיר.
תמונה ראשית (Hero) רגילה במצב בהיר.

אפשר להוסיף צבע מחדש באמצעות פילטר CSS בתמונות שלי. אני משתמש בסלקטור CSS שמתאים לכל התמונות שלא מכילות את הערך .svg בכתובת ה-URL שלהן. הרעיון הוא שאוכל להעניק לגרפיקת וקטורים (סמלים) טיפול שונה של צביעה מחדש מאשר לתמונות שלי (תמונות). מידע נוסף על כך זמין בפסקה הבאה. שימו לב שוב לשימוש במשתנה CSS, כדי שאוכל לשנות את המסנן בצורה גמישה בהמשך.

מכיוון שצביעה מחדש נדרשת רק במצב כהה, כלומר כשהאפשרות dark.css פעילה, אין כללים תואמים ב-light.css.

/* dark.css */
--image-filter: grayscale(50%);

img:not([src*='.svg']) {
  filter: var(--image-filter);
}

התאמה אישית של עוצמות הצביעה מחדש במצב כהה באמצעות JavaScript

כל אחד הוא שונה, ולכל אחד יש צרכים שונים לגבי מצב כהה. אם נעמוד בשיטה של הוספת צבע מחדש שמתוארת למעלה, נוכל בקלות להפוך את עוצמת האפור להעדפת משתמש שאפשר לשנות באמצעות JavaScript. בנוסף, אם נגדיר את הערך 0%, נוכל להשבית את הוספת הצבע מחדש לגמרי. שימו לב ש-document.documentElement מספק הפניה לרכיב הבסיס של המסמך, כלומר לאותו רכיב שאוכל להפנות אליו באמצעות פסאודו-הקלאס של CSS‏ :root.

const filter = 'grayscale(70%)';
document.documentElement.style.setProperty('--image-filter', value);

היפוך של סמלים וגרפיקה וקטורית

לגבי גרפיקה וקטורית – שבמקרה שלי משמשת כסמלים שאני מפנה אליהם באמצעות רכיבי <img> – אני משתמש בשיטה אחרת של שינוי צבעים. מחקרים הראו שאנשים לא אוהבים תמונות עם היפוך, אבל היפוך עובד מצוין ברוב הסמלים. שוב, משתמשים במשתני CSS כדי לקבוע את כמות ההיפוך במצב הרגיל ובמצב :hover.

הסמלים הופכים במצב כהה.
הסמלים הופכים במצב כהה.
סמלים רגילים במצב בהיר.
סמלים רגילים במצב בהיר.

שימו לב שוב: הפכתי את הסמלים רק ב-dark.css אבל לא ב-light.css, וגם :hover מקבל עוצמת היפוך שונה בשני המקרים כדי שהסמל יופיע כהה יותר או בהיר יותר, בהתאם למצב שבחר המשתמש.

/* dark.css */
--icon-filter: invert(100%);
--icon-filter_hover: invert(40%);

img[src*='.svg'] {
  filter: var(--icon-filter);
}
/* light.css */
--icon-filter_hover: invert(60%);
/* style.css */
img[src*='.svg']:hover {
  filter: var(--icon-filter_hover);
}

שימוש ב-currentColor לקובצי SVG מוטמעים

בתמונות SVG מוטמעות, במקום להשתמש במסנני היפוך, אפשר להשתמש במילות המפתח של CSS‏ currentColor שמייצגות את הערך של המאפיין color של רכיב. כך תוכלו להשתמש בערך color בנכסים שלא מקבלים אותו כברירת מחדל. באופן נוח, אם משתמשים ב-currentColor כערך של מאפייני ה-SVG fill או stroke, הוא יקבל את הערך שלו מהערך שעובר בירושה ממאפיין הצבע. יתרון נוסף: האפשרות הזו פועלת גם עבור <svg><use href="…"></svg>, כך שתוכלו להשתמש במקורות מידע נפרדים ועדיין להחיל את currentColor בהקשר. חשוב לזכור שהאפשרות הזו פועלת רק לגבי קובצי SVG inline או <use href="…">, אבל לא לגבי קובצי SVG שמפנים אליהם כאל src של תמונה או באופן כלשהו דרך CSS. אפשר לראות את השימוש בכך בהדגמה שבהמשך.

<!-- Some inline SVG -->
<svg xmlns="http://www.w3.org/2000/svg"
    stroke="currentColor"
>
  […]
</svg>

מעברים חלקים בין מצבים

אפשר להעביר את המשתמש ממצב כהה למצב בהיר או להפך בצורה חלקה, כי גם color וגם background-color הם מאפייני CSS שניתן להפעיל בהם אנימציה. כדי ליצור את האנימציה, פשוט מגדירים שני רכיבי transition לשני הנכסים. הדוגמה הבאה ממחישה את הרעיון הכללי, ואפשר להתנסות בו בדמו.

body {
  --duration: 0.5s;
  --timing: ease;

  color: var(--color);
  background-color: var(--background-color);

  transition: color var(--duration) var(--timing), background-color var(
        --duration
      ) var(--timing);
}

ניהול אמנותי עם מצב כהה

מטעמי ביצועי טעינה באופן כללי, מומלץ לעבוד רק עם prefers-color-scheme בתכונה media של רכיבי <link> (במקום בתוך שורות של סגנונות), אבל יש מצבים שבהם כדאי לעבוד עם prefers-color-scheme ישירות בתוך שורות של קוד HTML. ניהול קריאייטיב הוא מצב כזה. באינטרנט, ניהול אמנותי מתייחס למראה החזותי הכולל של דף, לאופן שבו הוא מתקשר באופן חזותי, ליצירת מצב רוח, ליצירת ניגוד בין תכונות וליצירת משיכה פסיכולוגית בקרב קהל היעד.

במצב כהה, ההחלטה לגבי התמונה הטובה ביותר במצב מסוים ועל הצבעה מחדש של תמונות לא מספיק טובה היא בידי המעצב. אם משתמשים ברכיב <picture>, אפשר להגדיר שהערך של <source> של התמונה שמוצגת יהיה תלוי במאפיין media. בדוגמה הבאה, אני מציג את חצי הכדור המערבי במצב כהה ואת חצי הכדור המזרחי במצב בהיר. אם לא צוינה העדפה, המערכת תשתמש בחצי הכדור המזרחי כברירת מחדל בכל שאר המקרים. כמובן, זהו דוגמה בלבד. כדי לראות את ההבדל, אפשר להפעיל או להשבית את המצב הכהה במכשיר.

<picture>
  <source srcset="western.webp" media="(prefers-color-scheme: dark)" />
  <source srcset="eastern.webp" media="(prefers-color-scheme: light)" />
  <img src="eastern.webp" />
</picture>

מצב כהה, אבל עם אפשרות לביטול ההסכמה

כפי שצוין בקטע למה כדאי להשתמש במצב כהה למעלה, המצב הכהה הוא בחירה אסתטית של רוב המשתמשים. כתוצאה מכך, יכול להיות שחלק מהמשתמשים יעדיפו ממשק משתמש כהה במערכת ההפעלה, אבל עדיין יעדיפו לראות את דפי האינטרנט שלהם כפי שהם רגילים לראות אותם. מומלץ לפעול לפי האות שהדפדפן שולח דרך prefers-color-scheme בהתחלה, אבל לאחר מכן לאפשר למשתמשים לשנות את ההגדרה ברמת המערכת.

הרכיב המותאם אישית <dark-mode-toggle>

כמובן שאפשר ליצור את הקוד בעצמכם, אבל אפשר גם להשתמש ברכיב מותאם אישית (רכיב אינטרנט) מוכן שיצרתים במיוחד למטרה הזו. הקוד נקרא <dark-mode-toggle>, והוא מוסיף לדף מתג (מצב כהה: מופעל/מושבת) או מתג להחלפת עיצוב (עיצוב: בהיר/כהה) שאפשר להתאים אישית לחלוטין. הדגמה שבהמשך מראה את הרכיב בפעולה (ו🤫 הוספת אותו בשקט לכל הדוגמאות האחרות שלמעלה).

<dark-mode-toggle
  legend="Theme Switcher"
  appearance="switch"
  dark="Dark"
  light="Light"
  remember="Remember this"
></dark-mode-toggle>
dark-mode-toggle במצב בהיר.
<dark-mode-toggle> במצב בהיר.
dark-mode-toggle במצב בהיר.
<dark-mode-toggle> במצב כהה.

כדאי לנסות ללחוץ או להקיש על אמצעי הבקרה של מצב האפל בפינה השמאלית העליונה בדמו שבהמשך. אם מסמנים את התיבות של אמצעי הבקרה השלישי והרביעי, אפשר לראות איך בחירת המצב נשמרת גם אחרי טעינת הדף מחדש. כך המבקרים יוכלו להשאיר את מערכת ההפעלה שלהם במצב כהה, אבל ליהנות מהאתר במצב בהיר, ולהפך.

מסקנות

עבודה עם מצב כהה ותמיכה בו היא מהנה ופותחת דרכים חדשות לעיצוב. עבור חלק מהמבקרים, זה יכול להיות ההבדל בין חוסר יכולת להשתמש באתר לבין שימוש מרוצה. יש כמה מלכודות וצריך לבצע בדיקה יסודית, אבל מצב כהה הוא בהחלט הזדמנות מצוינת להראות שאתם דואגים לכל המשתמשים שלכם. בעזרת השיטות המומלצות שמפורטות במאמר הזה וכלים כמו הרכיב המותאם אישית <dark-mode-toggle>, תוכלו ליצור חוויה מדהימה במצב כהה. אשמח לדעת ב-Twitter מה יצרתם, אם הפוסט הזה היה שימושי או אם יש לכם הצעות לשיפור שלו. תודה על שקראת מידע זה! 🌒

מקורות מידע לגבי שאילתת המדיה prefers-color-scheme:

מקורות מידע לגבי המטא תג color-scheme ומאפיין ה-CSS:

קישורים כלליים למצב כהה:

מאמרים של מחקר רקע לפוסט הזה:

תודות

תכונה של מדיה prefers-color-scheme, נכס ה-CSS color-scheme והמטא תג הקשור הם תוצאת ההטמעה של 👏 Rune Lillesveen. רוני הוא גם עורך שותף של המפרט של מודול התאמת הצבע של CSS ברמה 1. 🙏 תודה ללוצ'קס ז'בילוט, רואן מורוווד, צ'ירג דסאי ורוב דודסון על הבדיקות המקיפות של המאמר הזה. אסטרטגיית הטעינה היא פרי מוחו של Jake Archibald. Emilio Cobos Álvarez הצביע לי על שיטת הזיהוי הנכונה של prefers-color-scheme. הטיפ לגבי קובצי SVG עם הפניה ו-currentColor הגיע מ-Timothy Hatcher. לסיום, תודה רבה למשתתפים האנונימיים הרבים במחקרים השונים על התנהגות המשתמשים, שעזרו לנו לגבש את ההמלצות במאמר הזה. התמונה הראשית (Hero) היא של Nathan Anderson.