חפירה עמוקה יותר לתוך שאילתות בסגנון מיכל

צומת המקור: 1765194

רשמתי כמה מחשבות מוקדמות על שאילתות בסגנון מיכל זמן קצר אחורה. זה עדיין ימים מוקדמים. הם כבר מוגדרים ב מפרט מודול CSS Containment Level 1 (כרגע בסטטוס טיוטת העורך) אבל עדיין מתקיימים כמה דיונים יוצאי דופן.

הרעיון הבסיסי הוא שנוכל להגדיר מיכל ולאחר מכן ליישם סגנונות מותנים על צאצאיו בהתבסס על הסגנון המחושב שלו.

@container ?  {
  /* conditional styles */
}

הדוגמה הטובה ביותר שראיתי עד כה היא הסרת נטוי ממשהו כמו , , ו כאשר הם משמשים בהקשר שבו התוכן כבר נטוי:

em, i, q {
  font-style: italic; /* default UA behavior */
}

/* When the container's font-style is italic, remove italics from these elements. */
@container style(font-style: italic) {
  em, i, q {
    font-style: normal;
  }
}

זה הרעיון הכללי. אבל אם לא ידעתם את זה, מרים סוזן, שהיא עורכת של המפרט, שומרת על סט מתמשך ויסודי של הערות אישיות על שאילתות בסגנון מיכל שזמין לציבור. זה עודכן לפני כמה ימים וביליתי שם זמן מה בניסיון לעטוף את ראשי סביב היבטים יותר ניואנסים של שאילתות סגנון. זה דברים לא רשמיים, אבל חשבתי לרשום כמה דברים שבלטו לי. מי יודע? אולי זה דברים שבסופו של דבר נוכל לצפות לו!

כל אלמנט הוא מיכל בסגנון

אנחנו אפילו לא צריכים להקצות במפורש א container-name or container-type כדי להגדיר מיכל סגנון כי הכל הוא מיכל סגנון כברירת מחדל.

אז, אתה רואה את הדוגמה שלמעלה שמסירת נטוי? שימו לב שזה לא מזהה מיכל. זה קופץ ישר לשאילתה באמצעות ה style() פוּנקצִיָה. אז באיזה מיכל יש שאילתה? זה הולך להיות ה הורה ישיר של האלמנטים קבלת הסגנונות המיושמים. ואם לא זה, אז זה המכולה הקרובה הקרובה ביותר שיש לו עדיפות.

אני אוהב את זה. זה מאוד CSS-y עבור השאילתה לחפש התאמה, ואז להמשיך לבעבע עד שהיא מוצאת תנאי תואם.

למוח הקטן שלי היה קשה להבין מדוע אנו יכולים לברוח עם מיכל מרומז המבוסס על סגנונות, אבל לא כל כך כשאנחנו עוסקים בשאילתות מימדיות, כמו size ו inline-size. מרים מסבירה את זה יפה:

שאילתות מימדיות דורשות css הכלה על הגודל, הפריסה והסגנון של המיכל על מנת למנוע לולאות פריסה. בלימה היא דבר פולשני ליישום רחב, ולכן היה חשוב שלמחברים תהיה שליטה קפדנית על אילו אלמנטים הם (או שאינם) מיכלים בגודל.

לשאילתות המבוססות על סגנון אין את אותה מגבלה. כבר אין דרך ב-CSS שלסגנונות צאצאים תהיה השפעה על הסגנונות המחושבים של אב קדמון. אז לא נדרשת בלימה, ואין תופעות לוואי פולשניות או בלתי צפויות בביסוס אלמנט בתור מיכל שאילתה בסגנון.

(הדגש שלי)

הכל מסתכם בהשלכות - מהן אין כאלה, ככל שהכל הוא מיכל שאילתות בסגנון ישירות מהקופסה.

  • אם נמצא מיכל: התנאים נפתרו כנגד המיכל הזה.
  • אם מספר מיכלים תואמים: המיכל היחסי הקרוב ביותר מקבל עדיפות.
  • אם לא נמצאו התאמות: unknown חזר.

