सीएसएस प्रॉपर्टी appearance: base-select की मदद से, <select> एलिमेंट और उसके पिकर (::picker(select) के ज़रिए) को सामान्य एचटीएमएल एलिमेंट की तरह स्टाइल किया जा सकता है.
ग्रिड या फ़्लेक्सबॉक्स जैसी आधुनिक सीएसएस लेआउट तकनीकों के साथ, पारंपरिक स्टैक की गई वर्टिकल सूची से छुटकारा पाया जा सकता है. साथ ही, कस्टम जेएस के बिना बेहतर विज़ुअल अनुभव बनाया जा सकता है.
उदाहरण के लिए, विकल्पों को कार्ड के 2D ग्रिड के तौर पर स्टाइल करने के लिए, display: grid का इस्तेमाल किया जा सकता है.
यह कलर पिकर, इमोजी चुनने वाले टूल या प्रॉडक्ट के वैरिएंट के लिए सबसे सही है. इनमें लिस्ट के बजाय, विज़ुअल मेन्यू ज़्यादा असरदार होता है.
इन्हें कैसे लागू करें
1. बुनियादी स्टाइलिंग चालू करें
appearance: base-select को <select> एलिमेंट और उसके इंटरनल पिकर स्यूडो-एलिमेंट select::picker(select), दोनों पर लागू करें:
select.grid-picker {
&, &::picker(select) {
appearance: base-select;
}
}
2. पिकर कंटेनर को स्टाइल करना
select:open::picker(select) को टारगेट करें और display: grid (या display: flex) लागू करें.
कॉलम और गैप को उसी तरह तय करें जिस तरह किसी कंटेनर के लिए किया जाता है.
select.grid-picker:open::picker(select) {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1rem;
}
अहम जानकारी: :open ज़रूरी है. अगर आपने select::picker(select) को स्टाइल किया है, तो पिकर तब भी दिखेगा, जब select बंद हो!
3. विकल्पों को स्टाइल करना
<option> एलिमेंट को टारगेट करें, ताकि उन्हें ग्रिड आइटम या कार्ड के तौर पर स्टाइल किया जा सके.
इनमें इमेज, एसवीजी या जटिल लेआउट जोड़े जा सकते हैं.
/* Style options as grid cards */
.grid-picker option {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
/* padding, border-radius, background, etc. */
}
4. चुने गए विकल्प को स्टाइल करना
चुने गए विकल्प को स्टाइल करने के लिए, option:checked का इस्तेमाल करें. उदाहरण के लिए:
.grid-picker option:checked {
position: relative;
border: 2px solid var(--primary-color);
background-color: oklab(from var(--primary-color) l a b / 8%);
}
किसी भी यूज़र इंटरफ़ेस (यूआई) कंट्रोल की तरह, सिर्फ़ रंग से स्थिति की जानकारी न दें.साथ ही, कौनसा विकल्प चुना गया है, यह बताने के लिए कई विज़ुअल इंडिकेटर का इस्तेमाल करें. जैसे, रंग, बॉर्डर की मोटाई, सही का निशान.
5. (ज़रूरी नहीं) चुने गए विकल्प के सही के निशान को स्टाइल करें
डिफ़ॉल्ट रूप से, ब्राउज़र हर <option> के पहले चाइल्ड के तौर पर सही का निशान दिखाता है.
यह content: "✓" / "" के साथ ::before की तरह काम करता है. अगर लेखक ने कोई ::before दिया है, तो यह उससे पहले रेंडर होता है.
अगर यह विकल्प नहीं चुना जाता है, तो visibility: hidden की मदद से सही का निशान छिपा दिया जाता है.
::checkmark सूडो-एलिमेंट का इस्तेमाल करके, इसे स्टाइल किया जा सकता है. इसके अलावा, अगर आपको सिर्फ़ स्टाइल का इस्तेमाल करके चुने गए विकल्प को दिखाना है या कस्टम इंडिकेटर का इस्तेमाल करना है, तो इसे पूरी तरह से छिपाया जा सकता है.
उदाहरण के लिए, इसे विकल्प के सबसे ऊपर दाएं कोने में रखने के लिए, ऐसा कुछ किया जा सकता है:
select.grid-picker {
> option::checkmark {
/* Hide the checkmark for unselected options */
display: none;
}
> option:checked {
position: relative;
&::checkmark {
position: absolute;
inset-block-start: -.4em;
inset-inline-end: -.5em;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
min-inline-size: 1.6em;
aspect-ratio: 1;
padding-right: 0.12em;
padding-left: 0.05em;
border-radius: 50%;
background: var(--primary-color);
color: white;
font-size: 70%;
font-weight: bold;
}
}
}
सलाह: सही के निशान के आस-पास कोई कंटेनर (जैसे, सर्कल) बनाते समय, उसे थोड़ा ऊपर की ओर खिसकाएं (जैसा कि हमने यहां padding-bottom और padding-left के साथ किया है), ताकि वह ऑप्टिकल तौर पर बीच में दिखे.
इसके लिए, padding-inline-start या padding-block-end का इस्तेमाल न करें. ऐसा इसलिए, क्योंकि ये राइटिंग मोड के हिसाब से बदल जाएंगे. हालांकि, सही के निशान का आकार नहीं बदलता.
6. (ज़रूरी नहीं) चुने गए विकल्प के डिसप्ले को पसंद के मुताबिक बनाएं
डिफ़ॉल्ट रूप से, <select> चुने गए विकल्प का सिर्फ़ टेक्स्ट वाला वर्शन दिखाएगा.
चुनी गई वैल्यू के लिए रिच कॉन्टेंट दिखाने के लिए, <button> के अंदर <selectedcontent> का इस्तेमाल करें और/या चुने गए विकल्प को अलग तरीके से दिखाने के लिए (उदाहरण के लिए, कुछ जानकारी छिपाएं).
<selectedcontent> को उसके आस-पास <button> के बिना इस्तेमाल न करें, क्योंकि <selectedcontent> किसी भी अन्य कॉन्टेंट एलिमेंट की तरह, पिकर का हिस्सा बन जाएगा.
सबसे सही तरीके
- लेआउट के काम करने के तरीके की जांच करना.
appearance: base-selectको सेट करने से, डिफ़ॉल्ट ब्राउज़र का वह व्यवहार हट जाता है जिसके तहत, ब्राउज़र सबसे लंबे विकल्प की चौड़ाई के आधार पर, चुने गए विकल्प का साइज़ तय करता है. लेआउट शिफ़्ट रोकने के लिए, आपको तय चौड़ाई सेट करनी पड़ सकती है या फ़्लेक्स/ग्रिड कंस्ट्रेंट का इस्तेमाल करना पड़ सकता है. - पक्का करें कि आपके
<select>मेंnameएट्रिब्यूट और उससे जुड़ा<label>मौजूद हो. इससे यह पक्का होता है कि कस्टम यूज़र इंटरफ़ेस (यूआई) होने पर भी, कॉम्पोनेंट को स्क्रीन रीडर ऐक्सेस कर सकते हैं. साथ ही, यह स्टैंडर्ड फ़ॉर्म सबमिशन के साथ सही तरीके से काम करता है. - विकल्पों पर स्टैंडर्ड
valueएट्रिब्यूट का इस्तेमाल करें, ताकि यह पक्का किया जा सके कि फ़ॉर्म सबमिशन पहले की तरह ही काम करे.
सुलभता
नेटिव <select> सिर्फ़ अप/डाउन ऐरो वाले लीनियर नेविगेशन को हैंडल करता है. इसलिए, खुले हुए पिकर में लेफ़्ट/राइट ऐरो से कुछ नहीं होता. साथ ही, अप/डाउन ऐरो से आइटम को क्रम से नेविगेट किया जाता है, भले ही पंक्तियां और कॉलम कुछ भी हों.
ग्रिड के हिसाब से स्पेशल नेविगेशन लागू करने के लिए, keydown को इंटरसेप्ट किया जा सकता है.साथ ही, ऐरो बटन का इस्तेमाल किए जाने पर, दबाई गई दिशा में सबसे नज़दीकी विकल्प पर फ़ोकस किया जा सकता है. उदाहरण के लिए, getBoundingClientRect() का इस्तेमाल करके.
अगले/पिछले आइटम का पता लगाने के लिए, डीओएम के ऐसे तरीके इस्तेमाल करें जो असल ज्यामिति (जैसे, getBoundingClientRect()) पर काम करते हैं.इसके बजाय, grid-template-columns या grid-column जैसी सीएसएस स्ट्रिंग को पार्स न करें. ऐसा इसलिए, क्योंकि ये स्ट्रिंग मुश्किल ग्रिड, सबग्रिड, आरटीएल, और अन्य लेआउट के लिए गड़बड़ी वाली हो सकती हैं.
हालांकि, ज़रूरत से ज़्यादा इंजीनियरिंग न करें. इस लॉजिक को आसान बनाने के लिए, उन इनवैरिएंट का इस्तेमाल करें जो लेआउट के बारे में सही हैं.
ध्यान दें: यह सिर्फ़ कीबोर्ड नेविगेशन के लिए है. <select> और इसके ::picker() में अब भी उनकी डिफ़ॉल्ट भूमिकाएं (menu या listbox) मौजूद हैं. इन्हें बदला नहीं जा सकता. साथ ही, इनमें role="grid" वाला एलिमेंट शामिल करने की अनुमति नहीं है.
पिकर के अंदर role="grid" के साथ रैपर को नेस्ट करने से, यह काम करता है. हालांकि, यह मान्य नहीं है और इससे एटी उपयोगकर्ताओं को परेशानी हो सकती है.
कुछ मामलों में, विकल्पों को ग्रुप करने के लिए <optgroup> का इस्तेमाल करने से, role="grid" के बिना भी स्क्रीन रीडर का अच्छा उपयोगकर्ता अनुभव मिल सकता है.
ऐसा न होने पर, स्क्रीन रीडर इस्तेमाल करने वाले लोगों को बेहतर उपयोगकर्ता अनुभव देने के लिए, पॉपओवर एपीआई, ऐंकर पोज़िशनिंग, और role="grid" का इस्तेमाल करके, कस्टम समाधान पर स्विच करना पड़ सकता है.
फ़ॉलबैक रणनीति
कस्टमाइज़ किए जा सकने वाले <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.
}
});