מצב שירות ה-CSS 2022

תכונות של עיצוב אתרים שקיימות היום ויהיו קיימות בעתיד, כפי שהוצגו בכנס Google IO 2022, ועוד כמה תוספות.

שנת 2022 צפויה להיות אחת השנים הטובות ביותר של CSS, הן מבחינת תכונות והן מבחינת השקות של תכונות דפדפן שיתופיות, עם מטרה משותפת להטמעת 14 תכונות!

סקירה כללית

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

תוכן העניינים

אפשר להשתמש ברשימה הבאה כדי לדלג לנושאים שמעניינים אתכם:

תאימות דפדפן

אחת הסיבות העיקריות לכך שהרבה תכונות CSS מוגדרות להשקה שיתופית היא המאמצים של Interop 2022. לפני שמתעמקים במאמצי התאימות, חשוב לעיין במאמצי Compat 2021.

Compat 2021

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

  1. sticky מיקום
  2. aspect-ratio מידות
  3. פריסה של flex
  4. פריסה של grid
  5. transform מיקום ואנימציה

הציונים בבדיקות עלו בכל המדדים, מה שמעיד על שיפור ביציבות ובמהימנות. כל הכבוד לצוותים!

Interop 2022

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

  1. @layer
  2. מרחבי צבעים ופונקציות
  3. בלימה
  4. <dialog>
  5. תאימות של טפסים
  6. גלילה
  7. Subgrid
  8. טיפוגרפיה
  9. יחידות של אזור התצוגה
  10. תאימות לאינטרנט

זו רשימה מרגשת ושאפתנית, ואני לא יכול לחכות לראות איך היא תתפתח.

המלצות חדשות לשנת 2022

לא מפתיע שהמצב של CSS בשנת 2022 מושפע באופן משמעותי מהעבודה על Interop2022.

שכבות Cascade

Browser Support

  • Chrome: 99.
  • Edge: 99.
  • Firefox: 97.
  • Safari: 15.4.

Source

לפני @layer, הסדר שבו נטענו גיליונות הסגנונות היה חשוב מאוד, כי סגנונות שנטענו אחרונים יכולים לדרוס סגנונות שנטענו קודם. הדבר הוביל לגיליונות סגנונות (stylesheet) מנוהלים בקפידה, שבהם המפתחים נדרשו לטעון קודם סגנונות פחות חשובים ואחר כך סגנונות חשובים יותר. קיימות מתודולוגיות שלמות שעוזרות למפתחים לנהל את החשיבות הזו, כמו ITCSS.

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

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

כלי הפיתוח ל-Chrome עוזרים להבין אילו סגנונות מגיעים מאיזו שכבה:

צילום מסך של סרגל הצד Styles (סגנונות) ב-Chrome Devtools, שמראה איך סגנונות מופיעים בתוך קבוצות Layer (שכבה) חדשות.

משאבים

Subgrid

Browser Support

  • Chrome: 117.
  • Edge: 117.
  • Firefox: 71.
  • Safari: 16.

Source

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

אחרי subgrid, ילד של רשת יכול לאמץ את העמודות או השורות של ההורים שלו כעמודות או שורות משלו, וליישר את עצמו או את הילדים שלו אליהן.

בדוגמה הבאה, רכיב ה-body יוצר רשת קלאסית של שלוש עמודות: העמודה האמצעית נקראת main, והעמודות הימנית והשמאלית נותנות שם לקווים שלהן fullbleed. לאחר מכן, כל רכיב בגוף, <nav> ו-<main>, מאמץ את השורות שנקראות מהגוף על ידי הגדרת grid-template-columns: subgrid.

​​body {
  display: grid;
  grid-template-columns:
    [fullbleed-start]
    auto [main-start] min(90%, 60ch) [main-end] auto
    [fullbleed-end]
  ;
}

body > * {
  display: grid;
  grid-template-columns: subgrid;
}

לבסוף, ילדים בגיל <nav> או <main> יכולים ליישר את עצמם או לשנות את הגודל שלהם באמצעות העמודות והקווים fullbleed ו-main.

.main-content {
  grid-column: main;
}

.fullbleed {
  grid-column: fullbleed;
}

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

צילום מסך של הדגמה של רשת משנה, שבו נעשה שימוש בכלי שכבת העל של הרשת ב-Chrome DevTools כדי להציג את הקווים שמוגדרים על ידי CSS.

