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

אונה קראבץ
אונה קראבץ

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

הוספת שכבות 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 Project
מעיינים בפרויקט ב-Codepen.

שכבות והמפל

נחזור צעד אחורה ונראה איפה נעשה שימוש בשכבות בהקשר של המערך הרחב יותר:

איור של דירוג

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

  • 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) כדי לשנות את הצבע, והיא לא מיושמת".

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

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