החלה מותנית של CSS על סמך תמיכה בכלל At

תכונות אינטרנט: at-rule()‎

אפשר להשתמש ב-@supports at-rule(@<at-rule name>) {…} כדי להחיל כללים או הצהרות מסוימים של CSS באופן מותנה, רק אם הדפדפן תומך בכלל at-rule מסוים. הוא יכול להכיל כללים שלמים, או לשמש בשילוב עם קינון CSS כדי להחיל הצהרות מסוימות באופן מותנה.

.foo {
  background: var(--accent-color);

  @supports at-rule(@property) {
    background-image: var(--rainbow-gradient);
    animation: sliding-rainbow 1s linear infinite;
  }
}

אל תשתמשו ב-@supports at-rule() כדי להחיל באופן מותנה את כלל ה-at שזוהה, ולא שום דבר אחר.

/* BAD: CSS already ignores rules the browser doesn't understand, so this is unnecessary */
@supports at-rule(@starting-style) {
  @starting-style {
    /* ... */
  }
}

זיהוי תמיכה בכללי at-rule כש-@supports at-rule() לא מתאים

אם אי אפשר להשתמש ב-at-rule(), בגלל שהדפדפן לא תומך בזה או כי צריך זיהוי מעמיק יותר, אפשר להשתמש בהנחיות שבהמשך.

קודם כדאי לנסות מאפיינים, ערכים או סלקטורים

‫@supports כבר יכול לזהות מאפיינים, ערכים וסלקטורים (באמצעות @supports selector(...)). במקרים רבים, אפשר להשתמש בהם כדי לזהות תמיכה בתכונה בלי לבדוק את כלל ה-at עצמו.

לדוגמה, במקום @supports at-rule(@function) כדי לזהות תמיכה בפונקציות מותאמות אישית, אפשר להשתמש ב-@supports (color: --foo()).

במקרים אחרים, יכול להיות שיש מחלקות פסאודו או רכיבי פסאודו שזמינים רק כשכלל at-rule מסוים נתמך, ואפשר להשתמש בהם כדי לזהות תמיכה.

זיהוי סוגים של שאילתות בנוגע למאגר

הערך at-rule() מאפשר זיהוי של כללי at-rule רק לפי שם. הוא לא מאפשר זיהוי של תחביר או תיאורים אחרים. לדוגמה, הפעולה הבאה לא תעבוד:

@supports at-rule(@container style(--a: 1)) {
  /* ... */
}

בסוגים רבים של שאילתות מאגר, אפשר להשתמש ב-container-type עם ערך מתאים. למשל, @supports (container-type: scroll-state) לשאילתות של מצב גלילה או @supports (container-type: size)container-type: anchoredfor לשאילתות של anchored()‎.

עם זאת, אין container-type לשאילתות סגנון. חשוב: אל תנסו להשתמש ב-@supports (container-type: style) כדי לזהות תמיכה בשאילתות סגנון, כי זה לא יעבוד.

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

@container style(--a: 1) or (not (style(--a: 1))) {
  /* Rules here will only be applied if style queries are supported */
}

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

מאפיינים מותאמים אישית רשומים (@property)

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

/* Use a custom property to conditionally include the dash animation */
@property --progress-dash-animation {
  syntax: "*";
  inherits: false;
  initial-value: , progress-dash 3s ease-in-out infinite;
}

.spinner {
  /* The dash animation is only included if @property is supported */
  animation:
    progress-spin var(--_used-spinner-duration) linear infinite
    var(--progress-dash-animation, );
}

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

{# Testcase: https://codepen.io/leaverou/pen/KwWzpVr #}

@property --supports-atproperty {
    syntax: "*";
    inherits: false;
}

:root {
    --supports-atproperty: ;
}

body {
  /* The background is only applied if @property is supported */
    background: var(--supports-atproperty, green);
}

הערות:

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

שימוש ב-JavaScript כמוצא אחרון

כדי לבדוק כללי at-rule שלמים, צריך לבדוק אם יש ממשקים מסוימים ב-JavaScript. לדוגמה, אם globalThis.CSSFunctionRule מוגדר, אז @function נתמך.

אם אתם צריכים לבצע בדיקה מעמיקה יותר (למשל, עבור כללי prelude מסוימים, כללים בתצוגת עץ, מתארים), אתם יכולים להגדיר בדיקה ולראות איך היא נותחה:

const sheet = new CSSStyleSheet();
sheet.replaceSync(`
  @page {
    @top-left {
      content: "test";
    }
  }
`);
const SUPPORTS_PAGE_MARGINS = Boolean(sheet.cssRules[0]?.cssRules?.[0]);

חשוב:

  • כשמשתמשים ב-JS כדי לזהות תמיכה בתכונות CSS, אל תפעילו את הסגנונות מ-JS ישירות. במקום זאת, צריך להחיל מחלקה על רכיב הבסיס ולהסתעף ממנה ב-CSS.
  • חשוב לשים לב ששאילתות מאגר מנותחות גם אם ההקדמה לא מזוהה, ואין דרך לזהות תמיכה בסוגים מסוימים של שאילתות מאגר ממבנה CSSOM.
  • אל תשתמשו ב-CSS.registerProperty כדי לזהות תמיכה ב-@property, כי התמיכה שלו קצת יותר רחבה.

אסטרטגיות חלופיות

אלא אם זה במסגרת יעד התמיכה שלכם, השתמשו ב-@supports (at-rule()) רק כדי לזהות כללי at-rule שהתמיכה בהם מצומצמת יותר מהתכונה @supports (at-rule()) עצמה.

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

כדי לזהות תמיכה בתכונה @supports at-rule() עצמה, אפשר להשתמש בכלל at-rule שמובטח שיהיה קיים בכל הדפדפנים שתומכים ב-@supports at-rule(), כמו @supports at-rule(@media) { ... }.