סקירה בסיסית של אופן ההגדרה של ערכת צבעים דינמית וניתנת להתאמה אישית
בפוסט הזה אני רוצה לשתף מחשבות על דרכים לנהל כמה ערכות צבעים ב-CSS. צפייה בהדגמה
אם אתם מעדיפים לצפות בסרטון, הנה גרסת YouTube של הפוסט הזה:
סקירה כללית
אנחנו ניצור מערכת צבעים נגישה עם מאפיינים מותאמים אישית ועם calc(), כדי ליצור דף אינטרנט שמותאם להעדפות המשתמשים, תוך שמירה על חוויית כתיבה מינימלית. מתחילים עם צבע בסיסי של המותג ויוצרים ממנו מערכת של וריאציות: 2 צבעי טקסט, 4 צבעי משטח וצל תואם.
במדריך הזה, אנחנו מתחילים בהגדרה של כל הצבעים לכל ערכת צבעים. הם משמשים לשינוי הדף רק בסוף התהליך.
המותג
לרוב, צבע המותג כבר נקבע ומועבר בפורמט הקסדצימלי או RGB. צבע המותג הבסיסי של האתגר הזה בממשק המשתמש הגרפי הוא #0af. קודם כל, במערכת הצבעים הזו, צריך להמיר את הערך ההקסדצימלי ל-hsl.
* {
--brand: #0af;
--brand: hsl(200 100% 50%);
}
כדי להפעיל את הרעיון של הכהיית צבע המותג או הבהרתו, למשל ב-20%, צריך לחלץ את 3 הערוצים של ערך צבע ה-HSL למאפיינים מותאמים אישית משלהם, באופן הבא:
* {
--brand-hue: 200;
--brand-saturation: 100%;
--brand-lightness: 50%;
}
אפשר לבצע פעולות מתמטיות על מאפייני הצבע האלה באמצעות CSS, למשל calc(var(--brand-lightness) -
20%) כדי להפחית את ערך הבהירות ב-20%. ההגדרה הזו היא בסיסית ליצירת ערכת צבעים, כי אפשר להשתמש ב-CSS כדי לשמור על כל הצבעים באותה משפחת גוונים על ידי התאמת רמות הרוויה והבהירות של HSL.
עיצוב בהיר
כל וריאציה של צבע תסומן בסכימה התואמת שלה. במקרה הזה, לכל אחת מהן יצורף -light.

