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

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

מבוא

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

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

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

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

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

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

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

שימוש בסמארטפון בזמן שכיבה במיטה
הסמארטפון שנעשה בו שימוש במיטה (מקור: Un אימיילים)

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

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

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

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

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

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

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

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

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

חיסכון בצריכת החשמל במצב כהה במסכים מסוג AMOLED

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

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

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

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

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

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

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

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

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

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

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

מצב כהה מדווח באמצעות שאילתה של מדיה, כך שתוכלו לבדוק בקלות אם הדפדפן הנוכחי תומך במצב כהה על ידי בדיקה אם שאילתה ה-media‏ 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 { … }. כפי שהן מוגדרות ב-:root CSS pseudo-class— בורר שב-HTML מייצג את הרכיב <html> וזה זהה לסלקטור html, אלא שספציפיות שלו משמשת לערכי רשת גבוהים, שהיא מפענחת

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

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

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

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

כל השאר הוא רק עניין של הגדרת משתני 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'}.`);
});

החל מ-Chromium 93 ומ-Safari 15, אפשר לשנות את הצבע בהתאם לשאילתת מדיה באמצעות המאפיין 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 בתוך או <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) של נתן אנדרסון.