זה אותו דבר רוח "סולחת" כמו שאר ה-CSS.

מיכל יכול לתמוך בשאילתות מימדיות וגם בשאילתות סגנון

נניח שאנו רוצים להגדיר שאילתת סגנון ללא מפורש container-name:

@container style(font-style: italic) {
  em {
    font-style: normal;
  }
}

זה עובד בגלל כל האלמנטים הם מיכלים בסגנוןלא משנה container-type. זה מה שמאפשר לנו לבצע שאילתות סגנונות באופן מרומז ולהסתמך על ההתאמה הקרובה ביותר. וזה בסדר גמור שכן, שוב, אין תופעות לוואי שליליות בעת הקמת מיכלים בסגנון.

עלינו להשתמש במפורש container-type עבור שאילתות ממדי, אבל לא כל כך עבור שאילתות סגנון מכיוון שכל אלמנט הוא שאילתת סגנון. זה גם אומר שהמיכל הזה הוא גם סגנון ו שאילתת מימד:

.card-container {
  container: card / inline-size; /* implictly a style query container as well */
}

אי הכללת מיכל משאילתה

אולי אנחנו לא רוצים שמיכל ישתתף בתהליך ההתאמה. שם אולי אפשר להגדיר container-type: none על אלמנט.

.some-element {
  container-type: none;
}

מיכלי שאילתות בסגנון מפורש מציעים שליטה רבה יותר במה שנשאל

אם, נניח, היינו כותבים שאילתת סגנון עבור padding , אין דרך מהימנה לקבוע את הגורם המכיל המתאים ביותר, בין אם אנו עובדים עם גורם מכיל בעל שם מפורש או עם האב הישיר הקרוב ביותר. זה בגלל padding אינו נכס בירושה.

אז, במקרים אלה, אנחנו צריכים להשתמש container-name כדי ליידע את הדפדפן במפורש מאילו מכולות הם יכולים למשוך. אנחנו יכולים אפילו לתת למיכל שמות מפורשים מרובים כדי שיתאים לתנאים נוספים:

.card {
  container-name: card layout theme;
}

אה, ו container-name מקבל כל מספר אופציונלי ו לשימוש חוזר שמות למיכל! זה אפילו יותר גמישות כשזה מגיע לעזור לדפדפן לבחור בעת חיפוש התאמות.

.theme {
  container-name: theme;
}
.grid {
  container-name: layout;
}
.card {
  container-name: card layout theme;
}

אני סוג של תוהה אם זה עשוי להיחשב גם כ"נפילה" במקרה שמיכל אחד עובר על פניו.

ניתן לשלב שאילתות סגנון

אל האני or ו and מפעילים מאפשרים לנו לשלב בין דברים כדי לשמור על יבש:

@container bubble style(--arrow-position: start start) or style(--arrow-position: end start) {
  .bubble::after {
    border-block-end-color: inherit;
    inset-block-end: 100%;
  }
}

/* is the same as... */
@container bubble style(--arrow-position: start start) {
  /* etc. */
}
@container bubble style(--arrow-position: end start) {
  /* etc. */
}

החלפת סגנונות

יש חפיפה קטנה בין שאילתות בסגנון קונטיינר לבין העבודה נעשית להגדרת א toggle() פונקציה. לדוגמה, אנו יכולים לעבור בין שניים font-style ערכים, נניח italic ו normal:

em, i, q {
  font-style: italic;
}

@container style(font-style: italic) {
  em, i, q {
    font-style: normal;
  }
}

מגניב. אבל ההצעה ל-CSS Toggles מציעה כי toggle() הפונקציה תהיה גישה פשוטה יותר:

em, i, q {
  font-style: toggle(italic, normal);
}

אבל כל דבר מעבר לסוג זה של מקרה שימוש בינארי הוא היכן toggle() פחות מתאים. עם זאת, שאילתות סגנון מומלצות. מרים מזהה שלושה מקרים שבהם שאילתות סגנון מתאימות יותר מא toggle():