מותג
הוא נבנה מחדש על ידי הוספת מאפייני --brand-hue, --brand-saturation
ו---brand-lightness בהתאמה אישית בתוך הסוגריים של פונקציית ה-hsl (), בלי לבצע חישובים:
* {
--brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
}
צבעי הטקסט
בשלב הבא, צריך להגדיר צבעים לטקסט בערכת הצבעים. בנושא בהיר, הטקסט צריך להיות כהה מאוד. שימו לב שרמת הבהירות של הצבעים הבאים נמוכה, הרבה מתחת ל-50%.
* {
--text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
--text2-light: hsl(var(--brand-hue) 30% 30%);
}
--text1-light, מכיוון שהצבע כהה מאוד בבהירות של 10%, הוא שומר על הרוויה הגבוהה של 100% כדי שצבע המותג עדיין יבלוט על רקע הכחול הכהה מאוד.
--text2-light, הצבע הזה לא כהה כמו הצבע הראשון, וזה טוב כי הוא צבע משני. בנוסף, הוא פחות רווי.
צבעי המשטח
צבעי המשטח הם הרקעים, הגבולות ומשטחים דקורטיביים אחרים שעליהם או בתוכם מוצג הטקסט. בנושא בהיר, אלה הצבעים הבהירים, בניגוד לצבעי הטקסט שהיו כהים. כדי ליצור צבעים בהירים באמצעות HSL, נשתמש בערכי אחוזים גבוהים יותר בערך הבהירות השלישי. נוריד גם את רמת הרוויה, כדי שהגוונים האפורים הבהירים לא ייראו מוכתמים מדי.
* {
--surface1-light: hsl(var(--brand-hue) 25% 90%);
--surface2-light: hsl(var(--brand-hue) 20% 99%);
--surface3-light: hsl(var(--brand-hue) 20% 92%);
--surface4-light: hsl(var(--brand-hue) 20% 85%);
}
נוצרו 4 צבעים למשטחים, כי בדרך כלל צריך יותר וריאציות של צבעים דקורטיביים, למשל לרגעים אינטראקטיביים כמו :focus או :hover, או כדי ליצור מראה של שכבות נייר. בתרחישים האלה, כדאי להגדיר מעבר מ---surface2-light ל---surface3-light כשמעבירים את העכבר מעל הרכיב, כך שהניגודיות תגדל (מ-99% בהירות ל-92% בהירות, כלומר הרכיב יהיה כהה יותר).
אזורים כהים
צללים בתוך סכמת צבעים הם מעבר לנדרש, אבל הם מוסיפים לאפקט מראה מציאותי ועוזרים לו להתבלט לעומת צללים לא מציאותיים שמבוססים על שחור. כדי לעשות את זה, הצבע של הצל ישתמש במאפיין המותאם אישית של הגוון, יהיה מעט רווי בגוון אבל עדיין כהה מאוד. בעצם, יוצרים צל כהה מאוד עם גוון כחול קל.
* {
--surface-shadow-light: var(--brand-hue) 10% 20%;
--shadow-strength-light: .02;
}
הערך --surface-shadow-light לא מוקף בפונקציית hsl. הסיבה לכך היא שהערך --shadow-strength ישולב כדי ליצור אטימות מסוימת, וקובץ ה-CSS צריך את החלקים כדי לבצע חישובים. למידע נוסף, אפשר לדלג אל הקטע בנושא צללים רדיאליים.
צבעים בהירים ביחד
אין צורך לחפש איך נוצרים הצבעים הבהירים, כי כולם נמצאים במקום אחד בקובץ ה-CSS.
* {
--brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
--text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
--text2-light: hsl(var(--brand-hue) 30% 30%);
--surface1-light: hsl(var(--brand-hue) 25% 90%);
--surface2-light: hsl(var(--brand-hue) 20% 99%);
--surface3-light: hsl(var(--brand-hue) 20% 92%);
--surface4-light: hsl(var(--brand-hue) 20% 85%);
--surface-shadow-light: var(--brand-hue) 10% calc(var(--brand-lightness) / 5);
--shadow-strength-light: .02;
}
עיצוב כהה
רוב המותגים לא מתחילים עם עיצוב כהה, אלא עם וריאציה של העיצוב הראשי שלהם, שבדרך כלל בהירה יותר. לעומת זאת, משתמשים בוחרים לעיתים קרובות בעיצוב כהה בהקשרים שונים, כמו בלילה. הגורמים האלה הובילו אותי למסקנה שיש שני דברים שחשוב לזכור לגבי עיצובים כהים:
- בדרך כלל, המשתמשים לא יראו טוב את המסך כשהם משתמשים בעיצוב הזה, לכן חשוב לבדוק את העיצוב הכהה.
- הצבעים צריכים להיות פחות רוויים כדי שלא ייראו רוטטים במסך בגלל שהם אינטנסיביים מדי.