בחלונית Elements בכלי הפיתוח אפשר לראות אילו אלמנטים הם רשתות ורשתות משנה, וזה מאוד שימושי לניפוי באגים או לאימות פריסה.

צילום מסך של החלונית Elements (רכיבים) ב-Chrome Devtools, שמוצגות בה תוויות של רכיבים עם פריסות של רשת או רשת משנה.
צילום מסך מכלי הפיתוח של Firefox

משאבים

שאילתות בנוגע למאגר

Browser Support

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 110.
  • Safari: 16.

Source

לפני גרסה @container, רכיבים של דף אינטרנט יכלו להגיב רק לגודל של אזור התצוגה כולו. האפשרות הזו מצוינת לפריסות מאקרו, אבל בפריסות מיקרו, שבהן הקונטיינר החיצוני שלהן לא תופס את כל אזור התצוגה, אי אפשר להתאים את הפריסה בהתאם.

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

/* establish a container */
.day {
  container-type: inline-size;
  container-name: calendar-day;
}

הסגנונות האלה מאפשרים לשאול שאילתות לגבי העמודות Mon,‏ Tues,‏ Wed,‏ Thurs ו-Fri בסרטון הבא לפי רכיבי האירוע.

הדגמה מאת Una Kravets

הנה קוד ה-CSS לשליחת שאילתה למאגר calendar-day כדי לקבל את הגודל שלו, ואז להתאים את הפריסה ואת גדלי הגופן:

@container calendar-day (max-width: 200px) {
  .date {
    display: block;
  }

  .date-num {
    font-size: 2.5rem;
    display: block;
  }
}

דוגמה נוספת: רכיב ספר אחד מותאם לשטח הפנוי בעמודה שאליה הוא נגרר:

הדגמה מאת Max Böck

אונה צודקת בהערכת המצב כחדש רספונסיבי. יש הרבה החלטות מעניינות וחשובות בנוגע לעיצוב שאפשר לקבל כשמשתמשים ב-@container.

משאבים

accent-color

Browser Support

  • Chrome: 93.
  • Edge: 93.
  • Firefox: 92.
  • Safari: 15.4.

Source

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

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

/* tint everything */
:root {
  accent-color: hotpink;
}

/* tint one element */
progress {
  accent-color: indigo;
}

רכיבי HTML עם הדגשה בהירה וכהה זה לצד זה לצורך השוואה.

למידע נוסף על accent-color, מומלץ לעיין בפוסט שלי ב-web.dev שבו אני בוחן היבטים רבים נוספים של מאפיין ה-CSS השימושי הזה.

משאבים

צבע רמה 4 ו-5

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

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

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

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

@media (dynamic-range: high) {
  .neon-pink {
    --neon-glow: color(display-p3 1 0 1);
  }
}

@supports (color: lab(0% 0 0)) {
  .neon-pink {
    --neon-glow: lab(150% 160 0);
  }
}

hwb()

Browser Support

  • Chrome: 101.
  • Edge: 101.
  • Firefox: 96.
  • Safari: 15.

Source

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

השימוש בפונקציית הצבע הזו יוצר צבעים ממרחב הצבעים sRGB, כמו HSL ו-RGB. מבחינת חידושים לשנת 2022, לא מדובר בצבעים חדשים, אבל יכול להיות שזה יקל על חלק מהמשימות למעריצים של התחביר והמודל המנטלי.

משאבים

מרחבי צבעים

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

בשנת 2022, שירות CSS אמור להציע 10 מרחבי צבעים חדשים, שלכל אחד מהם יש תכונות ייחודיות שיעזרו למעצבים ולמפתחים להציג, לבחור ולערבב צבעים. בעבר, sRGB הייתה האפשרות היחידה לעבודה עם צבעים, אבל עכשיו CSS פותח אפשרויות חדשות ומרחב צבעים חדש שמוגדר כברירת מחדל, LCH.

color-mix()

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 113.
  • Safari: 16.2.

Source

לפני color-mix(), מפתחים ומעצבים היו צריכים להשתמש במעבדים מקדימים כמו Sass כדי לערבב את הצבעים לפני שהדפדפן הציג אותם. בנוסף, ברוב הפונקציות של ערבוב צבעים לא הייתה אפשרות לציין את מרחב הצבעים שבו יתבצע הערבוב, ולפעמים התוצאות היו מבלבלות.

