אפשרויות נוספות לעיצוב <details>

תאריך פרסום: 6 בנובמבר 2024

מגרסת Chrome 131 יש לכם יותר אפשרויות לעיצוב המבנה של הרכיבים <details> ו-<summary>. עכשיו אפשר להשתמש ברכיבים האלה כשיוצרים ווידג'טים של גילוי נאות או ווידג'טים מסוג אקורדיון.

באופן ספציפי, השינויים שהוצגו ב-Chrome 131 מאפשרים להשתמש במאפיין display ברכיבים האלה, ומוסיפים פסאודו-רכיב ::details-content כדי לעצב את החלק שמתרחב ונסגר.

תמיכה בדפדפנים

  • Chrome: ‏ 131.
  • Edge: לא נתמך.
  • Firefox: לא נתמך.
  • Safari: לא נתמך.

הגדרה של display ברכיב <details>

בעבר לא ניתן היה לשנות את סוג התצוגה של רכיב <details>. המגבלה הזו הוסר עכשיו, ועכשיו אפשר, למשל, להשתמש בפריסות של רשת או גמישות ברכיב <details>.

בדוגמה הבאה, האקורדיון הייחודי מורכב מכמה אלמנטים מסוג <details> שממוקמים זה לצד זה. כשמרחיבים את אחד מהרכיבים של <details>, התוכן שלו ממוקם לצד ה-<summary>.

הדגמה (דמו)

מתבצע תיעוד

הקלטה של https://codepen.io/web-dot-dev/pen/VwoBQjY ב-Chrome 131

הפעולה הזו מתבצעת באמצעות פריסה גמישה ברכיב <details>, באמצעות ה-CSS הבא:

details {
  display: flex;
  flex-direction: row;
}

ערכים אחרים של תצוגה מותרים גם כן, כמו grid.

הערה לגבי השימוש ב-display: inline

ערך של display שיכול להיות תוצאה לא צפויה הוא inline. לא בגלל שהיא לא פועלת, אלא בגלל מגבלות של מנתח ה-HTML.

כשמוסיפים רכיב <details> בתוך פסקה, המערכת לניתוח HTML נאלצת לסגור קודם את הפסקה הפתוחה, כפי שמוגדר בקטע 13.2.6.4.7 של תקן ה-HTML:

תג התחלה ששם התג שלו הוא אחד מהשמות הבאים: address,‏ article,‏ aside,‏ blockquote,‏ center,‏ details,‏ dialog,‏ dir,‏ div,‏ dl,‏ fieldset,‏ figcaption,‏ figure,‏ footer,‏ header,‏ hgroup,‏ main,‏ menu,‏ nav,‏ ol,‏ p,‏ search,‏ section,‏ summary,‏ ul

אם בסטאק של הרכיבים הפתוחים יש רכיב p ברמת הלחצן, סוגרים רכיב p. מוסיפים רכיב HTML לטוקן.

כתוצאה מכך, ה-<details> זורם בכיוון של הבלוק, ללא קשר להגדרה של display: inline.

לדוגמה, תגי העיצוב הבאים

<p>Hello <details>…</details> world</p>

המצב הזה הופך לאחר הניתוח:

<p>Hello </p><details>…</details> world<p></p>

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

שימו לב שהכלל הזה רלוונטי רק להטמעת <details> בתוך <p>. אפשר להשתמש ב-display: inline ב-<details> בתוך <div>.

הפסאודו ::details-content

בדפדפנים, הרכיב <details> מוטמע באמצעות Shadow DOM. הוא מכיל רכיב <slot> אחד לסיכום (עם רכיב צאצא של סיכום שמוגדר כברירת מחדל) ורכיב <slot> לכל התוכן הנותר, כלומר כל רכיבי הצאצא של רכיב <details> מלבד רכיב <summary>.

<details>
  ↳ #shadow-root (user-agent)
      <slot id="details-summary">
        <summary>Details</summary>
        <!-- The summary goes here -->
      </slot>
      <slot id="details-content">
        <!-- All content goes here -->
      </slot>
</details>

בנוסף לשימוש בסוגי תצוגה נוספים ב-<details>, עכשיו אפשר לטרגט את תא התוכן באמצעות רכיב הצירוף ::details-content. אפשר להשתמש בפסאודו-קלאס הזה כדי לעצב את המאגר שמקיף את התוכן של רכיב <details>.

details::details-content {
  border: 5px dashed hotpink;
}

כדי להחיל את הסגנון שהוגדר רק כאשר רכיב <details> נמצא במצב פתוח, מוסיפים אליו את הבורר [open].

[open]::details-content {
  border: 5px dashed hotpink;
}

מומלץ להחיל עיצוב על ::details-content רק כשהרכיב <details> נמצא במצב [open].

הדגמה (דמו)

מתבצע תיעוד

הקלטה של https://codepen.io/web-dot-dev/pen/oNKMEYv ב-Chrome 131

הסוג display של ::details-content מוגדר כ-block בגיליון הסגנונות של UA, בעוד שבעבר הוא היה display: contents. השינוי הזה עלול לפגוע בכם במקרים מסוימים, למשל בתוכן שפורסם תוך שימוש ב-height: 100%. אם זו בעיה, אפשר לעקוף את הבעיה על ידי הגדרת חזרה של סוג display לערך contents, למשל: details[open]::details-content { display: contents; }.

אנימציה של הפסואודו ::details-content

אפשר להוסיף אנימציה לתוכן של רכיב <details> בזמן שהוא מתרחב. בדוגמה הבאה, הרוחב משתנה באנימציה מ-0px ל-300px.

::details-content {
  transition: width 0.5s ease, content-visibility 0.5s ease allow-discrete;
  width: 0;
}

[open]::details-content {
  width: 300px;
}

בנוסף להעברת width, צריך להעביר גם את נכס content-visibility. הסיבה לכך היא שהערך שלו משתנה בין המצב הלא פתוח למצב הפתוח, כפי שמוגדר בגיליון הסגנונות של User-Agent. מכיוון שזהו נכס שאפשר להוסיף לו אנימציה באופן נפרד, צריך להשתמש במילת המפתח allow-discrete כדי שהאנימציה תפעל.

אם מוסיפים את הדמו הבלעדי של התצוגה האנכית, התוצאה היא:

הדגמה (דמו)

מתבצע תיעוד

הקלטה של https://codepen.io/web-dot-dev/pen/XWvBZNo ב-Chrome 131

אפשר גם להוסיף אנימציה ל-height. כדי ליצור אנימציה ל-height: auto, צריך להשתמש ב-interpolate-size או ב-calc-size(). בנוסף, כדי למנוע זליגת תוכן מתוך ::details-content, צריך להחיל עליו את overflow: clip.

::details-content {
    transition: height 0.5s ease, content-visibility 0.5s ease allow-discrete;
    height: 0;
    overflow: clip;
}

/* Browser supports interpolate-size */
@supports (interpolate-size: allow-keywords) {
    :root {
        interpolate-size: allow-keywords;
    }

    [open]::details-content {
        height: auto;
    }
}

/* Fallback for browsers with no interpolate-size support */
@supports not (interpolate-size: allow-keywords) {
    [open]::details-content {
        height: 150px;
        overflow-y: scroll; /* In case the contents should be taller than 150px */
    }
}

תוכלו לראות את הקוד בפעולה בהדגמה הבאה, בהשראת האקורדיון של ממשק המשתמש של Material. התוכן של כל רכיב <details> מוצג באנימציה יפה.

הדגמה (דמו)

מתבצע תיעוד

הקלטה של https://codepen.io/web-dot-dev/pen/ExqpQZM ב-Chrome 131

בדפדפנים ללא תמיכה ב-::details-content, הרכיב עדיין פועל בצורה תקינה. הדבר היחיד שהמבקרים לא יכולים לראות הוא האנימציה.

זיהוי תכונות

כדי לזהות תמיכה בפסאודו ::details-content ב-CSS, צריך להשתמש בקטע הקוד הבא.

@supports selector(::details-content) {
  
}

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

שיקולי נגישות

ההוספה של רכיב הסימון ::details-content והיכולת לשנות את סוג התצוגה לא משפיעים על הנגישות של רכיב <details>.

כמו בעבר, לפחות בדפדפנים המבוססים על Chromium ובהתאם לתקן HTML, הרכיב <details> ניתן לחיפוש ומתרחב באופן אוטומטי כשהדפדפן מנסה לגלול לתוכן המוסתר שלו בתגובה לחיפוש בדף, ScrollToTextFragment וניווט בין מקטעים של רכיבים. זה לא משתנה.

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

מה לגבי עיצוב הסמן?

נכון לעכשיו, סגנון הסמן של הרשימה לא תואם, כי יש שתי גישות שונות: אחת ב-Gecko וב-Chromium (הנוכחי), והשנייה ב-WebKit (ששותפה בעבר עם Chromium).

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

הדגמות נוספות

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

UIKit Accordion

הדגמה (דמו)

מתבצע תיעוד

הקלטה של https://codepen.io/web-dot-dev/pen/rNXrJyQ ב-Chrome 131

ההדגמה הזו נוצרה אחרי UIKit Accordion. הקוד הוא כמעט זהה לקוד של הפסנתר של Material UI ששיתפתם קודם.

ווידג'ט הגילוי הנאות פתוח חלקית

הדגמה (דמו)

מתבצע תיעוד

הקלטה של https://codepen.io/web-dot-dev/pen/PoMBQmW ב-Chrome 131

הדגמה הזו כוללת ווידג'ט של גילוי נאות שנפתח חלקית, והתוכן שלו כבר גלוי במסך. כדי להשיג זאת, השדה content-visibility מוגדר תמיד לערך visible. האנימציה של height מתבצעת באמצעות calc-size() כי יש מעורבות חישוב.

::details-content {
  content-visibility: visible; /* Make it always visible */
    
  transition: height 0.5s ease;
  height: 150px;
  overflow: clip;
}

[open]::details-content {
  height: calc-size(auto, size + 0.5rem); /* calc-size because we need to add a length */
}

כדי להקל על עיצוב התוכן, הוא עטוף ב-div של עטיפה. ה-div של העטיפה מקבל את סגנונות הפריסה, כמו padding, והסימול ::details-content מקבל אנימציה.