מותג
בנושא הבהיר נעשה שימוש ב-3 ערכי הערוצים של צבעי המותג ב-HSL ללא שינוי, אבל בנושא הכהה לא. הרוויה נחתכת בחצי והבהירות מופחתת ב-50% יחסית.
* {
--brand-dark: hsl(
var(--brand-hue)
calc(var(--brand-saturation) / 2)
calc(var(--brand-lightness) / 1.5)
);
}
צבעי הטקסט
בנושא כהה, צבעי הטקסט צריכים להיות בהירים. הצבעים הבאים הם בעלי ערכים גבוהים של בהירות, ולכן הם קרובים יותר ללבן.
* {
--text1-dark: hsl(var(--brand-hue) 15% 85%);
--text2-dark: hsl(var(--brand-hue) 5% 65%);
}
צבעי המשטח
בנושא כהה, צבעי המשטח צריכים להיות כהים. הצבעים הבאים הם בעלי בהירות ורוויה נמוכות, והמשטח הראשון הוא הכהה ביותר ב-10%.
* {
--surface1-dark: hsl(var(--brand-hue) 10% 10%);
--surface2-dark: hsl(var(--brand-hue) 10% 15%);
--surface3-dark: hsl(var(--brand-hue) 5% 20%);
--surface4-dark: hsl(var(--brand-hue) 5% 25%);
}
אזורים כהים
בעיצוב כהה, יכול להיות שיהיה קשה מאוד לראות את הצללים. זה הגיוני כי קשה להכהות משהו שכבר די כהה. כאן --shadow-strength-dark שימושי מאוד, כי הוא מאפשר לנו להכהות את הצללים על ידי שינוי של משתנה אחד.
* {
--surface-shadow-dark: var(--brand-hue) 50% 3%;
--shadow-strength-dark: .8;
}
כדאי גם לבדוק את רמת הרוויה בצל. האם אתה רואה את הצבע כשאתה מסתכל על הממשק? כדאי לנסות להסיר את הרוויה מכלי הפיתוח. מה יותר מוצא חן בעיניך?
צבעים כהים ביחד
* {
--brand-dark: hsl(var(--brand-hue) calc(var(--brand-saturation) / 2) calc(var(--brand-lightness) / 1.5));
--text1-dark: hsl(var(--brand-hue) 15% 85%);
--text2-dark: hsl(var(--brand-hue) 5% 65%);
--surface1-dark: hsl(var(--brand-hue) 10% 10%);
--surface2-dark: hsl(var(--brand-hue) 10% 15%);
--surface3-dark: hsl(var(--brand-hue) 5% 20%);
--surface4-dark: hsl(var(--brand-hue) 5% 25%);
--surface-shadow-dark: var(--brand-hue) 50% 3%;
--shadow-strength-dark: .8;
}
עיצוב מעומעם
ערכת הצבעים הזו מתמקדת בשילוב של בהירות ורוויה. צריך להיות מספיק רוויה כדי שגוון הצבע יהיה גלוי, אבל גם כדי לעבור את הניקוד של הניגודיות, כי המטרה היא שהצבע יהיה עמום ועם ניגודיות נמוכה.

מותג
* {
--brand-dim: hsl(
var(--brand-hue)
calc(var(--brand-saturation) / 1.25)
calc(var(--brand-lightness) / 1.25)
);
}
צבעי הטקסט
* {
--text1-dim: hsl(var(--brand-hue) 15% 75%);
--text2-dim: hsl(var(--brand-hue) 10% 61%);
}
צבעי המשטח
* {
--surface1-dim: hsl(var(--brand-hue) 10% 20%);
--surface2-dim: hsl(var(--brand-hue) 10% 25%);
--surface3-dim: hsl(var(--brand-hue) 5% 30%);
--surface4-dim: hsl(var(--brand-hue) 5% 35%);
}
אזורים כהים
* {
--surface-shadow-dim: var(--brand-hue) 30% 13%;
--shadow-strength-dim: .2;
}
החלשת כל הצבעים
* {
--brand-dim: hsl(var(--brand-hue) calc(var(--brand-saturation) / 1.25) calc(var(--brand-lightness) / 1.25));
--text1-dim: hsl(var(--brand-hue) 15% 75%);
--text2-dim: hsl(var(--brand-hue) 10% 61%);
--surface1-dim: hsl(var(--brand-hue) 10% 20%);
--surface2-dim: hsl(var(--brand-hue) 10% 25%);
--surface3-dim: hsl(var(--brand-hue) 5% 30%);
--surface4-dim: hsl(var(--brand-hue) 5% 35%);
--surface-shadow-dim: var(--brand-hue) 30% 13%;
--shadow-strength-dim: .2;
}
צבעים נגישים
שימו לב שהבהירות הנמוכה ביותר בסט של צבעי טקסט כהים היא 65%, והבהירות הגבוהה ביותר במשטחים כהים היא 25%. זה אומר שיש ביניהם מרווח של 40% בהירות. בעיצוב הבהיר, יש 55% מרווח נשימה. שמירה על הבדלים של כ-40-50% בבהירות בין הטקסט לצבעי הרקע יכולה לעזור לשמור על יחסי ניגודיות גבוהים, וגם לשמש ככלי עדין להתאמה במקרה שהציונים נמוכים.
אני קורא לזה 'התנגשות עד שעוברים', שזה האינטראקציה של התנגשות עם ערך הבהירות עד שכלי מראה שעברתי.
כל אחת מהערכות הנושא שנוצרו באתגר הזה עברה את מבחן ניגודיות הצבעים. ערכת הצבעים העמומה היא בעלת הניגודיות הנמוכה ביותר מבין האפשרויות, אבל היא עדיין עומדת בדרישות המינימום. כדי לעזור לחברי הצוות להשתמש בצבעים מנוגדים טובים, מומלץ ליצור שם מחלקה שמקשר בין צבע משטח לבין צבע טקסט נגיש.
.surface1 {
background-color: var(--surface1);
color: var(--text2);
}
.surface2 {
background-color: var(--surface2);
color: var(--text2);
}
.surface3 {
background-color: var(--surface3);
color: var(--text1);
}
.surface4 {
background-color: var(--surface4);
color: var(--text1);
}
Rad Shadow
העיצובים משתמשים במחלקה של כלי עזר שנקראת .rad-shadow. הצל הזה נוצר בכלי Smooth Shadow, ואני מאוד מעריך את זה. לקחתי את קטע הקוד שנוצר והתאמתי אותו אישית עם הצבעים שלי וחישובים של אטימות. הסיבה לכך הייתה ליצור צל שאפשר להתאים אותו בכל ערכת צבעים.

