नेटिव <select> एलिमेंट को स्टाइल करना पहले मुश्किल था. साथ ही, इसमें सिर्फ़ सादे टेक्स्ट के विकल्प शामिल किए जा सकते थे. appearance: base-select प्रॉपर्टी, <select> एलिमेंट के लिए, पसंद के मुताबिक बनाई जा सकने वाली स्थिति में ऑप्ट-इन करने का एक डिक्लेरेटिव और सिर्फ़ सीएसएस वाला तरीका उपलब्ध कराती है. इससे डेवलपर, <option> एलिमेंट में इमेज, एसवीजी, और जटिल लेआउट जैसे रिच एचटीएमएल कॉन्टेंट को शामिल कर सकते हैं. साथ ही, नेटिव कीबोर्ड सुलभता और फ़ॉर्म इंटिग्रेशन को बनाए रख सकते हैं. इस पैटर्न का इस्तेमाल करके, कस्टम तौर पर बनाए गए भारी-भरकम कॉम्पोनेंट को स्टैंडर्ड और नेटिव एलिमेंट से बदलें.
इन्हें कैसे लागू करें
Customizable Select API का इस्तेमाल करके, रिच मीडिया पिकर लागू करने के लिए:
- बेसिक स्टाइल के लिए ऑप्ट-इन करना:
::picker(select)सूडो-एलिमेंट का इस्तेमाल करके,appearance: base-selectको<select>एलिमेंट और उसके इंटरनल पिकर, दोनों पर लागू करें. इससे<select>में मौजूद कॉन्टेंट के लिए, ब्राउज़र का एचटीएमएल पार्सर बदल जाता है. - बटन का कॉन्टेंट तय करना: पिकर बंद होने पर क्या दिखेगा, यह तय करने के लिए
<select>के अंदर स्टैंडर्ड<button>और<selectedcontent>एलिमेंट का इस्तेमाल करें.<selectedcontent>एलिमेंट, चुने गए विकल्प के कॉन्टेंट को अपने-आप दिखाता है. अगर आपको बटन में, फ़िलहाल चुना गया रिच कॉन्टेंट दिखाना है, तो यह ज़रूरी है. - विकल्पों में रिच कॉन्टेंट का इस्तेमाल करना: अब
<option>टैग में इमेज, एसवीजी, और अन्य एचटीएमएल टैग जोड़े जा सकते हैं. इस एपीआई से पहले, ब्राउज़र<option>टैग से टैग हटा देता था और सिर्फ़ सादा टेक्स्ट रेंडर करता था. - पॉपओवर को स्टाइल करना:
::picker(select)स्यूडो-एलिमेंट को टारगेट करके, ड्रॉप-डाउन विकल्पों की सूची को स्टाइल करें. यह सबसे ऊपर वाली लेयर में रेंडर होता है. इसका मतलब है कि आपकोz-indexके साथ काम करने की ज़रूरत नहीं है. विकल्पों को ऐंकर पोज़िशनिंग एपीआई का इस्तेमाल करके, नेटिव तौर पर पोज़िशन किया जाता है.
कोड का उदाहरण: रिच रोल पिकर
<label for="role-picker">Select your role</label>
<select class="custom-select" name="role" id="role-picker">
<button>
<selectedcontent></selectedcontent> <!-- Mirrors the selected option's content automatically so you do not need JS to update the button -->
</button>
<!-- Define concise aria-label values on options whose mirrored rich content would otherwise read awkwardly as a concatenated string -->
<option value="frontend" aria-label="Frontend Developer">
<svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect>
</svg>
<div class="option-text">
<span class="option-title">Frontend Developer</span>
<span class="option-desc">React, Vue, CSS</span>
</div>
</option>
<option value="backend" aria-label="Backend Developer">
<svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<rect x="2" y="12" width="20" height="14" rx="2" ry="2"></rect>
</svg>
<div class="option-text">
<span class="option-title">Backend Developer</span>
<span class="option-desc">Node.js, Python</span>
</div>
</option>
</select>
select.custom-select,
select.custom-select::picker(select) {
appearance: base-select; /* MUST opt-in both the select and its picker to enable the customizable state, otherwise browser standard rendering applies */
}
select.custom-select {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
padding: 12px;
background-color: #1e293b;
border: 1px solid #334155;
border-radius: 8px;
color: #f1f5f9;
cursor: pointer;
}
select.custom-select::picker(select) {
background-color: #0f172a;
border: 1px solid #334155;
border-radius: 8px;
padding: 8px;
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.5);
width: anchor-size(width); /* Uses Anchor Positioning API to keep the dropdown precisely aligned to the button trigger width */
}
select.custom-select option {
display: flex;
align-items: center;
gap: 12px;
padding: 10px;
border-radius: 4px;
cursor: pointer;
}
select.custom-select option:hover {
background-color: #1e293b;
}
/* Remove standard OS checkmark for base-select */
select.custom-select option::before {
display: none;
}
/* MANDATORY: Provide multiple visual indicators (e.g., prominent background color and bold title font) to communicate the checked state cleanly */
select.custom-select option:checked {
background-color: #3b82f6;
color: #ffffff;
}
select.custom-select option:checked .option-title {
font-weight: 700;
}
रणनीति को लागू करने के तरीके और सबसे सही तरीके
- ज़रूर इस्तेमाल करें
appearance: base-selectजब आपको जटिल विकल्पों के लेआउट (आइकॉन, ब्यौरे, इमेज) की ज़रूरत हो. पहले ऐसा सिर्फ़ भारी JavaScript यूज़र इंटरफ़ेस (यूआई) फ़्रेमवर्क से ही किया जा सकता था. - अगर आपको परफ़ॉर्मेंस में कमी दिखती है, तो ऐड-हॉक एलिमेंट का इस्तेमाल न करें. ब्राउज़र, नेटिव कीबोर्ड फ़ोकस को नेटिव तरीके से मैनेज करता है.
- ज़रूर: टॉप-लेयर रेंडरिंग को ध्यान में रखें. पिकर, टॉप-लेयर में रेंडर होता है. इसका मतलब है कि यह पेज के कॉन्टेंट के रिलेटिव
z-indexको बदल देता है. - अगर बटन की स्थिति में, ब्यौरे जैसी अन्य जानकारी ज़्यादा जगह लेती है, तो उसे छिपाएं. इसके लिए,
.custom-select selectedcontent .option-desc { display: none; }को स्टाइल करें. - लेआउट के काम करने के तरीके की जांच करना.
appearance: base-selectको सेट करने से, डिफ़ॉल्ट ब्राउज़र का वह व्यवहार हट जाता है जिसके तहत, ब्राउज़र सबसे लंबे विकल्प की चौड़ाई के आधार पर, चुने गए विकल्प का साइज़ तय करता है. लेआउट शिफ़्ट रोकने के लिए, आपको तय चौड़ाई सेट करनी पड़ सकती है या फ़्लेक्स/ग्रिड कंस्ट्रेंट का इस्तेमाल करना पड़ सकता है. - पक्का करें कि आपके
<select>मेंnameएट्रिब्यूट और उससे जुड़ा<label>मौजूद हो. इससे यह पक्का होता है कि कस्टम यूज़र इंटरफ़ेस (यूआई) होने पर भी, कॉम्पोनेंट को स्क्रीन रीडर ऐक्सेस कर सकते हैं. साथ ही, यह स्टैंडर्ड फ़ॉर्म सबमिशन के साथ सही तरीके से काम करता है. - विकल्पों पर स्टैंडर्ड
valueएट्रिब्यूट का इस्तेमाल करें, ताकि यह पक्का किया जा सके कि फ़ॉर्म सबमिशन पहले की तरह ही काम करे.
फ़ॉलबैक रणनीतियां
कस्टमाइज़ किए जा सकने वाले <select> के लिए फ़ॉलबैक और ब्राउज़र की सुविधा
जिन ब्राउज़र पर अब तक appearance: base-select काम नहीं करता है उनके लिए, <select> एलिमेंट को स्टैंडर्ड ऑपरेटिंग सिस्टम के ड्रॉपडाउन में बदल दिया जाता है.
- बिना टेक्स्ट वाले कॉन्टेंट को अनदेखा किया जाता है: पुराने ब्राउज़र,
<option>टैग में मौजूद एचटीएमएल टैग (जैसे,<svg>या<div>) को हटा देते हैं और सिर्फ़ टेक्स्ट नोड को रेंडर करते हैं. पक्का करें कि<option>का टेक्स्ट कॉन्टेंट पढ़ने लायक हो और उसका कोई मतलब निकलता हो. - एचटीएमएल स्ट्रक्चर को मैनेज करना: स्टैंडर्ड पार्सर,
<select>के अंदर मौजूद<button>और<selectedcontent>टैग को अनदेखा कर सकते हैं या उन्हें अमान्य मान सकते हैं. अगर स्टैंडर्ड टेक्स्ट को पढ़ने लायक फ़ॉलबैक के तौर पर देखा जाता है, तो प्रोग्रेसिव एनहैंसमेंट के लिए, भारी-भरकम JavaScript पॉलीफ़िल की ज़रूरत नहीं होती.
document.addEventListener("DOMContentLoaded", () => {
// Check if browser supports base-select value
if (!CSS.supports("appearance", "base-select")) {
// Custom select overrides are not supported natively.
}
});