דרג שכבות (כלל @layer
CSS) יהיו זמינות ב-Chromium 99, ב-Firefox 97 וב-Safari 15.4 בטא. הם מאפשרים שליטה מפורשת יותר בקובצי ה-CSS כדי למנוע התנגשויות בין סגנונות ספציפיים. היא שימושית במיוחד ל-codebase גדולים, למערכות עיצוב ולניהול סגנונות של צדדים שלישיים באפליקציות.
הוספת שכבות 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
הסגנונות לא משנה את סדר השכבות, כי הוא כבר נקבע במופע הראשון של שם השכבה. זה דבר אחד פחות לדאוג לו. עדיין תוכלו להגדיר קבצים מיובאים לשכבות ספציפיות, אבל הסדר שלהן כבר נקבע.
שכבות והמפל
נחזור צעד אחורה ונראה איפה נעשה שימוש בשכבות בהקשר של המערך הרחב יותר:
סדר הקדימות הוא:
- User Agent Standard (העדיפות הנמוכה ביותר)
- @layer של משתמש מקומי
- משתמש מקומי רגיל
- המחבר @layers
- מחבר רגיל
- מחבר !important
- המחבר @layer !important
- משתמש מקומי חשוב!
- User Agent !important** (הקדימות הגבוהה ביותר)
יכול להיות שתבחינו כאן שהסגנונות של @layer !important
הפוכים. במקום להיות פחות ספציפיים מסגנונות ללא שכבות (רגיל), יש להם עדיפות גבוהה יותר. הסיבה לכך היא האופן שבו !important
פועל בסולם: הוא שובר את הדירוג הרגיל בגיליונות הסגנונות והופך את הספציפיות הרגילה ברמת השכבה (הקדימות).
שכבות בתוך שכבות
ניתן גם להציב שכבות בתוך שכבות אחרות. הדוגמה הבאה לקוחה מהסבר על שכבות-על מאת מרים סוזאן:
@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 ללא שכבות. זו הייתה החלטה מכוונת כדי להקל עליכם להציג שכבות בצורה הגיונית יותר עם ה-codebase הקיים שלכם. שימוש בקובץ reset.css
, למשל, הוא נקודת התחלה טובה ותרחיש לדוגמה מצוין להעברת שכבות.
כלל 3: !important
הופך את הספציפיות של הדירוג
סגנונות של שכבות הם פחות ספציפיים מסגנונות ללא שכבות באופן כללי, אבל השימוש ב-!important
הופך את הפעולה הזו. בשכבה, הצהרות עם הכלל !important
הן יותר ספציפיות מסגנונות ללא שכבות.
במקרה כזה, הסגנונות של !important
הופכים את הספציפיות שלהם. התרשים שלמעלה מציג זאת כהקשר: ל-author @layers יש עדיפות נמוכה יותר מזו של המחבר הרגיל, שיש להן פחות קדימות מאשר למחבר !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
) כדי לשנות את הצבע, והיא לא מיושמת".
מידע נוסף על העברת שכבות
לקבלת מידע נוסף על העברת שכבות, אפשר לעיין במקורות המידע הבאים: