सीएसएस में आर्किटेक्चर का इस्तेमाल करने के लिए दूसरा प्रस्ताव

Chrome की टीम, वेब पर मैसोनरी टाइप लेआउट लागू करने के लिए उत्सुक है. हालांकि, हमें लगता है कि हाल ही में WebKit के पोस्ट में सुझाए गए तरीके के मुताबिक, इसे सीएसएस ग्रिड स्पेसिफ़िकेशन के हिस्से के तौर पर लागू करना गलत होगा. हमें यह भी लगता है कि WebKit की पोस्ट में, मार्सियारी के ऐसे वर्शन के ख़िलाफ़ तर्क दिया गया है जिसका कोई भी सुझाव नहीं दे रहा था.

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

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

क्या मैसनरी को ग्रिड में शामिल किया जाना चाहिए?

Chrome की टीम का मानना है कि मेज़रमेंट के लिए, display: masonry (या कोई दूसरा कीवर्ड) का इस्तेमाल करके, मैसोनरी को अलग लेआउट के तरीके के तौर पर तय किया जाना चाहिए. इस पोस्ट में आगे, आपको कुछ उदाहरण मिलेंगे जिनसे पता चलेगा कि कोड में यह कैसा दिख सकता है.

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

परफ़ॉर्मेंस

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

इसलिए, अगर आपके पास grid-template-columns: 200px auto 200px के ट्रैक डेफ़िनिशन वाला कोई मेज़रमेंट लेआउट था, तो आपको समस्याएं आ सकती हैं. ऐसा, ग्रिड में बहुत आम तौर पर किया जाता है. सबग्रिड जोड़ने के बाद, ये समस्याएं कई गुना बढ़ जाती हैं.

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

हम उन चीज़ों के बारे में क्या करते हैं जो हर लेआउट के तरीके में काम की नहीं हैं?

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

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

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

ऐसे पैटर्न भी हैं जो मेज़रमेंट के लिए सही होते हैं. उदाहरण के लिए, grid-template-columns: repeat(auto-fill, max-content), क्योंकि आपके पास क्रॉस कंस्ट्रेंट नहीं हैं, लेकिन आपको ग्रिड में अमान्य रहना होगा. यहां उन प्रॉपर्टी की सूची दी गई है जिनके लिए हमें अलग तरह के व्यवहार की उम्मीद है या जिनकी मान्य वैल्यू अलग-अलग हो सकती हैं.

  • grid-template-areas: मेज़रमेंट के लिए, सिर्फ़ मेज़रमेंट की दिशा के अलावा किसी दूसरी दिशा में शुरुआती पंक्ति तय की जा सकती है.
  • grid-template: शॉर्टहैंड में सभी अंतरों को ध्यान में रखना होगा.
  • कानूनी वैल्यू में अंतर की वजह से, grid-template-columns और grid-template-rows के लिए साइज़ की वैल्यू ट्रैक करें.
  • grid-auto-flow, मेज़रमेंट के लिए इस्तेमाल होने वाले मैसोनरी फ़ॉर्मैट पर लागू नहीं होता. वहीं, masonry-auto-flow, ग्रिड फ़ॉर्मैट पर लागू नहीं होता. इन्हें मर्ज करने पर, उन चीज़ों से जुड़ी समस्याएं होंगी जो आपके लेआउट के तरीके की वजह से अमान्य हैं.
  • ग्रिड में चार प्लेसमेंट प्रॉपर्टी (grid-column-start वगैरह) होती हैं, जबकि मेसनरी में सिर्फ़ दो होती हैं.
  • ग्रिड में justify-* और align-* की सभी छह प्रॉपर्टी का इस्तेमाल किया जा सकता है. हालांकि, मेसनरी में सिर्फ़ फ़्लेक्सबॉक्स जैसे सबसेट का इस्तेमाल किया जाता है.

यह भी बताना ज़रूरी होगा कि गड़बड़ी के उन सभी नए मामलों में क्या होता है जिनकी वजह यह है कि डेवलपर ने ऐसी वैल्यू का इस्तेमाल किया है जो ग्रिड-विद-मेसनरी या ग्रिड-विदाउट-मेसनरी में मान्य नहीं है. उदाहरण के लिए, grid-template-columns: masonry या grid-template-rows: masonry का इस्तेमाल किया जा सकता है, लेकिन एक साथ दोनों का नहीं. अगर दोनों का एक साथ इस्तेमाल किया जाता है, तो क्या होगा? यह जानकारी इसलिए देनी होती है, ताकि सभी ब्राउज़र एक ही काम करें.

