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

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

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

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

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

  • Chrome: ‏ 131.
  • Edge: ‏ 131.
  • 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 UI. התוכן של כל רכיב <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 מקבל אנימציה.