अगली-पीढ़ी की वेब स्टाइलिंग

आधुनिक सीएसएस की कुछ दिलचस्प सुविधाओं के बारे में अप-टू-डेट रहें.

इस समय सीएसएस में कई कई रोमांचक चीज़ें हो रही हैं और इनमें से कई चीज़ें पहले से ही आज के ब्राउज़र में काम कर रही हैं! सीडीएस 2019 में हमारी बातचीत को यहां देखा जा सकता है. इसमें हमने कई नई और आने वाली सुविधाओं के बारे में बताया है. हमें लगता है कि इन पर ध्यान दिया जाना चाहिए.

इस पोस्ट में उन सुविधाओं के बारे में बताया गया है जिनका इस्तेमाल फ़िलहाल किया जा सकता है. इसलिए, Houdini जैसी आने वाली सुविधाओं के बारे में ज़्यादा जानने के लिए, ज़रूर बातचीत देखें. CSS@CDS पेज पर, हमने जिन सुविधाओं के बारे में बताया है उनके डेमो भी देखे जा सकते हैं.

कॉन्टेंट

स्क्रोल स्नैप

स्क्रोल स्नैप की मदद से, उपयोगकर्ता के वर्टिकल, हॉरिज़ॉन्टल या दोनों तरह से स्क्रोल करने पर, स्नैप पॉइंट तय किए जा सकते हैं. यह बिल्ट-इन स्क्रोल इनर्शिया और डिसेलरेशन की सुविधा देता है. साथ ही, इसका टच चालू है.

यह सैंपल कोड, <section> एलिमेंट में हॉरिज़ॉन्टल स्क्रोलिंग सेट अप करता है. इसमें स्नैप पॉइंट, चाइल्ड <picture> एलिमेंट की बाईं ओर अलाइन किए जाते हैं:

section {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
}

section > picture {
  scroll-snap-align: start;
}

यह इस तरह से काम करता है:

  • पैरंट <section> एलिमेंट पर,
    • हॉरिज़ॉन्टल स्क्रोलिंग की अनुमति देने के लिए, overflow-x को auto पर सेट किया गया है.
    • overscroll-behavior-x को contain पर सेट किया जाता है, ताकि जब उपयोगकर्ता <section> एलिमेंट के स्क्रोल एरिया की सीमाओं तक पहुंच जाए, तो किसी भी पैरंट एलिमेंट को स्क्रोल न किया जा सके. (स्नैप करने के लिए, ऐसा करना ज़रूरी नहीं है, लेकिन आम तौर पर ऐसा करना अच्छा रहता है.)
    • हॉरिज़ॉन्टल रूप से स्नैप करने के लिए scroll-snap-type को x पर और mandatory पर सेट किया गया है, ताकि व्यूपोर्ट हमेशा सबसे नज़दीकी स्नैप पॉइंट पर स्नैप हो जाए.
  • चाइल्ड <picture> एलिमेंट पर, scroll-snap-align को शुरू करने के लिए सेट किया गया है. इससे हर तस्वीर की बाईं ओर स्नैप पॉइंट सेट हो जाते हैं. ऐसा तब होता है, जब direction को ltr पर सेट किया गया हो.

यहां इसका लाइव डेमो दिया गया है:

वर्टिकल स्क्रोल स्नैप और मैट्रिक्स स्क्रोल स्नैप के डेमो भी देखे जा सकते हैं.

:focus-within

:focus-within, सुलभता से जुड़ी एक पुरानी समस्या को हल करता है: कई मामलों में, किसी चाइल्ड एलिमेंट पर फ़ोकस करने से पैरंट एलिमेंट के प्रज़ेंटेशन पर असर पड़ता है, ताकि सहायक टेक्नोलॉजी का इस्तेमाल करने वाले लोग यूज़र इंटरफ़ेस को ऐक्सेस कर सकें.

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

:focus-within, ब्राउज़र को बताता है कि किसी खास एलिमेंट के किसी चाइल्ड एलिमेंट पर फ़ोकस होने पर, स्टाइल लागू करें. मेन्यू के उदाहरण पर वापस आकर, मेन्यू एलिमेंट पर :focus-within सेट करके, यह पक्का किया जा सकता है कि मेन्यू आइटम पर फ़ोकस होने पर, यह दिखता रहे:

.menu:focus-within {
  display: block;
  opacity: 1;
  visibility: visible;
}

फ़ोकस और फ़ोकस-इन के बीच के व्यवहार में अंतर दिखाने वाला इलस्ट्रेशन.

नीचे दिए गए डेमो में, फ़ोकस किए जा सकने वाले एलिमेंट पर टैब करके देखें. आपको पता चलेगा कि मेन्यू आइटम पर फ़ोकस करने पर, मेन्यू दिखते रहते हैं:

मीडिया क्वेरी का लेवल 5

नई मीडिया क्वेरी की मदद से, उपयोगकर्ता के डिवाइस की प्राथमिकताओं के आधार पर, अपने ऐप्लिकेशन के उपयोगकर्ता अनुभव में बदलाव किया जा सकता है. आम तौर पर, ब्राउज़र सिस्टम-लेवल की प्राथमिकताओं के लिए प्रॉक्सी के तौर पर काम करता है. हम अपनी सीएसएस में, मीडिया क्वेरी के prefers-* ग्रुप का इस्तेमाल करके इन प्राथमिकताओं का जवाब दे सकते हैं:

सिस्टम-लेवल पर उपयोगकर्ता की प्राथमिकताओं का अनुमान लगाने वाली मीडिया क्वेरी दिखाने वाला डायग्राम.

यहां कुछ नई क्वेरी दी गई हैं. हमें लगता है कि डेवलपर इनके बारे में सबसे ज़्यादा उत्साहित होंगे:

ये क्वेरी, सुलभता के लिए काफ़ी मददगार हैं. उदाहरण के लिए, पहले हमारे पास यह जानने का कोई तरीका नहीं था कि किसी उपयोगकर्ता ने अपने ओएस को हाई-कंट्रास्ट मोड पर सेट किया है या नहीं. अगर आपको किसी ऐसे वेब ऐप्लिकेशन के लिए हाई-कंट्रास्ट मोड उपलब्ध कराना है जो आपके ब्रैंड के लिए सही है, तो आपको उपयोगकर्ताओं से उसे अपने ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) से चुनने के लिए कहना होगा. अब prefers-contrast का इस्तेमाल करके, ओएस से हाई-कंट्रास्ट सेटिंग का पता लगाया जा सकता है.

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

यह एडम के लिए ज़रूरी है कि "कम मोशन" को "कोई मोशन नहीं" के तौर पर लागू न किया जाए. उपयोगकर्ता का मतलब है कि उन्हें कम मोशन चाहिए, न कि उन्हें कोई ऐनिमेशन नहीं चाहिए. उनका कहना है कि कम मोशन का मतलब है कि कोई मोशन नहीं है. यहां एक उदाहरण दिया गया है, जिसमें उपयोगकर्ता की पसंद के मुताबिक कम मोशन के लिए क्रॉसफ़ेड ऐनिमेशन का इस्तेमाल किया गया है:

लॉजिकल प्रॉपर्टी

लॉजिकल प्रॉपर्टी, एक ऐसी समस्या को हल करती हैं जो अंतरराष्ट्रीय स्तर पर उपलब्ध कराने के लिए, ज़्यादा से ज़्यादा डेवलपर की कोशिशों की वजह से सामने आई है. margin और padding जैसी कई लेआउट प्रॉपर्टी, ऐसी भाषा के हिसाब से काम करती हैं जिसे ऊपर से नीचे और बाएं से दाएं पढ़ा जाता है.

पारंपरिक सीएसएस लेआउट प्रॉपर्टी दिखाने वाला डायग्राम.

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

लॉजिकल प्रॉपर्टी की मदद से, अनुवाद और लिखने के मोड में लेआउट को पूरी तरह से बनाए रखा जा सकता है. वे कॉन्टेंट के क्रम के हिसाब से डाइनैमिक तौर पर अपडेट होते हैं, न कि जगह के हिसाब से. लॉजिकल प्रॉपर्टी में, हर एलिमेंट के दो डाइमेंशन होते हैं:

  • ब्लॉक डाइमेंशन, लाइन में टेक्स्ट के फ़्लो के लंबवत होता है. (अंग्रेज़ी में, block-size और height एक ही हैं.)
  • इनलाइन डाइमेंशन, किसी लाइन में मौजूद टेक्स्ट के फ़्लो के पैरलल होता है. (अंग्रेज़ी में, inline-size और width एक जैसे हैं.)