स्पेसिफ़िकेशन के हिसाब से, यह अब और आने वाले समय में मुश्किल हो जाएगा. हमें यह पक्का करना होगा कि हर चीज़ में मेज़रमेंट के लिए, मैसोनरी का ध्यान रखा गया हो. साथ ही, यह भी पक्का करना होगा कि मैसोनरी में यह सुविधा काम करती है या नहीं. डेवलपर के लिहाज़ से भी यह भ्रम पैदा करने वाला है. आपको यह क्यों याद रखना चाहिए कि display: grid का इस्तेमाल करने के बावजूद, मेसनरी का इस्तेमाल करने की वजह से कुछ चीज़ें काम नहीं करती हैं?

कोई दूसरा प्रस्ताव

जैसा कि पहले बताया गया है, Chrome की टीम मैसोनरी को ग्रिड स्पेसिफ़िकेशन के बाहर तय करना चाहती है. इसका मतलब यह नहीं है कि यह एक जैसे कॉलम साइज़ वाले बहुत ही आसान लेआउट के तरीके तक सीमित होगा. WebKit के पोस्ट में मौजूद सभी डेमो अब भी काम करेंगे.

क्लासिक मैसनरी लेआउट

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

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, minmax(14rem, 1fr));
  gap: 1rem;
}

एक जैसे साइज़ के ट्रैक.

अलग-अलग कॉलम की चौड़ाई के लिए, ग्रिड टाइप ट्रैक के साइज़ का इस्तेमाल करना

पहले बताई गई समस्या के अलावा, अब ग्रिड में अपनी पसंद के हिसाब से ट्रैक साइज़ का इस्तेमाल किया जा सकता है. जैसे, WebKit ब्लॉग पोस्ट का उदाहरण, जिसमें बार-बार छोटे और बड़े कॉलम का पैटर्न दिखता है.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, minmax(8rem, 1fr) minmax(16rem, 2fr)) minmax(8rem, 1fr);
  gap: 1rem;
}

चौड़े और छोटे साइज़ के ट्रैक का पैटर्न.

मेज़रमेंट के लिए, अतिरिक्त ट्रैक साइज़

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

max-content साइज़ के ट्रैक अपने-आप भरना.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, max-content);
  gap: 1rem;
}

auto साइज़ के ट्रैक अपने-आप भर जाएंगे. इससे, एक जैसे साइज़ के ट्रैक बन जाएंगे. साथ ही, सबसे बड़े ट्रैक के हिसाब से साइज़ अपने-आप तय हो जाएगा.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, auto);
  gap: 1rem;
}

अपने-आप साइज़ होने वाले ट्रैक के साथ मेसनरी.

कॉन्टेंट को कॉलम में दिखाने की अनुमति दें और आइटम को मज़ारी लेआउट पर रखें

अलग-अलग मेज़रमेंट के लिए, कॉलम में कॉन्टेंट को अलग-अलग तरीके से दिखाने की ज़रूरत नहीं है. इसमें masonry-track प्रॉपर्टी का इस्तेमाल किया जा सकता है, जो masonry-track-start और masonry-track-end के लिए शॉर्टहैंड है. ऐसा इसलिए, क्योंकि मैसोनरी लेआउट में, चीज़ों को अलग-अलग डाइमेंशन में दिखाने के लिए सिर्फ़ एक डाइमेंशन होता है.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, auto);
}

.span-2 {
  masonry-track: span 2; /* spans two columns */
}

.placed {
  masonry-track: 2 / 5; /* covers tracks 2, 3, and 4 */
}

प्लेस किए गए और स्पैन करने वाले आइटम के साथ मेसनरी.

सब-मेसनरी या सबग्रिड, जिसमें मेसनरी ट्रैक का इस्तेमाल किया गया हो

इसे अलग से दी गई मेज़रमेंट स्पेसिफ़िकेशन की मदद से दिखाया जा सकता है. हालांकि, इसके लिए यह ज़रूरी है कि इसमें अलग-अलग साइज़ के ट्रैक न हों. यह तय करना होगा कि यह कैसा दिखेगा. हमें नहीं लगता कि ऐसा करने से कोई समस्या आएगी.

नतीजा

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

अगर आपका कोई सुझाव/राय है, तो समस्या 9041 में जाकर चर्चा में शामिल हों.

इस पोस्ट की समीक्षा करने और इस पर हुई चर्चाओं के लिए, Bramus, Tab Atkins-Bittner, Una Kravets, Ian Kilpatrick, और Chris Harrelson का धन्यवाद.