<details> को स्टाइल करने के ज़्यादा विकल्प

पब्लिश किया गया: 6 नवंबर, 2024

Chrome 131 में, <details> और <summary> एलिमेंट के स्ट्रक्चर को स्टाइल करने के लिए, आपके पास ज़्यादा विकल्प हैं. अब इन एलिमेंट का इस्तेमाल, जानकारी ज़ाहिर करने वाले या अकॉर्डियन विजेट बनाते समय किया जा सकता है.

खास तौर पर, Chrome 131 में किए गए बदलावों की मदद से, इन एलिमेंट पर display प्रॉपर्टी का इस्तेमाल किया जा सकता है. साथ ही, बड़ा और छोटा होने वाले हिस्से को स्टाइल करने के लिए, ::details-content स्यूडो-एलिमेंट जोड़ा जा सकता है.

ब्राउज़र के इस्तेमाल से जुड़ी सहायता

  • Chrome: 131.
  • Edge: 131.
  • Firefox: यह सुविधा काम नहीं करती.
  • Safari: यह सुविधा काम नहीं करती.

<details> एलिमेंट पर display सेट करना

पहले, <details> एलिमेंट के डिसप्ले टाइप को नहीं बदला जा सकता था. इस पाबंदी को अब हटा दिया गया है. उदाहरण के लिए, अब <details> एलिमेंट पर ग्रिड या फ़्लेक्स लेआउट का इस्तेमाल किया जा सकता है.

नीचे दिए गए उदाहरण में, एक्सक्लूज़िव ऐकॉर्डियन में कई <details> एलिमेंट एक साथ रखे गए हैं. <details> एलिमेंट में से किसी एक को बड़ा करने पर, उसका कॉन्टेंट <summary> के बगल में दिखता है.

डेमो

रिकॉर्डिंग

Chrome 131 में https://codepen.io/web-dot-dev/pen/VwoBQjY की रिकॉर्डिंग

ऐसा करने के लिए, <details> एलिमेंट पर फ़्लेक्स लेआउट का इस्तेमाल करें. इसके लिए, यह सीएसएस इस्तेमाल करें:

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

grid जैसी अन्य डिसप्ले वैल्यू भी इस्तेमाल की जा सकती हैं.

display: inline का इस्तेमाल करने के बारे में जानकारी

display वैल्यू, inline हो सकती है. इससे अनचाहा नतीजा मिल सकता है. ऐसा इसलिए नहीं है, क्योंकि यह काम नहीं करता, बल्कि एचटीएमएल पार्सर की सीमाओं की वजह से ऐसा होता है.

किसी पैराग्राफ़ में <details> एलिमेंट डालने पर, एचटीएमएल पार्सर पहले खुले हुए पैराग्राफ़ को बंद कर देता है. इस बारे में एचटीएमएल स्टैंडर्ड के सेक्शन 13.2.6.4.7 में बताया गया है:

ऐसा स्टार्ट टैग जिसका टैग नाम इनमें से कोई एक हो: "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 एलिमेंट को बंद करें. टोकन के लिए एचटीएमएल एलिमेंट डालें.

इस वजह से, <details> ब्लॉक की दिशा में फ़्लो करता है. भले ही, आपने display: inline सेट किया हो.

उदाहरण के लिए, यह मार्कअप

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

पार्स करने के बाद यह हो जाता है:

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

इस डेमो में, Chrome DevTools का इस्तेमाल करके पार्स किए गए मार्कअप की जांच करके, खुद देखें.

ध्यान दें कि यह सिर्फ़ <p> के अंदर <details> को नेस्ट करने पर लागू होता है. <div> में मौजूद <details> पर display: inline का इस्तेमाल किया जा सकता है.

::details-content स्यूडो

ब्राउज़र में, <details> एलिमेंट को शैडो डीओएम का इस्तेमाल करके लागू किया जाता है. इसमें खास जानकारी के लिए एक <slot> (डिफ़ॉल्ट खास जानकारी वाले चाइल्ड एलिमेंट के साथ) और बाकी सभी कॉन्टेंट के लिए एक <slot> होता है. इसका मतलब है कि <summary> एलिमेंट को छोड़कर, <details> एलिमेंट के सभी चाइल्ड एलिमेंट.

<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] स्टेटस में हो.

डेमो

रिकॉर्डिंग

Chrome 131 में https://codepen.io/web-dot-dev/pen/oNKMEYv की रिकॉर्डिंग

UA स्टाइल शीट में, ::details-content का display टाइप block पर सेट है, जबकि पहले यह 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 कीवर्ड की ज़रूरत होगी.

पहले शेयर किए गए एक्सक्लूज़िव ऐकॉर्डियन डेमो में जोड़ा गया, नतीजा यह हुआ:

डेमो

रिकॉर्डिंग

Chrome 131 में https://codepen.io/web-dot-dev/pen/XWvBZNo की रिकॉर्डिंग

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> एलिमेंट का कॉन्टेंट बेहतर तरीके से ऐनिमेट होता है.

डेमो

रिकॉर्डिंग

Chrome 131 में https://codepen.io/web-dot-dev/pen/ExqpQZM की रिकॉर्डिंग

जिन ब्राउज़र में ::details-content काम नहीं करता उनमें भी यह कॉम्पोनेंट ठीक से काम करता है. वेबसाइट पर आने वाले लोगों को सिर्फ़ ऐनिमेशन नहीं दिखता.

फ़ीचर का पता लगाना

सीएसएस में ::details-content सूडो एलिमेंट के साथ काम करने की सुविधा का पता लगाने के लिए, नीचे दिए गए स्निपेट का इस्तेमाल करें.

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

इस पहचान का इस्तेमाल, यह पता लगाने के लिए भी किया जा सकता है कि आपके वेबसाइट पर आने वाले व्यक्ति का इस्तेमाल किया जा रहा ब्राउज़र, अतिरिक्त डिसप्ले वैल्यू के साथ काम करता है या नहीं.

सुलभता से जुड़ी बातें

::details-content स्यूडो-एलिमेंट और डिसप्ले टाइप बदलने की सुविधा के आने से, <details> एलिमेंट की सुलभता पर कोई असर नहीं पड़ता.

पहले की तरह ही, कम से कम Chromium वाले ब्राउज़र और एचटीएमएल स्टैंडर्ड के मुताबिक, <details> एलिमेंट को खोजा जा सकता है. साथ ही, जब ब्राउज़र, पेज में खोजने, ScrollToTextFragment, और एलिमेंट फ़्रैगमेंट नेविगेशन के जवाब में अपने छिपे हुए कॉन्टेंट पर स्क्रोल करने की कोशिश करता है, तो यह अपने-आप बड़ा हो जाता है. इसमें कोई बदलाव नहीं होता.

हालांकि, एक्सक्लूज़िव अकॉर्डियन का इस्तेमाल करने से पहले, यह देख लें कि यह उपयोगकर्ताओं के लिए मददगार है या नुकसान पहुंचाने वाला. एक्सक्लूज़िव ऐकॉर्डियन का इस्तेमाल करने पर, विज़ुअल स्पेस में कॉन्टेंट कम जगह लेता है. हालांकि, पूरी जानकारी पाने के लिए उपयोगकर्ताओं को कई आइटम खोलने पड़ सकते हैं. इससे उन उपयोगकर्ताओं को परेशानी हो सकती है जो एक ही समय पर कई आइटम देखना चाहते हैं.

मार्कर की स्टाइल कैसे तय करें?

फ़िलहाल, सूची मार्कर की स्टाइल को इंटरऑपरेबल नहीं किया जा सकता, क्योंकि इसके दो अलग-अलग तरीके हैं. पहला तरीका Gecko और (मौजूदा) Chromium का है और दूसरा तरीका WebKit का है. WebKit का तरीका पहले Chromium के साथ शेयर किया गया था.

जब यह सुविधा इंटरऑपरेबल हो जाएगी, तब हमारा मकसद आपको मार्कर को स्टाइल करने के तरीके पर बेहतर कंट्रोल देना है.

ज़्यादा डेमो

आखिर में, यहां कुछ और डेमो दिए गए हैं. ये सभी ::details-content का इस्तेमाल करते हैं.

UIKit अकॉर्डियन

डेमो

रिकॉर्डिंग

Chrome 131 में https://codepen.io/web-dot-dev/pen/rNXrJyQ की रिकॉर्डिंग

यह डेमो, UIKit Accordion के बाद बनाया गया है. यह कोड, पहले शेयर किए गए Material UI Accordion जैसा ही है.

ज़ाहिर की गई जानकारी वाला आधा खुला विजेट

डेमो

रिकॉर्डिंग

Chrome 131 में https://codepen.io/web-dot-dev/pen/PoMBQmW की रिकॉर्डिंग

इस डेमो में, ज़ाहिर की गई जानकारी वाला एक विजेट दिखाया गया है, जो कुछ हद तक खुला हुआ है. इसका कॉन्टेंट, स्क्रीन पर पहले से दिख रहा है. ऐसा करने के लिए, 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 */
}

स्टाइल करने में आसानी के लिए, कॉन्टेंट को रैपर डिव में रैप किया जाता है. रैपर डिव में padding जैसी लेआउट स्टाइल लागू की जाती हैं और ::details-content स्यूडो को ऐनिमेशन दिया जाता है.