שמות 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 ברמת היקף 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
ברמה של root בצל.
הערה: ל-counter-reset
, ל-counter-set
ול-counter-increment
יש כללים שונים במקצת כי הם שמות משתמעים, ולהצהרה על מאפייני CSS יש קבוצת כללים מוגדרת ובדיקה היטב.
סיכום
החדשות הרעות הן שבבדיקה של קובץ ה-snapshot של מצב ה-interop הנוכחי בנוגע לשמות CSS ול-DOM בצל, החוויה לא עקבית ויש בה באגים. אף אחת מהתכונות שבדקנו כאן לא פועלת באופן עקבי בכל הדפדפנים בהתאם למפרט. החדשות הטובות הן שהפערים שצריך למלא כדי לשמור על עקביות בחוויה הם רשימה מוגבלת של באגים ובעיות במפרט. קדימה, נתקן את זה! בינתיים, הסקירה הכללית עשויה לעזור לך להתמודד עם חוסר העקביות שמתוארת במאמר הזה.