ये डाइमेंशन नाम, सभी लॉजिकल लेआउट प्रॉपर्टी पर लागू होते हैं. उदाहरण के लिए, अंग्रेज़ी में block-start और top एक ही हैं. साथ ही, inline-end और right भी एक ही हैं.

सीएसएस की नई लॉजिकल लेआउट प्रॉपर्टी दिखाने वाला डायग्राम.

लॉजिकल प्रॉपर्टी की मदद से, अन्य भाषाओं के लिए अपने लेआउट को अपने-आप अपडेट किया जा सकता है. इसके लिए, अलग-अलग एलिमेंट पर दर्ज दर्जनों लेआउट प्रॉपर्टी को अपडेट करने के बजाय, अपने पेज के लिए writing-mode और direction प्रॉपर्टी को बदलना होगा.

नीचे दिए गए डेमो में, <body> एलिमेंट पर writing-mode प्रॉपर्टी को अलग-अलग वैल्यू पर सेट करके देखा जा सकता है कि लॉजिकल प्रॉपर्टी कैसे काम करती हैं:

position: sticky

position: sticky वाला एलिमेंट तब तक ब्लॉक फ़्लो में रहता है, जब तक वह ऑफ़स्क्रीन पर स्क्रोल करना शुरू नहीं करता. इसके बाद, वह पेज के बाकी हिस्से के साथ स्क्रोल करना बंद कर देता है और एलिमेंट की top वैल्यू से तय की गई जगह पर बना रहता है. उस एलिमेंट के लिए तय की गई जगह, फ़्लो में बनी रहती है और जब उपयोगकर्ता वापस ऊपर की ओर स्क्रोल करता है, तब एलिमेंट वापस आ जाता है.

स्टिक ऐलिमेंट की मदद से, कई ऐसे काम के इफ़ेक्ट बनाए जा सकते हैं जिनके लिए पहले JavaScript की ज़रूरत होती थी. इस सुविधा के कुछ इस्तेमाल के उदाहरण दिखाने के लिए, हमने कई डेमो बनाए हैं. हर डेमो काफ़ी हद तक एक ही सीएसएस का इस्तेमाल करता है और हर इफ़ेक्ट को बनाने के लिए सिर्फ़ एचटीएमएल मार्कअप में थोड़ा बदलाव करता है.

स्टिकी स्टैक

इस डेमो में, सभी स्टिक एलिमेंट एक ही कंटेनर शेयर करते हैं. इसका मतलब है कि जब उपयोगकर्ता नीचे की ओर स्क्रोल करता है, तो हर स्टिक एलिमेंट पिछले एलिमेंट के ऊपर स्लाइड करता है. स्टिक एलिमेंट एक ही जगह पर स्टिक होते हैं.

स्टिकी स्लाइड

यहां, स्टिकी एलिमेंट एक-दूसरे के भाई-बहन हैं. (यानी, उनके माता-पिता भाई-बहन हैं.) जब कोई स्टिक वाला एलिमेंट अपने कंटेनर की निचली सीमा तक पहुंच जाता है, तो वह कंटेनर के साथ ऊपर की ओर बढ़ जाता है. इससे ऐसा लगता है कि नीचे मौजूद स्टिक वाले एलिमेंट, ऊपर मौजूद एलिमेंट को ऊपर की ओर धकेल रहे हैं. दूसरे शब्दों में कहें, तो वे अटकी हुई पोज़िशन के लिए मुकाबला करते दिखते हैं.

स्टिकी डिस्परेडो

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

backdrop-filter

backdrop-filter प्रॉपर्टी की मदद से, एलिमेंट के बजाय उसके पीछे मौजूद एरिया पर ग्राफ़िकल इफ़ेक्ट लागू किए जा सकते हैं. इसकी वजह से कई अच्छे इफ़ेक्ट बन जाते हैं, जिन्हें पहले सिर्फ़ मुश्किल सीएसएस और JavaScript हैकिंग का इस्तेमाल करके हासिल किया जा सकता था. इन इफ़ेक्ट को सीएसएस की एक लाइन से ही इस्तेमाल किया जा सकता था.

उदाहरण के लिए, इस डेमो में ओएस स्टाइल के हिसाब से धुंधला करने के लिए, backdrop-filter का इस्तेमाल किया गया है:

हमारे पास पहले से ही backdrop-filter के बारे में एक बढ़िया पोस्ट है, इसलिए ज़्यादा जानकारी के लिए वहां जाएं.

:is()

हालांकि, :is() pseudo-class 10 साल से ज़्यादा पुराना है, लेकिन अब भी इसका उतना इस्तेमाल नहीं हुआ जितना हमें लगता है कि इसकी ज़रूरत है. यह फ़ंक्शन, अपने आर्ग्युमेंट के तौर पर कॉमा लगाकर अलग की गई सिलेक्टर की सूची लेता है और उस सूची में मौजूद किसी भी सिलेक्टर से मैच करता है. इस सुविधा की मदद से, सीएसएस को आसानी से इस्तेमाल किया जा सकता है. साथ ही, इससे आपकी शिप की जाने वाली सीएसएस की संख्या में काफ़ी कमी आ सकती है.

इसका एक उदाहरण यहां दिया गया है:

button.focus,
button:focus {
  
}

article > h1,
article > h2,
article > h3,
article > h4,
article > h5,
article > h6 {
  
}

/* selects the same elements as the code above */
button:is(.focus, :focus) {
  
}

article > :is(h1,h2,h3,h4,h5,h6) {
  
}

gap

सीएसएस के ग्रिड लेआउट में कुछ समय से, gap (पहले grid-gap) था. चाइल्ड एलिमेंट के आस-पास स्पेस के बजाय, शामिल एलिमेंट के बीच स्पेस देकर gap, लेआउट से जुड़ी कई सामान्य समस्याओं को हल करता है. उदाहरण के लिए, गैप का इस्तेमाल करने पर, आपको चाइल्ड एलिमेंट के मार्जिन की चिंता नहीं करनी पड़ती. इससे, किसी एलिमेंट के किनारों के आस-पास ग़ैर-ज़रूरी खाली जगह नहीं दिखती:

इलस्ट्रेशन, जिसमें दिखाया गया है कि गैप प्रॉपर्टी, कंटेनर एलिमेंट के किनारों के आस-पास अनचाहे स्पेस से कैसे बचाती है.

इससे भी बेहतर खबर: gap अब फ़्लेक्सबॉक्स में भी उपलब्ध होगा. इसमें भी ग्रिड की तरह ही स्पेसिंग की सुविधाएं मिलेंगी:

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

इस वीडियो में, दो एलिमेंट के लिए एक gap प्रॉपर्टी का इस्तेमाल करने के फ़ायदों के बारे में बताया गया है. इनमें से एक एलिमेंट ग्रिड लेआउट और दूसरा फ़्लेक्स लेआउट का इस्तेमाल करता है:

फ़िलहाल, सिर्फ़ FireFox के लिए फ़्लेक्स लेआउट वाले लेआउट में ही gap को इस्तेमाल किया जा सकता है. हालांकि, इस डेमो को आज़माकर देखें कि यह कैसे काम करता है:

CSS Houdini

