कुछ साल पहले, मैंने एक डैशबोर्ड बनाने के लिए काम शुरू किया। कुछ खास नहीं—बस एक फिक्स्ड साइडबार, एक मुख्य कंटेंट एरिया और एक फुटर। Flexbox सबसे आसान विकल्प लगा, और शुरुआत में यह सही काम भी कर रहा था। फिर मैंने मुख्य सेक्शन में कार्ड्स की एक पंक्ति डाली। पूरा लेआउट बिखर गया। मैंने अगले तीन घंटे flex-grow रेश्यो और नेस्टेड प्रतिशत चौड़ाई (percentage widths) के साथ जूझते हुए बिताए, और यह देखते हुए कि कितना भी पैडिंग कम कर लूँ, कंटेनर लाइन में आने से इनकार कर रहे थे। ऐसा लग रहा था जैसे कोई मीनार गिरने ही वाली हो।
उस कठिन अनुभव ने मुझे आधुनिक CSS लेआउट के बारे में सबसे महत्वपूर्ण बात सिखाई: Flexbox और Grid प्रतिद्वंद्वी नहीं हैं। वे अलग-अलग कामों के लिए उपकरण हैं, और अधिकांश असफल लेआउट गलत टूल चुनने के कारण होते हैं।
अंतर आयामी (Dimensional) है
Flexbox को एक गलियारे (hallway) की तरह समझें। आइटम एक ही दिशा में प्रवाहित होते हैं, या तो एक row के रूप में या एक column के रूप में। यह एक-आयामी (one-dimensional) वितरण के लिए बना है। ब्राउज़र कंटेंट को देखता है, और फिर तय करता है कि उस एकल अक्ष (axis) पर उसे कैसे फैलाना, सिकोड़ना या संरेखित (align) करना है। यह Flexbox को उन स्थितियों के लिए एकदम सही बनाता है जहाँ कंटेंट लेआउट तय करता है। एक नेविगेशन बार, फॉर्म फ़ील्ड का एक स्टैक, या समान स्पेसिंग वाले टैग्स का सेट, सभी एक flex कंटेनर में स्वाभाविक रूप से फिट हो जाते हैं क्योंकि वे एक ही लॉजिक का पालन करते हैं।
दूसरी ओर, Grid एक फ्लोर प्लान की तरह है। यह पूरी तरह से दो-आयामी (two-dimensional) है, जो एक ही समय में rows और columns को संभालता है। आप पहले संरचना (structure) को परिभाषित करते हैं, और फिर उसके अंदर आइटम रखते हैं। यह Grid को समग्र पेज आर्किटेक्चर के लिए आदर्श बनाता है—ऐसी कहीं भी जहाँ आपको वर्टिकल और हॉरिजॉन्टल पोजीशनिंग को एक साथ नियंत्रित करने की आवश्यकता हो। जब आप नेस्टेड Flexbox कंटेनरों के माध्यम से एक जटिल दो-आयामी डिज़ाइन बनाने की कोशिश करते हैं, तो अंत में आपके पास गहरा मार्कअप, नाजुक रैपर्स और जटिल गणित बचता है जो एक अतिरिक्त एलिमेंट जोड़ते ही बिखर जाता है।
Flexbox अभी भी अपनी उपयोगिता बनाए हुए है
हर flex कंटेनर को Grid से बदलने की जल्दबाजी न करें। व्यक्तिगत कंपोनेंट्स के अंदर, Flexbox अक्सर अधिक साफ और सटीक होता है। यदि आपके पास दो बटनों वाला एक कार्ड फुटर है और आप एक को बाईं ओर और एक को दाईं ओर संरेखित करना चाहते हैं, तो justify-content: space-between बिल्कुल वही करता है जो आप चाहते हैं। यदि आपको अज्ञात ऊंचाई वाले बटन के अंदर एक आइकन को वर्टिकली सेंटर करने की आवश्यकता है, तो align-items: center सबसे सरल रास्ता है। परिवर्तनशील कंटेंट—जैसे अलग-अलग नाम की लंबाई वाले यूजर बैज की एक पंक्ति—Flexbox के अंदर आसानी से फिट हो जाता है क्योंकि यह 'कंटेंट-फर्स्ट' है। कंटेनर उस चीज़ के अनुसार ढल जाता है जिसे वह रखता है।
Grid 'कंटेनर-फर्स्ट' है। आप ब्राउज़र को बताते हैं कि कितने tracks मौजूद हैं और वे कितने बड़े होने चाहिए, फिर आप उन cells में आइटम डालते हैं। यदि आपका लेआउट वास्तव में केवल स्पेस साझा करने वाली एक ही पंक्ति के आइटम हैं, तो Grid अनावश्यक जटिलता जोड़ता है।
पेज लेआउट Grid का क्षेत्र है
यहीं से Grid का काम शुरू होता है। मेरा डैशबोर्ड वाला बुरा सपना याद है? यहाँ बताया गया है कि संरचना शुरुआत से ही कैसी दिखनी चाहिए थी:
.page {
display: grid;
min-height: 100vh;
grid-template-rows: auto 1fr auto;
grid-template-columns: 200px 1fr;
}
.header { grid-row: 1; grid-column: 1 / -1; }
.sidebar { grid-row: 2; grid-column: 1; }
.main { grid-row: 2; grid-column: 2; }
.footer { grid-row: 3; grid-column: 1 / -1; }
देखें कि क्या हो रहा है। .page कंटेनर तीन rows और दो columns स्थापित करता है। auto की मदद से पहली row अपने आप उस आकार में आ जाती है जो हेडर में मौजूद कंटेंट का होता है। बीच वाली row 1fr के साथ सारा उपलब्ध बचा हुआ स्थान ले लेती है। फुटर अंतिम row में आता है, जिसका आकार उसके अपने कंटेंट के अनुसार होता है। इस बीच, साइडबार 200 पिक्सेल की चौड़ाई पर लॉक हो जाता है, और मुख्य क्षेत्र बाकी जगह भर देता है।
प्लेसमेंट लॉजिक ही असली राहत है। हेडर कॉलम लाइन 1 से लाइन -1 तक फैला हुआ है, जिसका अर्थ है कि आप बाद में कितने भी कॉलम जोड़ें, यह दोनों कॉलमों में फैला रहेगा। साइडबार और मुख्य कंटेंट row 2 साझा करते हैं लेकिन अलग-अलग कॉलम में होते हैं। फुटर row 3 में पूरी चौड़ाई में वापस आ जाता है। आपको चाइल्ड एलिमेंट्स पर प्रतिशत गणित (percentage math) लगाने की आवश्यकता नहीं है। आपको ऊंचाई के लिए लड़ते हुए नेस्टेड रैपर्स की आवश्यकता नहीं है। एक ही जगह पर साइडबार की चौड़ाई बदलें, और मुख्य क्षेत्र अपने आप एडजस्ट हो जाएगा। पूरा लेआउट एक एकल प्रणाली के रूप में काम करता है।
grid-template-areas के साथ पठनीयता (Readability)
और भी अधिक स्पष्टता के लिए, आप अपने सेक्शन को नाम दे सकते हैं। लाइन नंबरों को मैनेज करने के बजाय, आप एक विजुअल मैप लिखते हैं:
.page {
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
.header { grid-area: header; }
.main { grid-area: main; }
अब आपकी स्टाइलशीट एक वायरफ्रेम की तरह पढ़ी जा सकती है। यदि आप कभी किसी अलग breakpoint के लिए साइडबार को दाईं ओर दिखाना चाहते हैं, तो आप बस template string में दो शब्दों को बदल देते हैं। इस तरह की संरचनात्मक पठनीयता नेस्टेड flex कंटेनरों के ढेर के भीतर प्राप्त करना असंभव है।
दो कठिन सबक
Grid कोई जादू नहीं है। ऐसी दो गलतियाँ हैं जो आपके लेआउट को तुरंत खराब कर देंगी।
पहली समस्या यूनिट का लापरवाही से उपयोग करना है। यदि आप grid-template-columns: 1fr 1fr 1fr परिभाषित करते हैं लेकिन आपके डिज़ाइन को केवल सामग्री के दो कॉलम की आवश्यकता है, तो वह तीसरा ट्रैक अभी भी मौजूद रहता है। यह या तो खाली रहेगा और एक ऐसा गैप बनाएगा जिसकी आपने अपेक्षा नहीं की थी, या यह आपकी वास्तविक सामग्री को इस तरह से सिकोड़ने के लिए मजबूर करेगा जिससे आपका डिज़ाइन बिगड़ जाएगा। सोच-समझकर काम करें। जब आपका मतलब दो कॉलम से हो, तो repeat(2, 1fr) लिखें।
