שכבות מדורגות (כלל ה-CSS @layer
) יגיעו ל-Chromium 99, ל-Firefox 97 ול-Safari 15.4 Beta. הם מאפשרים שליטה מפורשת יותר בקובצי ה-CSS כדי למנוע התנגשויות בין סגנונות ספציפיים. האפשרות הזו שימושית במיוחד לבסיסי קוד גדולים, למערכות עיצוב ולניהול סגנונות של צד שלישי באפליקציות.
שכבות CSS ברורות מונעות שינוי סגנון בלתי צפוי ומקדמות ארכיטקטורה טובה יותר של CSS.
ספציפיות של CSS והשלב
הספציפיות של CSS היא הדרך שבה המערכת של CSS מחליטה אילו סגנונות להחיל על אילו רכיבים. הבוררים השונים שבהם אפשר להשתמש קובעים את מידת הספציפיות של כל כלל סגנון. לדוגמה, רכיבים פחות ספציפיים ממחלקות או ממאפיינים, שהם פחות ספציפיים ממזהים. זהו חלק מהותי בלמידת CSS.
אנשים משתמשים במוסכמות של מתן שמות ב-CSS, כמו BEM, כדי למנוע שינוי לא מכוון של ספציפיות. כשנותנים לכל דבר שם של סיווג יחיד, הכול ממוקם באותו מישור ספציפיות. עם זאת, לא תמיד אפשר לשמור על סגנונות מאורגנים כאלה, במיוחד כשעובדים עם קוד ומערכות עיצוב של צד שלישי.
שכבות מדורגות נועדו לפתור את הבעיה הזו. הם מוסיפים שכבה חדשה למפל של CSS. כשמשתמשים בסגנונות בשכבות, עדיפות השכבה תמיד מנצחת את הספציפיות של הבורר.
לדוגמה, לבורר .post a.link
יש רמת ספציפיות גבוהה יותר מאשר ל-.card a
. אם תנסו לעצב קישור בתוך כרטיס בפוסט, תגלו שהבורר הספציפי יותר יוחל.
השימוש ב-@layer
מאפשר לכם להגדיר בצורה מפורשת יותר את הספציפיות של הסגנון של כל אחד מהם, ולוודא שהסגנונות של הקישור לכרטיס גוברים על הסגנונות של הקישור לפוסט, גם אם הספציפיות המספרית עשויה להיות נמוכה יותר אם כל קובצי ה-CSS היו באותו מישור. הסיבה לכך היא עדיפות במורד הזרם. סגנונות בשכבות יוצרים 'מישורים' חדשים של אשכולות.
@layer
בפעולה
בדוגמה הזו מוצגת העוצמה של שכבות מדורגות באמצעות @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
תמיד יהיו ספציפיים יותר מכללי הסגנון בשכבת הטיפוגרפיה. הם לא יהיו יותר קישורים ירוקים, אלא אדומים או כחולים.
ארגון ייבוא
אפשר גם להשתמש ב-@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
אתם מגדירים את הסגנונות לא ישפיע על סדר השכבות, כי הוא כבר הוגדר במופע הראשון של שם השכבה. כך תוכלו להפסיק לדאוג לזה. עדיין אפשר להגדיר קבצים מיובאים לשכבות ספציפיות, אבל הסדר כבר נקבע.
שכבות והסלמת
נרחיב את התמונה ונראה איפה נעשה שימוש בשכבות בהקשר של המפלס הרחב יותר:
סדר הקדימות הוא:
- סוכן משתמש רגיל (העדיפות הנמוכה ביותר)
- משתמש מקומי @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
כדי לשנות את הצבע והיא לא חלה".
מידע נוסף על שכבות מדורגות
תוכלו גם להיעזר במקורות המידע הבאים כדי לקבל מידע נוסף על שכבות מדורגות: