שמות CSS שהוגדרו על ידי המחבר ו-DOM בצל אמורים לפעול יחד. עם זאת, הדפדפנים לא תואמים למפרט, ולפעמים גם לא זה לזה, וכל שם CSS לא עקבי בדרך שונה במקצת.
במאמר הזה מתועד הסטטוס הנוכחי של האופן שבו שמות CSS שהוגדרו על ידי המחבר מתנהגים בהיקפי צל, בתקווה שהוא ישמש כמדריך לשיפור יכולת הפעולה ההדדית בעתיד הקרוב.
מהם שמות CSS שהוגדרו על ידי המחבר?
שמות CSS שהוגדרו על ידי המחבר הם מנגנון תחביר CSS ישן יחסית, שהוצג במקור לכלל @keyframes
, שמגדיר <keyframe-name>
בתור מזהה מותאם אישית או מחרוזת. המטרה של המושג הזה היא להצהיר על משהו בחלק אחד של גיליון סגנונות, ולהפנות אליו בחלק אחר.
/* "fade-in" is a CSS name, representing a set of keyframes */
@keyframes fade-in {
from { opacity: 0 };
to { opacity: 1 }
}
.card {
/* "fade-in" is a reference to the above keyframes */
animation-name: fade-in;
}
תכונות CSS אחרות שמשתמשות בשמות CSS הן גופנים, הצהרות על מאפיינים, שאילתות של מאגרים, ובשנים האחרונות גם מעברים בין תצוגות, מיקום של עוגנים ואנימציות שמבוססות על גלילה. הטבלה הבאה היא לא מקיפה, אבל היא כוללת שמות שהמצב שלהם נבדק ב-Chrome.
תכונה | הצהרת שם | הפניה לשם |
---|---|---|
תמונות מפתח (keyframes) | @keyframes |
animation-name |
גופנים | @font-face { }
@font-palette-values |
font-family
font-palette |
הצהרות על נכסים | @property כל הצהרה על נכס מותאם אישית לא רשום |
var() |
הצגת המעברים | view-transition-name
view-transition-class |
::view-transition-* רכיבי פסאודו |
מיקום של מודעת עוגן | anchor-name |
position-anchor |
אנימציה שמבוססת על גלילה | view-timeline-name
scroll-timeline-name |
animation-timeline |
סגנונות רשימה | @counter-style |
list-style |
מונים | counter-reset
counter-set
counter-increment |
|
שאילתות בקונטיינרים | container-name |
@container |
דף | page |
@page |
כפי שאפשר לראות בטבלה, לשם של שירות CSS בדרך כלל יש הפניה תואמת לשירות ה-CSS. לדוגמה, animation-name
הוא הפניה לשם @keyframes
. שמות ב-CSS שונים משמות שמוגדרים ב-DOM, כמו מאפיינים ושמות תגים, כי הם מוצהרים ולאחר מכן מתבצעת הפניה אליהם בהקשר של סגנונות עימוד.
הקשר בין שמות ל-Shadow DOM
שמות CSS נועדו ליצור קשרים בין חלקים שונים של מסמך או של גיליון סגנונות, אבל Shadow DOM נועד לעשות את ההפך. הוא עוטף את היחסים כדי שלא יהיו דליפות בין רכיבי אינטרנט שאמורים להיות להם מרחבי שמות משלהם.
שילוב השמות ב-CSS עם DOM בצל אמור לספק חוויה של כתיבת רכיבי אינטרנט שמאפשרת ביטוי גמיש, אבל עם הגבלות מספיקות כדי לשמור על יציבות.
זה נשמע טוב בתיאוריה. בפועל, הדפדפנים לא עקביים בדרך שבה שמות ה-CSS פועלים יחד עם ה-Shadow DOM, גם בין תכונות באותו דפדפן, גם בין דפדפנים וגם בין התכונות לבין המפרט.
איך השמות וה-DOM בצל צריכים לפעול יחד
כדי להבין את הבעיה, כדאי להבין איך החלקים האלה של CSS אמורים לפעול יחד בתיאוריה.
הכלל הכללי
הכלל הכללי לגבי האופן שבו שמות CSS מתנהגים בעצים מוצלים מוגדר במפרט של CSS Scoping ברמה 1. לסיכום: שם CSS הוא גלובלי בהיקף שבו הוא מוגדר, כלומר אפשר לגשת אליו מעצי צל של צאצאים, אבל לא מעצי צל של אחים או של אבות. חשוב לשים לב שהמצב הזה שונה משמות בפלטפורמת האינטרנט, כמו מזהי רכיבים, שמקובצים באותו היקף עץ.
החרגה לכלל: @property
בניגוד לשמות אחרים של CSS, מאפייני CSS לא עטופים ב-shadow DOM.
במקום זאת, הם משמשים להעברת פרמטרים בין עצי צל שונים.
לכן, התיאור @property
הוא מיוחד: הוא אמור לפעול כמו הצהרת סוג ברמת המסמך שמגדירה את האופן שבו פועל מאפיין ספציפי בעל שם. מאחר שהמאפיינים צריכים להתאים בין עצי הצללים, אי-התאמה בהצהרות על המאפיינים תיצור תוצאות בלתי צפויות. לכן, ההצהרות על @property
מצוינות כשטוחות וניתנות לפתרון לפי סדר המסמך.
איך הכלל אמור לפעול עם ::part
חלקי צל חושפים אלמנט בתוך עץ צל לעץ ההורה שלו. כך עץ ההורה יכול לגשת לאלמנט הזה וגם להחיל עליו סגנון באמצעות האלמנט ::part
.
מכיוון ש-::part
מאפשר לשני היקפי עץ לעצב את אותו רכיב, מצוין הסדר הבא של מפל:
- קודם כל, בודקים את הסגנון בהקשר של ההצללה. זהו הסגנון 'ברירת המחדל' של החלק.
- לאחר מכן מחילים את הסגנון החיצוני כפי שמוגדר ב-
::part
. זהו הסגנון 'המותאם אישית' של החלק. - לאחר מכן, מחילים כל סגנון פנימי שמוגדר יחד עם
!important
. כך אפשר להצהיר על רכיב מותאם אישית שמאפיין מסוים של חלק מסוים לא ניתן להתאמה אישית באמצעות::part
.
פירוש הדבר הוא שאי אפשר להפנות לשמות מתוך DOM בצל מ-::part
, כי ::part
הוא סגנון ברמת המארח ולא ברמת הצל. לדוגמה:
// inside the shadow DOM:
@keyframes fade-in {
from { opacity: 0}
}
// This shouldn't work!
// The host style shouldn't know the name "fade-in"
::part(slider) {
animation-name: fade-in;
}
איך הכלל אמור לפעול עם סגנונות בקוד
בניגוד ל-::part
, סגנונות מוטבעים עם המאפיין style
, או סגנונות שמוגדרים באופן פרוגרמטי באמצעות סקריפט, מוגדרים ברמת ההיקף של הרכיב. הסיבה לכך היא שכדי להחיל סגנון על אלמנט צריך גישה למזהה של האלמנט, וכך גם לשורש הצל עצמו.
איך שמות CSS ו-DOM בצל פועלים יחד במציאות
הכללים הקודמים מוגדרים היטב ועקביים, אבל ההטמעות הנוכחיות לא תמיד משקפות זאת.
בפועל, @property
פועל בצורה שונה מהמפרט באופן עקבי בכל הדפדפנים, וברוב התכונות האחרות יש באגים פתוחים (חלק מהן עדיין לא פורסמו, כך שיש זמן לתקן אותן).
כדי לבדוק ולהדגים איך התכונות האלה פועלות בפועל, יצרנו את הדף הבא: https://css-names-in-the-shadow.glitch.me/. בדף הזה יש כמה iframes, שכל אחד מהם מתמקד באחת מהתכונות ובוחן שישה תרחישים:
- הפניה חיצונית לשם חיצוני: אין DOM בצל מעורב, זה אמור לפעול.
- הפניה חיצונית לשם פנימי: הפעולה הזו לא אמורה לפעול, כי זה אומר שהשם שהוגדר בהקשר הצל הדלף.
- הפניה פנימית לשם חיצוני: הפניה כזו אמורה לפעול, כי שמות ברמת העץ עוברים בירושה לשורשי צל.
- הפניה פנימית לשם פנימי: הפניה כזו אמורה לפעול, כי השם של ההפניה נמצא באותו היקף.
::part
הפניה לשם החיצוני: הפעולה הזו אמורה לפעול, כי גם::part
וגם השם מוצהרים באותו היקף.::part
הפניה לשם פנימי: הפעולה הזו לא אמורה לפעול, כי ההיקף החיצוני לא אמור לקבל מידע על שמות שהוגדרו בתוך DOM הצל.
@keyframes
כפי שמוגדר במפרט, אפשר להפנות לשמות של תמונות מפתח מתוך שורש צל, כל עוד כלל at-rule @keyframes
נמצא בהיקף של אב קדמון. בפועל, אף דפדפן לא מטמיע את ההתנהגות הזו, וניתן להפנות להגדרות של נקודות המפתח רק בהיקף שבו הן מוגדרות. בעיה מס' 10540
@property
כפי שמוגדר במפרט, כל הצהרה על @property
תהיה שטוחה בהיקף המסמך. עם זאת, נכון לעכשיו, בכל הדפדפנים אפשר להצהיר על @property
רק ברמת המסמך, והצהרות על @property
בשורשי צללים מתעלמות.
ראו בעיה 10541.
באגים ספציפיים לדפדפן
התכונות האחרות לא מציגות התנהגות עקבית בדפדפנים השונים:
@font-face
מוצג ברמת הבסיס (root) ב-Safari.- ב-Chromium אסור לרשת כללים של
anchor-name
ברמה של root בצל - ההיקף של
scroll-timeline-name
ו-view-timeline-name
לא נכון ב-::part
(וגם ב-Chromium). - אף דפדפן לא מאפשר להצהיר על
@font-palette-values
בשורשי צל. - אפשר להגדיר את
view-transition-class
בתוך root בצל (המעבר עצמו נמצא מחוץ ל-root בצל). - ב-Firefox, ל-
::part
יש גישה לשמות של צללים פנימיים (שאילתות של מאגרים, פריימים מרכזיים). - הדפדפנים Firefox ו-Safari לא מכבדים את
@counter-style
ברמה הבסיסית.
שימו לב של-counter-reset
, counter-set
ו-counter-increment
יש כללים שונים במקצת, כי הם שמות משתמעים, ולהצהרה על מאפייני CSS יש קבוצת כללים מוגדרת ובדיקה היטב.
סיכום
החדשות הרעות הן שבבדיקה של קובץ ה-snapshot של מצב ה-interop הנוכחי בנוגע לשמות CSS ול-DOM בצל, החוויה לא עקבית ויש בה באגים. אף אחת מהתכונות שבדקנו כאן לא פועלת באופן עקבי בכל הדפדפנים בהתאם למפרט. החדשות הטובות הן שהפערים שצריך למלא כדי לשמור על עקביות בחוויה הם רשימה מוגבלת של באגים ובעיות במפרט. קדימה, נתקן את זה! בינתיים, אנחנו מקווים שהסקירה הכללית הזו תעזור לכם להתמודד עם חוסר העקביות שמתואר במאמר הזה.