Houdini, ब्राउज़र के रेंडरिंग इंजन के लिए लो-लेवल एपीआई का एक सेट है. इसकी मदद से, ब्राउज़र को कस्टम सीएसएस को समझने का तरीका बताया जा सकता है. दूसरे शब्दों में, यह आपको सीएसएस ऑब्जेक्ट मॉडल का ऐक्सेस देता है. इससे, JavaScript की मदद से सीएसएस को बढ़ाया जा सकता है. इससे कई फ़ायदे मिलते हैं:

  • इससे आपको कस्टम सीएसएस सुविधाएं बनाने की ज़्यादा सुविधा मिलती है.
  • रेंडरिंग से जुड़ी समस्याओं को ऐप्लिकेशन लॉजिक से अलग करना आसान होता है.
  • यह सीएसएस पॉलीफ़िलिंग की तुलना में ज़्यादा बेहतर परफ़ॉर्म करती है. फ़िलहाल, हम JavaScript की मदद से सीएसएस पॉलीफ़िलिंग करते हैं. हालांकि, Houdini की मदद से सीएसएस पॉलीफ़िलिंग करने पर, ब्राउज़र को स्क्रिप्ट को पार्स करने और रेंडरिंग का दूसरा साइकल करने की ज़रूरत नहीं पड़ती. Houdini कोड को पहले रेंडरिंग साइकल में पार्स किया जाता है.

इस इमेज में दिखाया गया है कि पारंपरिक JavaScript पॉलीफ़िल के मुकाबले हुडीनी कैसे काम करती है.

Houdini, कई एपीआई का एक यूम्ब्रेला नेम है. अगर आपको इस सुविधा और इसके मौजूदा स्टेटस के बारे में ज़्यादा जानकारी चाहिए, तो क्या Houdini अब तक तैयार है? लेख पढ़ें अपनी बातचीत में, हमने प्रॉपर्टीज़ और वैल्यू एपीआई, Paint API, और ऐनिमेशन वर्कलेट के बारे में बात की, क्योंकि फ़िलहाल ये सबसे ज़्यादा काम के हैं. हम इन दिलचस्प एपीआई के लिए, पूरी पोस्ट बना सकते हैं. फ़िलहाल, हमारी बातचीत की खास जानकारी और कुछ बेहतरीन डेमो देखें. इनसे आपको यह जानकारी मिलेगी कि एपीआई की मदद से क्या-क्या किया जा सकता है.

ओवरफ़्लो

आने वाले समय में, हम कुछ और सुविधाओं को लॉन्च करने जा रहे हैं. हालांकि, इनके बारे में पूरी जानकारी देने के लिए हमारे पास समय नहीं था. इसलिए, हमने इन सुविधाओं के बारे में कम शब्दों में बताया है.⚡ अगर आपको इनमें से कुछ सुविधाओं के बारे में नहीं पता है, तो टॉक का आखिरी हिस्सा ज़रूर देखें!

  • size: एक प्रॉपर्टी, जिसकी मदद से एक ही समय में ऊंचाई और चौड़ाई सेट की जा सकती है
  • aspect-ratio: यह एक ऐसी प्रॉपर्टी है जो उन एलिमेंट के लिए आसपेक्ट रेशियो सेट करती है जिनमें यह पहले से मौजूद नहीं होता
  • min(), max(), और clamp(): ये फ़ंक्शन, आपको किसी भी सीएसएस प्रॉपर्टी पर संख्या से जुड़ी पाबंदियां सेट करने की सुविधा देते हैं. इनमें चौड़ाई और ऊंचाई के अलावा अन्य चीज़ें भी शामिल हैं
  • list-style-type एक मौजूदा प्रॉपर्टी है, लेकिन यह जल्द ही इमोजी और एसवीजी के साथ-साथ कई तरह की वैल्यू के साथ काम करेगी
  • display: outer inner: display प्रॉपर्टी जल्द ही दो पैरामीटर स्वीकार करेगी. इससे, inline-flex जैसे कंपाउंड कीवर्ड का इस्तेमाल करने के बजाय, इसके आउटर और इनर लेआउट को साफ़ तौर पर बताया जा सकेगा.
  • सीएसएस क्षेत्र: इसकी मदद से, किसी खास और रेक्टैंगल के अलावा किसी दूसरे आकार वाले क्षेत्र को भरा जा सकता है. इस क्षेत्र में कॉन्टेंट डाला और हटाया जा सकता है
  • सीएसएस मॉड्यूल: JavaScript, सीएसएस मॉड्यूल का अनुरोध कर पाएगा. साथ ही, इससे एक रिच ऑब्जेक्ट वापस मिल जाएगा. इस ऑब्जेक्ट पर आसानी से कार्रवाइयां की जा सकेंगी