מדרג שכבות מגיעות לדפדפן שלך

שכבות מדורגות (כלל ה-CSS @layer) יגיעו ל-Chromium 99, ל-Firefox 97 ול-Safari 15.4 Beta. הם מאפשרים שליטה מפורשת יותר בקובצי ה-CSS כדי למנוע התנגשויות בין סגנונות ספציפיים. האפשרות הזו שימושית במיוחד לבסיסי קוד גדולים, למערכות עיצוב ולניהול סגנונות של צד שלישי באפליקציות.

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

ספציפיות של CSS והשלב

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

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

תצוגה חזותית של BEM של כרטיס עם כיתות
דוגמה מאוירת למתן שמות לפי BEM מ-keepinguptodate.com

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

לדוגמה, לבורר .post a.link יש רמת ספציפיות גבוהה יותר מאשר ל-.card a. אם תנסו לעצב קישור בתוך כרטיס בפוסט, תגלו שהבורר הספציפי יותר יוחל.

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

איור מהדגמה של הפרויקט של הפרדת ממשק המשתמש

@layer בפעולה

הדגמה של צבעי קישורים עם ייבוא
הדגמה ב-Codepen

בדוגמה הזו מוצגת העוצמה של שכבות מדורגות באמצעות @layer. מוצגים כמה קישורים: חלקם בלי שמות של כיתות נוספות, אחד עם כיתה .link ואחד עם כיתה .pink. לאחר מכן, ה-CSS מוסיף שלוש שכבות: base, ‏ typography ו-utilities באופן הבא:

@layer base {
  a {
    font-weight: 800;
    color: red; /* ignored */
  }

  .link {
    color: blue; /* ignored */
  }
}

@layer typography {
  a {
    color: green; /* styles *all* links */
  }
}

@layer utilities {
  .pink {
    color: hotpink;  /* styles *all* .pink's */
  }
}

בסופו של דבר, כל הקישורים יהיו ירוקים או ורוד. הסיבה לכך היא: למרות של-.link יש ספציפיות גבוהה יותר ברמת הבורר מאשר ל-a, יש סגנון צבע ב-a ב-@layer בעל עדיפות גבוהה יותר. a { color: green } מבטל את .link { color: blue } כשהכלל הירוק נמצא בשכבה אחרי הכלל הכחול.

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

ארגון השכבות

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

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

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

@layer utilities, typography, base;

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

צילום מסך של פרויקט ב-Codepen
הדגמה ב-Codepen

ארגון ייבוא

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

/* Base */
@import '../styles/base/normalize.css' layer(base); /* normalize or rest file */
@import '../styles/base/base.css' layer(base); /* body and base styles */
@import '../styles/base/theme.css' layer(theme); /* theme variables */
@import '../styles/base/typography.css' layer(theme); /* theme typography */
@import '../styles/base/utilities.css' layer(utilities); /* base utilities */

/* Layouts */
@import '../styles/components/post.css' layer(layouts); /* post layout */

/* Components */
@import '../styles/components/cards.css' layer(components); /* imports card */
@import '../styles/components/footer.css' layer(components); /* footer component */

לקטע הקוד שלמעלה יש שלוש שכבות: base,‏ layouts ו-components. קובצי הנורמליזציה, העיצוב והטיפוגרפיה נמצאים בתיקייה base, קובץ post נמצא בתיקייה layouts, וקבצים cards ו-footer נמצאים בתיקייה components. כשמייבאים את הקובץ, היצירה של השכבות מתבצעת באמצעות פונקציית השכבה. גישה חלופית היא לארגן את השכבות בחלק העליון של הקובץ ולהצהיר עליהן לפני כל ייבוא:

@layer base,
       theme,
       layouts,
       components,
       utilities;

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

צילום מסך מפרויקט ב-Codepen
בפרויקט הזה ב-Codepen

שכבות והסלמת

נרחיב את התמונה ונראה איפה נעשה שימוש בשכבות בהקשר של המפלס הרחב יותר:

איור של Cascade

סדר הקדימות הוא:

  • סוכן משתמש רגיל (העדיפות הנמוכה ביותר)
  • משתמש מקומי @layer
  • משתמש מקומי רגיל
  • מחבר @layers
  • Author normal
  • Author !important
  • Author @layer !important
  • משתמש מקומי !important
  • סוכן משתמש ‎!important** (עדיפות הגבוהה ביותר)

שימו לב שהסגנונות של @layer !important הפוכים. במקום להיות פחות ספציפיים לסגנונות ללא שכבות (רגילים), הם מקבלים עדיפות גבוהה יותר. הסיבה לכך היא האופן שבו !important פועל בשרשור: הוא מפר את השרשור הרגיל בגיליונות הסגנון ומהפך את הספציפיות הרגילה ברמת השכבה (העדיפות).

שכבות בתצוגת עץ

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

@layer default {
  p { max-width: 70ch; }
}

@layer framework {
  @layer default {
    p { margin-block: 0.75em; }
  }

  p { margin-bottom: 1em; }
}

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

@layer framework.default {
  p { margin-block: 0.75em }
}

השכבות והסדר שלהן שיתקבלו הם:

  • ברירת מחדל
  • framework.default
  • framework ללא שכבות
  • ללא שכבות

דברים שכדאי לשים לב אליהם

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

כלל 1: אין להשתמש ב-@layer לצורך הגדרת היקף

שכבות מדורגות לא פותרות את בעיית ההיקף. אם יש לכם קובץ CSS עם @layer, למשל card.css, ואתם רוצים להגדיר סגנון לכל הקישורים בכרטיס, אל תכתבו סגנונות כמו:

a {
  
}

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

.card a {
  
}

כלל 2: שכבות מדורגות ממוינות מאחורי CSS ללא שכבות

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

כלל 3: !important הופך את הספציפיות של המפל

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

במקרה כזה, הסגנונות של !important מבטלים את הספציפיות שלהם. לצורך המחשה, בתרשים שלמעלה מוצגת ההיררכיה: ל-author @layers יש עדיפות נמוכה יותר מאשר ל-author normal, ל-author normal יש עדיפות נמוכה יותר מאשר ל-author !important, ול-author !important יש עדיפות נמוכה יותר מאשר ל-author @layer !important.

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

כלל 4: הבנת נקודות ההזרקה

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

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

כלל מס' 5: חשוב לשמור על רמת ספציפיות גבוהה

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

הערך של a בקובץ layer(components) יבטל את הערך של .pink בקובץ layer(utilities) אם: צוין הערך @layer utilities, components. זהו חלק מכוון של ה-API, אבל אם לא ציפיתם לזה, זה עלול לבלבל ולתסכל אתכם.

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

מידע נוסף על שכבות מדורגות

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