אחרי color-mix(), מפתחים ומעצבים יכולים לשלב צבעים בדפדפן, לצד כל הסגנונות האחרים שלהם, בלי להריץ תהליכי בנייה או לכלול JavaScript. בנוסף, הם יכולים לציין את מרחב הצבעים שבו יתבצע המיזוג, או להשתמש במרחב הצבעים למיזוג שמוגדר כברירת מחדל – LCH.

לרוב, צבע המותג משמש כבסיס ויוצרים ממנו וריאציות, כמו צבעים בהירים או כהים יותר לסגנונות של מצב ריחוף. כך זה נראה עם color-mix():

.color-mix-example {
  --brand: #0af;

  --darker: color-mix(var(--brand) 25%, black);
  --lighter: color-mix(var(--brand) 25%, white);
}

ואם רוצים לערבב את הצבעים האלה במרחב צבעים אחר, כמו srgb, אפשר לשנות את זה:

.color-mix-example {
  --brand: #0af;

  --darker: color-mix(in srgb, var(--brand) 25%, black);
  --lighter: color-mix(in srgb, var(--brand) 25%, white);
}

בהמשך מופיעה הדגמה של שימוש בערכות נושא באמצעות color-mix(). אפשר לנסות לשנות את צבע המותג ולראות את העדכון של העיצוב:

אתם מוזמנים ליהנות מערבוב צבעים במרחבי צבע שונים בגיליונות הסגנונות שלכם בשנת 2022!

משאבים

color-contrast()

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

צילום מסך של 3 לוחות צבעים של Material, שמוצגים בהם 14 צבעים וצבעי הניגודיות המתאימים שלהם לטקסט (לבן או שחור).
דוגמה מתוך לוחות הצבעים של Material Design משנת 2014

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

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

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

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

color: color-contrast(gray);

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

color: color-contrast(gray vs indigo, rebeccapurple, hotpink);

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

color: color-contrast(
  var(--bg-blue-1)
  vs
  var(--text-lightest), var(--text-light), var(--text-subdued)
  to AA /* 4.5 could also be passed */
);

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

משאבים

תחביר של צבעים יחסיים

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 113.
  • Safari: 15.

Source

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

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

בדוגמה הבאה של תחביר, מסופק ערך הקסדצימלי בסיסי ושני צבעים חדשים נוצרים ביחס אליו. הצבע הראשון --absolute-change יוצר צבע חדש במרחב הצבעים LCH מהצבע הבסיסי, ואז מחליף את בהירות הצבע הבסיסי ב-75%, תוך שמירה על הכרומה (c) והגוון (h). הצבע השני --relative-change יוצר צבע חדש במרחב הצבעים LCH מהצבע הבסיסי, אבל הפעם הוא מפחית את הכרומה (c) ב-20%.

.relative-color-syntax {
  --color: #0af;
  --absolute-change: lch(from var(--color) 75% c h);
  --relative-change: lch(from var(--color) l calc(c-20%) h);
}

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

בדמו הבא השתמשתי בתחביר של צבעים יחסיים כדי ליצור וריאציות בהירות וכהות יותר של צבע בסיסי, והשתמשתי ב-color-contrast() כדי לוודא שלתוויות יש ניגודיות מתאימה:

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

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

:root {
  --_color-base: #339af0;

  --color-0:  lch(from var(--_color-base) 98% 10 h);
  --color-1:  lch(from var(--_color-base) 93% 20 h);
  --color-2:  lch(from var(--_color-base) 85% 40 h);
  --color-3:  lch(from var(--_color-base) 75% 46 h);
  --color-4:  lch(from var(--_color-base) 66% 51 h);
  --color-5:  lch(from var(--_color-base) 61% 52 h);
  --color-6:  lch(from var(--_color-base) 55% 57 h);
  --color-7:  lch(from var(--_color-base) 49% 58 h);
  --color-8:  lch(from var(--_color-base) 43% 55 h);
  --color-9:  lch(from var(--_color-base) 39% 52 h);
  --color-10: lch(from var(--_color-base) 32% 48 h);
  --color-11: lch(from var(--_color-base) 25% 45 h);
  --color-12: lch(from var(--_color-base) 17% 40 h);
  --color-13: lch(from var(--_color-base) 10% 30 h);
  --color-14: lch(from var(--_color-base) 5% 20 h);
  --color-15: lch(from var(--_color-base) 1% 5 h);
}
צילום מסך של 15 פלטות שנוצרו באופן דינמי על ידי CSS.
אפשר לנסות את ההדגמה

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

משאבים

מרחבי צבעים של מעברי צבע

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

4 הדרגתיות ברשת, כולם מציאן עד ורוד עמוק. הגוונים ב-LCH וב-LAB דינמיים יותר באופן עקבי, בעוד שב-sRGB יש מעט גוונים דהויים באמצע.

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

התוספת לתחביר מופיעה אחרי כיוון הגרדיאנט, משתמשת בתחביר החדש in והיא אופציונלית:

background-image: linear-gradient(
  to right in hsl,
  black, white
);

background-image: linear-gradient(
  to right in lch,
  black, white
);

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

מוצגים 11 מרחבי צבעים בהשוואה בין שחור ללבן.

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

‫11 מרחבי צבעים שמוצגים בהשוואה בין כחול לשחור.

לדוגמאות, להסברים ולתגובות נוספות, אפשר לקרוא את השרשור הזה בטוויטר.

משאבים

inert

Browser Support

  • Chrome: 102.
  • Edge: 102.
  • Firefox: 112.
  • Safari: 15.5.

Source

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

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

דוגמה טובה לכך היא הפונקציה alert() ב-JavaScript:

האתר מוצג כאינטראקטיבי, ואז מתבצעת קריאה לפונקציה alert(), והדף כבר לא פעיל.

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

הנה קוד לדוגמה שממחיש איך זה עובד:

<body>
  <div class="modal">
    <h2>Modal Title</h2>
    <p>...<p>
    <button>Save</button>
    <button>Discard</button>
  </div>
  <main inert>
    <!-- cannot be keyboard focused or clicked -->
  </main>
</body>

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

משאבים

גופני COLRv1

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

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

הדמיה השוואתית ותרשים עמודות שמראים שגופני COLRv1 חדים וקטנים יותר.
התמונה נלקחה מהכתובת https://developer.chrome.com/blog/colrv1-fonts/

דוגמה מפוסט בבלוג למפתחי Chrome בנושא אמוג'י. יכול להיות ששמתם לב שאם מגדילים את גודל הגופן של אמוג'י, הוא לא נשאר חד. זו תמונה ולא יצירת אומנות וקטורית. לעתים קרובות, כשמשתמשים באמוג'י באפליקציות, הוא מוחלף בנכס באיכות גבוהה יותר. בגופני COLRv1, סמלי האמוג'י הם וקטוריים ויפים:

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

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

התאמה אישית של גופן COLRv1 מתבצעת באמצעות @font-palette-values, כלל מיוחד ב-CSS שמאפשר לקבץ ולתת שם לקבוצה של אפשרויות התאמה אישית כדי להשתמש בהן בהמשך. שימו לב איך מציינים שם מותאם אישית בדיוק כמו מאפיין מותאם אישית, שמתחיל ב---:

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

@font-palette-values --colorized {
  font-family: "Bungee Spice";
  base-palette: 0;
  override-colors: 0 hotpink, 1 cyan, 2 white;
}

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

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

@font-palette-values --colorized {
  font-family: "Bungee Spice";
  base-palette: 0;
  override-colors: 0 hotpink, 1 cyan, 2 white;
}

.spicy {
  font-family: "Bungee Spice";
  font-palette: --colorized;
}
צילום מסך של הגופן Bungee Spice עם המילה DUNE.
גופן Bungee Spice מוצג עם צבעים מותאמים אישית, המקור מ-https://developer.chrome.com/blog/colrv1-fonts/

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

משאבים

יחידות של אזור התצוגה

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

לפני שהשקנו את הווריאציות החדשות של אזורי התצוגה, האינטרנט הציע יחידות פיזיות שיעזרו להתאים את אזורי התצוגה. היו כאלה לגובה, לרוחב, לגודל הכי קטן (vmin) ולצד הכי גדול (vmax). הן עבדו טוב להרבה דברים, אבל דפדפנים לנייד הוסיפו מורכבות.

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

.original-viewport-units {
  height: 100vh;
  width: 100vw;
  --size: 100vmin;
  --size: 100vmax;
}

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

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

זוהי רשימה מלאה של כל האפשרויות החדשות של יחידות אזור התצוגה שזמינות עם הווריאציות החדשות של אזור התצוגה:

יחידות גובה של אזור התצוגה
​​.new-height-viewport-units {
  height: 100vh;
  height: 100dvh;
  height: 100svh;
  height: 100lvh;
  block-size: 100vb;
  block-size: 100dvb;
  block-size: 100svb;
  block-size: 100lvb;
}
יחידות רוחב של אזור התצוגה
.new-width-viewport-units {
  width: 100vw;
  width: 100dvw;
  width: 100svw;
  width: 100lvw;
  inline-size: 100vi;
  inline-size: 100dvi;
  inline-size: 100svi;
  inline-size: 100lvi;
}
היחידות הקטנות ביותר בצד של אזור התצוגה
.new-min-viewport-units {
  --size: 100vmin;
  --size: 100dvmin;
  --size: 100svmin;
  --size: 100lvmin;
}
היחידות הגדולות ביותר בצד אזור התצוגה
.new-max-viewport-units {
  --size: 100vmax;
  --size: 100dvmax;
  --size: 100svmax;
  --size: 100lvmax;
}

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

משאבים

:has()

Browser Support

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 121.
  • Safari: 15.4.

Source

לפני גרסה :has(), הנושא של בורר היה תמיד בסוף. לדוגמה, הנושא של בורר זה הוא פריט ברשימה: ul > li. סלקטורים פסאודו יכולים לשנות את הסלקטור, אבל הם לא משנים את הנושא: ul > li:hover או ul > li:not(.selected).

אחרי :has(), נושא שנמצא ברמה גבוהה יותר בעץ הרכיבים יכול להישאר הנושא תוך כדי מתן שאילתה לגבי ילדים: ul:has(> li). קל להבין למה :has() קיבל את השם הנפוץ parent selector (סלקטור הורה), כי הנושא של הסלקטור הוא עכשיו ההורה במקרה הזה.

הנה דוגמה לתחביר בסיסי שבה המחלקה .parent נשארת הנושא, אבל היא נבחרת רק אם לרכיב צאצא יש את המחלקה .child:

.parent:has(.child) {...}

דוגמה שבה רכיב <section> הוא הנושא, אבל הסלקטור תואם רק אם לאחד מרכיבי הצאצא יש :focus-visible:

section:has(*:focus-visible) {...}

הכלי לבחירת :has() מתחיל להיות שימושי מאוד כשמתגלים תרחישי שימוש מעשיים יותר. לדוגמה, אי אפשר לבחור תגי <a> כשהם עוטפים תמונות, ולכן קשה ללמד את תג העוגן איך לשנות את הסגנונות שלו בתרחיש השימוש הזה. אבל אפשר לעשות את זה באמצעות :has():

a:has(> img) {...}

בדוגמאות האלה, :has() נראה כמו סלקטור של רכיב אב. כדאי לשקול את תרחיש השימוש בתמונות בתוך רכיבי <figure> ולהתאים את הסגנונות של התמונות אם יש לרכיב <figcaption>. בדוגמה הבאה, נבחרו דמויות עם כיתובים, ואז תמונות בהקשר הזה. השימוש ב-:has() לא משנה את הנושא, כי הנושא שאנחנו מתמקדים בו הוא תמונות ולא דמויות:

figure:has(figcaption) img {...}

נראה שהשילובים הם אינסופיים. משלבים את :has() עם שאילתות quantity ומשנים את פריסות ה-CSS grid על סמך מספר הצאצאים. אפשר לשלב את :has() עם מצבי מחלקה פסאודו אינטראקטיביים וליצור אפליקציות שמגיבות בדרכים יצירתיות חדשות.

קל לבדוק אם יש תמיכה באמצעות הפונקציה @supports והפונקציה selector() שלה, שבודקות אם הדפדפן מבין את התחביר לפני שמשתמשים בו:

@supports (selector(:has(works))) {
  /* safe to use :has() */
}

משאבים

‫2022 ואילך

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

המשמעות של הקטעים הבאים היא שרבים מחפשים פתרונות לבעיות שמפורטות בהם, ולא שהפתרונות האלה יפורסמו ב-2023.

מאפיינים מותאמים אישית עם הקלדה חלשה

Browser Support

  • Chrome: 85.
  • Edge: 85.
  • Firefox: 128.
  • Safari: 16.4.

Source

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

נניח שיש תרחיש שבו box-shadow משתמש במאפיינים מותאמים אישית בשביל הערכים שלו:

box-shadow: var(--x) var(--y) var(--blur) var(--spread) var(--color);

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

כאן נכנס לתמונה @property: --x יכול להפוך למאפיין מותאם אישית עם הקלדה, הוא כבר לא חופשי וגמיש, אלא בטוח עם גבולות מוגדרים:

@property --x {
  syntax: '<length>';
  initial-value: 0px;
  inherits: false;
}

עכשיו, כשהאפליקציה box-shadow משתמשת ב-var(--x) ומאוחר יותר מתבצע ניסיון להשתמש ב---x: red, המערכת תתעלם מ-red כי הוא לא <length>. המשמעות היא שה-Shadow ממשיך לפעול, גם אם ניתן ערך לא תקין לאחד מהמאפיינים המותאמים אישית שלו. במקום להיכשל, הוא חוזר לערך initial-value של 0px.

Animation

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

בדוגמה הבאה, נעשה שימוש במעבר צבעים רדיאלי כדי ליצור חלק משכבת-על, וכך ליצור אפקט של אור ממוקד. ‫JavaScript מגדיר את המיקום של העכבר בציר X ובציר Y כשמקש Alt או Opt נלחץ, ואז משנה את גודל המיקוד לערך קטן יותר כמו 25%, וכך יוצר את עיגול המיקוד של הזרקור במיקום העכבר:

לניסיון ההדגמה
.focus-effect {
  --focal-size: 100%;
  --mouse-x: center;
  --mouse-y: center;

  mask-image: radial-gradient(
    circle at var(--mouse-x) var(--mouse-y),
    transparent 0%,
    transparent var(--focal-size),
    black 0%
  );
}

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

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

@property --focal-size {
  syntax: '<length-percentage>';
  initial-value: 100%;
  inherits: false;
}

.focus-effect {
  --focal-size: 100%;
  --mouse-x: center;
  --mouse-y: center;

  mask-image: radial-gradient(
    circle at var(--mouse-x) var(--mouse-y),
    transparent 0%,
    transparent var(--focal-size),
    black 0%
  );

  transition: --focal-size .3s ease;
}
אפשר לנסות את ההדגמה

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

אפשר לעשות הרבה יותר עם @property, אבל גם הפעלה של התכונות הקטנות האלה יכולה לעזור מאוד.

משאבים

היית במקום min-width או במקום max-width

לפני טווחי שאילתות מדיה, שאילתת מדיה מסוג CSS משתמשת ב-min-width וב-max-width כדי להגדיר תנאים של מעל ומתחת. הוא עשוי להיראות כך:

@media (min-width: 320px) {
  
}

אחרי טווחי שאילתות מדיה, אותה שאילתת מדיה יכולה להיראות כך:

@media (width >= 320px) {
  
}

שאילתת מדיה של CSS שמשתמשת גם ב-min-width וגם ב-max-width יכולה להיראות כך:

@media (min-width: 320px) and (max-width: 1280px) {
  
}

אחרי טווחי שאילתות מדיה, אותה שאילתת מדיה יכולה להיראות כך:

@media (320px <= width <= 1280px) {
  
}

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

משאבים

אין משתנים של שאילתות מדיה

לפני @custom-media, שאילתות מדיה היו צריכות לחזור על עצמן שוב ושוב, או להסתמך על מעבדים מקדימים כדי ליצור את הפלט המתאים על סמך משתנים סטטיים במהלך זמן ה-build.

אחרי @custom-media, שירותי CSS מאפשרים ליצור כינויים לשאילתות מדיה ולהפנות אליהן, בדיוק כמו מאפיין בהתאמה אישית.

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

@custom-media --OSdark  (prefers-color-scheme: dark);
@custom-media --OSlight (prefers-color-scheme: light);

@custom-media --pointer (hover) and (pointer: coarse);
@custom-media --mouse   (hover) and (pointer: fine);

@custom-media --xxs-and-above (width >= 240px);
@custom-media --xxs-and-below (width <= 240px);

אחרי שהגדרתי אותן, אני יכול להשתמש באחת מהן כך:

@media (--OSdark) {
  :root {
    
  }
}

תמצא רשימה מלאה של שאילתות מדיה מותאמות אישיתשבהן אני משתמש בספריית המאפיינים המותאמים אישית של CSS‏ Open Props.

משאבים

הקינון של הסלקטורים נוח מאוד

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

אחרי @nest, החזרה נעלמת. כמעט כל התכונות של קינון עם מעבד מקדים יהיו זמינות כחלק מ-CSS.

article {
  color: darkgray;
}

article > a {
  color: var(--link-color);
}

/* with @nest becomes */

article {
  color: darkgray;

  & > a {
    color: var(--link-color);
  }
}

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

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

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

/* parent owns this, adjusting children */
section:focus-within > article {
  border: 1px solid hotpink;
}

/* with @nest becomes */

/* article owns this, adjusting itself when inside a section:focus-within */
article {
  @nest section:focus-within > & {
     border: 1px solid hotpink;
  }
}

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

משאבים

קשה מאוד להגדיר סגנונות

Browser Support

  • Chrome: 118.
  • Edge: 118.
  • Firefox: 146.
  • Safari: 17.4.

Source

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

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

בדוגמה הבאה, אפשר להפוך את ההיקף של מוסכמת מתן השמות BEM לכוונת השימוש בפועל. הבורר BEM מנסה להגדיר את הצבע של רכיב header בתוך מאגר .card באמצעות מוסכמות שמות. כדי להשיג את היעד, הכותרת צריכה לכלול את שם המחלקה הזה. עם @scope, לא נדרשים כללי מתן שמות כדי להשיג את אותה מטרה בלי לתייג את רכיב הכותרת:

.card__header {
  color: var(--text);
}

/* with @scope becomes */

@scope (.card) {
  header {
    color: var(--text);
  }
}

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

​​@scope (.light-theme) {
  a { color: purple; }
}

@scope (.dark-theme) {
  a { color: plum; }
}

כדי להשלים את הסיפור, @scope מאפשר גם לקבוע איפה מסתיים היקף הסגנון. אי אפשר לעשות את זה באמצעות מוסכמות שמות או מעבדי קדם; זה מיוחד ורק CSS מובנה בדפדפן יכול לעשות את זה. בדוגמה הבאה, הסגנונות img ו-.content מוחלים באופן בלעדי כאשר צאצא של .media-block הוא אח או הורה של .content:

@scope (.media-block) to (.content) {
  img {
    border-radius: 50%;
  }

  .content {
    padding: 1em;
  }
}

משאבים

אין דרך להשתמש ב-CSS כדי ליצור פריסת masonry

לפני CSS masonry עם grid, ‏ JavaScript הייתה הדרך הכי טובה ליצור פריסת masonry, כי כל אחת משיטות ה-CSS עם עמודות או flexbox לא הציגה את סדר התוכן בצורה מדויקת.

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

צילום מסך של פריסת ה-Masonry שבו מוצגים מספרים שנעים לאורך החלק העליון, ואז יורדים למטה.
תמונה והדגמה מ-Smashing Magazine
https://www.smashingmagazine.com/native-css-masonry-layout-css-grid/

הדמו שלמעלה נוצר באמצעות ה-CSS הבא:

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: masonry;
}

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

משאבים

אי אפשר להשתמש ב-CSS כדי לעזור למשתמשים לצמצם את הנתונים

Browser Support

  • Chrome: behind a flag.
  • Edge: behind a flag.
  • Firefox: not supported.
  • Safari: not supported.

Source

לפני prefers-reduced-data שאילתת המדיה, JavaScript ושרת יכלו לשנות את ההתנהגות שלהם על סמך מערכת ההפעלה או הדפדפן של המשתמש, או על סמך האפשרות 'חיסכון בנתונים', אבל CSS לא יכל.

אחרי שאילתת המדיה prefers-reduced-data, CSS יכול להצטרף לשיפור חוויית המשתמש ולמלא את חלקו בשמירת נתונים.

@media (prefers-reduced-data: reduce) {
  picture, video {
    display: none;
  }
}

ה-CSS שלמעלה משמש ברכיב הזה של גלילה במדיה, והחיסכון יכול להיות משמעותי. ככל שאזור התצוגה של המבקר גדול יותר, כך אפשר לחסוך יותר זמן בטעינת הדף. השמירה נמשכת בזמן שהמשתמשים יוצרים אינטראקציה עם רכיבי הגלילה של המדיה. לכל התמונות יש מאפייני loading="lazy", ובשילוב עם הסתרת הרכיב לחלוטין באמצעות CSS, זה אומר שלעולם לא תישלח בקשה לרשת לגבי התמונה.

צילום מסך של ממשק קרוסלה של תוכנית טלוויזיה עם הרבה תמונות ממוזערות ושמות.

בבדיקה שלי, בתיבת תצוגה בגודל בינוני, נטענו בהתחלה 40 בקשות ו-700kb של משאבים. כשהמשתמש גולל את רשימת המדיה, נטענות עוד בקשות ומשאבים. עם CSS ושאילתת המדיה של הנתונים המצומצמים, נטענות 10 בקשות ו-172KB של משאבים. זה חצי מגה-בייט של חיסכון, והמשתמש אפילו לא גלל את המדיה, ובשלב הזה לא מתבצעות בקשות נוספות.

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

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

משאבים

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

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

ממשקי API חדשים

snapChanging()

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

document.querySelector('.snap-carousel').addEventListener('snapchanging', event => {
  console.log('Snap is changing', event.snappedTargetsList);
});
snapChanged()

האירוע הזה מופעל ברגע שהדפדפן עובר לחלון צאצא חדש והגלילה מסתיימת. כך כל ממשק משתמש שתלוי בצאצא המוצמד יכול להתעדכן ולשקף את החיבור.

document.querySelector('.snap-carousel').addEventListener('snapchanged', event => {
  console.log('Snap changed', event.snappedTargetsList);
});
scroll-start

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

:root { --nav-height: 100px }

.snap-scroll-y {
  scroll-start-y: var(--nav-height);
}
:snap-target

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

.card {
  --shadow-distance: 5px;
  box-shadow: 0 var(--shadow-distance) 5px hsl(0 0% 0% / 25%);
  transition: box-shadow 350ms ease;
}

.card:snapped {
  --shadow-distance: 30px;
}

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

התכונות האלה של CSS ו-JS עדיין בשלבים מוקדמים מאוד, אבל בקרוב נפרסם פוליפילים שיעזרו לכם להטמיע אותן ולבדוק אותן.

משאבים

רכיבה על אופניים בין מדינות מוכרות

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

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

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

<ul class='ingredients'>
   <li>1 banana
   <li>1 cup blueberries
  ...
</ul>

וסגנונות ה-CSS הרלוונטיים:toggle()

li {
  toggle-root: check self;
}

li:toggle(check) {
  text-decoration: line-through;
}

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

משאבים

התאמה אישית של רכיבי בחירה

לפני <selectmenu>, לא הייתה אפשרות להתאים אישית רכיבי <option> עם HTML עשיר או לשנות הרבה דברים בתצוגה של רשימת אפשרויות ב-CSS. לכן, מפתחים נאלצו לטעון ספריות חיצוניות ששחזרו חלק גדול מהפונקציונליות של <select>, וזה דרש הרבה עבודה.

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

בדוגמה הבאה, שנלקחה מ<selectmenu> דף ההסבר, נוצר תפריט בחירה חדש עם כמה אפשרויות בסיסיות:

<selectmenu>
  <option>Option 1</option>
  <option>Option 2</option>
  <option>Option 3</option>
</selectmenu>

אפשר להשתמש ב-CSS כדי לטרגט ולסגנן את החלקים של הרכיב:

.my-select-menu::part(button) {
  color: white;
  background-color: red;
  padding: 5px;
  border-radius: 5px;
}

.my-select-menu::part(listbox) {
  padding: 10px;
  margin-top: 5px;
  border: 1px solid red;
  border-radius: 5px;
}

תפריט עם מראה נבחר וצבעי הדגשה אדומים.

אתם יכולים לנסות את רכיב <selectmenu> ב-Chromium ב-Canary עם הדגל web experiments מופעל. בשנת 2023 והלאה, כדאי לשים לב לרכיבי תפריט נפתח שניתן להתאים אישית.

משאבים

הצמדת אלמנט לאלמנט אחר

לפני anchor(), האסטרטגיות position absolute ו-relative היו זמינות למפתחים כדי להזיז רכיבי צאצא בתוך רכיב אב.

אחרי anchor(), מפתחים יכולים למקם רכיבים ביחס לרכיבים אחרים, בלי קשר להיותם צאצאים או לא. המאפיין הזה גם מאפשר למפתחים לציין את הקצה שביחס אליו רוצים למקם את הרכיב, ועוד אפשרויות ליצירת קשרים בין מיקומי הרכיבים.

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

משאבים