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

पब्लिश किए जाने की तारीख: 6 नवंबर, 2024

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

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

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

  • Chrome: 131.
  • Edge: इस्तेमाल नहीं किया जा सकता.
  • 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 का pseudo

ब्राउज़र में, <details> एलिमेंट को Shadow DOM का इस्तेमाल करके लागू किया जाता है. इसमें खास जानकारी के लिए एक <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 pseudo पर तब ही लागू करें, जब <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 (जिसे पहले 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 पर सेट किया जाता है. calc-size() का इस्तेमाल करके, height ऐनिमेशन के साथ दिखता है, क्योंकि इसमें कैलकुलेशन शामिल है.

::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 स्यूडो को ऐनिमेशन दिया जाता है.