לשם כך, יצרתי 2 משתנים לכל ערכת צבעים שרציתי לשנות: צבע הצללית ועוצמת הצללית. הצבע משמש לשינויים ברוויה ובכהות, והעוצמה מאפשרת להגביר בקלות את עוצמת הצל כשמשתמשים בערכת צבעים כהה. התוצאה הסופית הייתה בערך כזו.
:root {
--surface-shadow-light: var(--brand-hue) 10% 20%;
--shadow-strength-light: .02;
}
.rad-shadow {
box-shadow:
0 2.8px 2.2px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .03)),
0 6.7px 5.3px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .01)),
0 12.5px 10px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .02)),
0 22.3px 17.9px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .02)),
0 41.8px 33.4px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .03)),
0 100px 80px hsl(var(--surface-shadow) / var(--shadow-strength))
;
}
אם הייתי רוצה להשתמש בעוד צללים בסכמת הצבעים שלי, הייתי מגדיר את זוויות הצללים כקבוע של טוקן עיצובי, כי כיוון האור צריך להיות זהה בכל הצללים בעיצוב.
שימוש בערכות הצבעים
אחרי שמגדירים מראש את הצבעים, הגיע הזמן להפוך אותם למאפיינים שלא תלויים בסכמה. הכוונה היא שבתור מחבר CSS בפרויקט של ערכת צבעים, בדרך כלל לא צריך לגשת לערך של ערכת צבעים ספציפית. אני רוצה שיהיה קל להשתמש בעיצוב.
כדי לעשות את זה, צריך להשתמש בסכמת הצבעים רק דרך המאפיינים הגנריים בהתאמה אישית, שנגדיר אותם בהמשך. כך, מי שמשתמש במשתני העיצוב לא צריך לדאוג לגבי ערכת הצבעים שמוגדרת כרגע, אלא רק להשתמש בצבעי הרקע והטקסט. במקום color: var(--text1-light), צריך להשתמש ב-color: var(--text1). כל ההתאמות והשינויים בצבעים מתבצעים ברמה גבוהה יותר ב-CSS.
בקטע הקוד הבא, הסגנונות המקשרים של העיצוב הבהיר מקשרים בין מאפיין כללי בהתאמה אישית לבין צבע ספציפי של העיצוב הבהיר. מעכשיו, בכל מקום שבו נעשה שימוש ב-var(--brand), יוצג צבע המותג הבהיר.
עיצוב בהיר (אוטומטי)
:root {
color-scheme: light;
--brand: var(--brand-light);
--text1: var(--text1-light);
--text2: var(--text2-light);
--surface1: var(--surface1-light);
--surface2: var(--surface2-light);
--surface3: var(--surface3-light);
--surface4: var(--surface4-light);
--surface-shadow: var(--surface-shadow-light);
--shadow-strength: var(--shadow-strength-light);
}
האתר משתמש עכשיו בעיצוב הבהיר. זה רגע מוצלח ומהנה מאוד! בואו נראה עוד כמה רגעים כאלה כשנשתמש בצבעים המוגדרים מראש בהקשרים אחרים של ערכות צבעים.
עיצוב כהה (אוטומטי)
@media (prefers-color-scheme: dark) {
:root {
color-scheme: dark;
--brand: var(--brand-dark);
--text1: var(--text1-dark);
--text2: var(--text2-dark);
--surface1: var(--surface1-dark);
--surface2: var(--surface2-dark);
--surface3: var(--surface3-dark);
--surface4: var(--surface4-dark);
--surface-shadow: var(--surface-shadow-dark);
--shadow-strength: var(--shadow-strength-dark);
}
}
עיצוב בהיר
[color-scheme="light"] {
color-scheme: light;
--brand: var(--brand-light);
--text1: var(--text1-light);
--text2: var(--text2-light);
--surface1: var(--surface1-light);
--surface2: var(--surface2-light);
--surface3: var(--surface3-light);
--surface4: var(--surface4-light);
--surface-shadow: var(--surface-shadow-light);
--shadow-strength: var(--shadow-strength-light);
}
עיצוב כהה
[color-scheme="dark"] {
color-scheme: dark;
--brand: var(--brand-dark);
--text1: var(--text1-dark);
--text2: var(--text2-dark);
--surface1: var(--surface1-dark);
--surface2: var(--surface2-dark);
--surface3: var(--surface3-dark);
--surface4: var(--surface4-dark);
--surface-shadow: var(--surface-shadow-dark);
--shadow-strength: var(--shadow-strength-dark);
}
עיצוב מעומעם
[color-scheme="dim"] {
color-scheme: dark;
--brand: var(--brand-dim);
--text1: var(--text1-dim);
--text2: var(--text2-dim);
--surface1: var(--surface1-dim);
--surface2: var(--surface2-dim);
--surface3: var(--surface3-dim);
--surface4: var(--surface4-dim);
--surface-shadow: var(--surface-shadow-dim);
--shadow-strength: var(--shadow-strength-dim);
}
בשלב הזה, המחברים יכולים להשתמש בערכת הצבעים הגנרית שסופקה לפי הצורך, ולא צריכים לדאוג יותר לגבי ערכות נושא.
סיכום
עכשיו שאתה יודע איך עשיתי את זה, איך היית עושה את זה?! 🙂
בואו נגוון את הגישות שלנו ונלמד את כל הדרכים לבנות אתרים. אתם יכולים ליצור הדגמה ב-Codepen או לארח הדגמה משלכם, לצייץ לי אותה ואוסיף אותה לקטע 'רמיקסים של הקהילה' שבהמשך.
מקור
רמיקסים של הקהילה
- @chris-kruining הוסיף פס הזזה של גוון, צבעי סטטוס ומצבי ניגודיות ל-no-preference, more ו-less:
הדגמה.