/* When font-style is italic, apply background color. */
/* Toggles can only handle one property at a time. */
@container style(font-style: italic) {
  em, i, q {
    background: lightpink;
  }
}

/* When font-style is italic and --color-mode equals light */
/* Toggles can only evaluate one condition at a time */
@container style((font-style: italic) and (--color-mode: light)) {
  em, i, q {
    background: lightpink;
  }
}

/* Apply the same query condition to multiple properties */
/* Toggles have to set each one individually as separate toggles */
@container style(font-style: italic) {
  em, i, q {
    /* clipped gradient text */
    background: var(--feature-gradient);
    background-clip: text;
    box-decoration-break: clone;
    color: transparent;
    text-shadow: none;
  }
}

שאילתות סגנון פותרות את "הפריצה להחלפת נכס מותאם אישית"

שים לב ששאילתות סגנון הן פתרון פורמלי עבור "טריק להחלפת נכס מותאם אישית של CSS". שם, אנו מגדירים מאפיין מותאם אישית ריק (--foo: ;) והשתמש בשיטת החזרה מופרדת בפסיקים כדי "להפעיל ולכבות" מאפיינים כאשר מאפיין מותאם אישית מוגדר לערך אמיתי.

button {
  --is-raised: ; /* off by default */
  
  border: 1px solid var(--is-raised, rgb(0 0 0 / 0.1));
  box-shadow: var(
    --is-raised,
    0 1px hsl(0 0% 100% / 0.8) inset,
    0 0.1em 0.1em -0.1em rgb(0 0 0 / 0.2)
  );
  text-shadow: var(--is-raised, 0 -1px 1px rgb(0 0 0 / 0.3));
}

button:active {
  box-shadow: var(--is-raised, 0 1px 0.2em black inset);
}

#foo {
  --is-raised: initial; /* turned on, all fallbacks take effect. */
}

זה סופר מגניב, גם הרבה עבודה ששאילתות מיכל בסגנון הופכות לטריוויאלית.

שאילתות סגנון ותוכן שנוצר ב-CSS

עבור תוכן שנוצר על ידי ה content רכוש של ::before ו ::after פסאודו-אלמנטים, המיכל התואם הוא האלמנט שעליו נוצר התוכן.

.bubble {
  --arrow-position: end end;
  container: bubble;
  border: medium solid green;
  position: relative;
}

.bubble::after {
  content: "";
  border: 1em solid transparent;
  position: absolute;
}

@container bubble style(--arrow-position: end end) {
  .bubble::after {
    border-block-start-color: inherit;
    inset-block-start: 100%;
    inset-inline-end: 1em;
  }
}

שאילתות סגנון ורכיבי אינטרנט

אנחנו יכולים להגדיר רכיב אינטרנט כמיכל ולשאול אותו לפי סגנון. ראשית, יש לנו את של הרכיב:


  
… …

לאחר מכן אנו משתמשים ב- :host פסאודו-אלמנט כמיכל להגדרת א container-name, container-type, וכמה תכונות ברמה גבוהה עליו:

:host {
  container: media-host / inline-size;
  --media-location: before;
  --media-style: square;
  --theme: light;
}

אלמנטים בתוך יכול לשאול את הפרמטרים של אֵלֵמֶנט:

@container media-host style(--media-style: round) {
  [part='img'] {
    border-radius: 100%;
  }
}

מה הלאה?

שוב, כל הדברים שרשמתי כאן מבוססים על ההערות של מרים, וההערות הללו אינן תחליף למפרט הרשמי. אבל הם מהווים אינדיקציה למה שנדון והיכן דברים יכולים לנחות בעתיד. אני מעריך שמרים קישרה קומץ של דיונים יוצאי דופן שעדיין מתקיימים שנוכל לעקוב אחריהם כדי להתעדכן בעניינים:

בול זמן:

עוד מ טריקים של CSS