2 पॉइंट द्वारा GN⁺ 2024-08-17 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • CSS Grid को मार्च 2017 से प्रमुख browsers में व्यापक support मिला है, लेकिन grid-template-areas अब भी कम इस्तेमाल होता है और यह line number की गणना किए बिना layout को CSS के अंदर visually व्यक्त कर सकता है
  • grid-template-areas में strings के जरिए area names रखे जाते हैं और child elements को grid-area से जोड़ा जाता है; एक ही नाम को अनिवार्य रूप से आयताकार area बनाना चाहिए
  • Named grid lines में content-start / content-end की तरह lines को नाम दिए जाते हैं, और *-start*-end pattern को browser implicit areas की तरह उपयोग कर सकता है
  • Card flip, responsive header, editorial layout, Threads-style post, overlapping cards, और :has() conditional layout में parent की area string ही बदलकर placement variants manage किए जा सकते हैं
  • Chrome, Safari, Firefox सभी Grid areas के लिए DevTools देते हैं; Firefox में area names दिखाना और grid-area edit करते समय संभावित line name autocomplete खास तौर पर उपयोगी है

grid-template-areas से layout को पढ़ने में आसान बनाना

  • मौजूदा CSS Grid placement में grid-column: 1 / 3 की तरह line numbers को सीधे specify करना आम है
  • Line numbers DevTools में देखने से पहले दिखाई नहीं देते, और columns व rows साथ वाले layout में सही number दिमाग में calculate करना मुश्किल होता है
  • grid-template-areas हर cell को नाम देकर placement करता है, इसलिए CSS code खुद layout के map जैसा दिखता है
.page {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-areas: "item1 item2";
  gap: 1rem;
}

.item-1 {
  grid-area: item1;
}

.item-2 {
  grid-area: item2;
}
  • Child elements grid-area के जरिए named area से mapped होते हैं
  • Card example में "featured featured article" जैसा define करके featured area को 2 columns और article area को 1 column लेने के लिए बनाया जा सकता है

Syntax और जरूरी नियम

  • grid-template-areas एक या अधिक area strings लेता है
    • एक string केवल columns वाला 1-dimensional layout बनाती है
    • कई strings rows और columns वाला multi-dimensional layout बनाती हैं
  • कई strings इस्तेमाल करते समय उन्हें अलग-अलग lines में लिखने से layout पढ़ना आसान होता है
.element {
  display: grid;
  grid-template-columns: 200px 1fr;
  grid-template-areas:
    "aside main"
    "footer footer";
}
  • हर string grid की एक row दर्शाती है, इसे table की तरह सोच सकते हैं
  • एक ही नाम से define किए गए areas code में आयताकार होने चाहिए
/* invalid */
.layout {
  grid-template-areas:
    "header header"
    "sidebar main"
    "header footer";
}

/* valid */
.layout {
  grid-template-areas:
    "header header"
    "sidebar main"
    "sidebar footer";
}
  • सभी rows में area tokens की संख्या समान होनी चाहिए, और भले ही कोई जरूरी area इस्तेमाल न हो, cell खुद define होना चाहिए
  • Empty cells को एक dot या कई dots से दिखाया जा सकता है
.element {
  grid-template-areas:
    "aside main"
    "... footer";
}
  • Dot CSS Grid spec का null cell token है, जो empty grid cell को दर्शाता है

Named grid lines और areas का संबंध

  • CSS Grid में columns की संख्या से lines की संख्या एक अधिक होती है
    • 3 columns हों तो 4 grid lines बनती हैं
  • Named grid lines में default numbers के बजाय lines को unique names दिए जाते हैं
.layout {
  grid-template-columns:
    [full-start] 1fr
    [content-start] 2fr
    [content-end] 1fr [full-end];
}

.item {
  grid-column: content-start / content-end;
}
  • Lines को नाम देने पर भी numeric lines का इस्तेमाल जारी रह सकता है
  • Track size का मतलब column या row का size है, और 1fr 1fr जैसे values track size हैं
  • Named lines में track के आसपास की lines को नाम दिया जाता है
.layout {
  display: grid;
  grid-template-columns:
    [aside-start] 200px [aside-end main-start] 1fr [main-end];
}
  • एक line कई names share कर सकती है; ऊपर के example में aside-end और main-start एक ही line हैं
  • aside-start और aside-end जैसे *-start / *-end names define करने पर browser implicit line names के जरिए grid-column: aside जैसा इस्तेमाल allow करता है
  • हर line को नाम देना जरूरी नहीं है; केवल important lines को selectively नाम दिया जा सकता है
  • Placement के समय numbers और names को मिलाकर grid-column: 1 / content-end की तरह इस्तेमाल किया जा सकता है

Parent की area string से placement variants manage करना

  • grid-template-areas इस्तेमाल करने पर child elements के grid-area names जैसे हैं वैसे रखते हुए, केवल parent की area string बदलकर पूरा layout बदला जा सकता है
.aside {
  grid-area: aside;
}

.main {
  grid-area: main;
}

.footer {
  grid-area: footer;
}
  • वही aside, main, footer names बनाए रखते हुए केवल grid-template-areas string बदलने से पूरा placement automatically update हो जाता है
  • Layout control parent की area definition में centralized हो जाता है, इसलिए adjustments आसान होते हैं

Card direction flip करना

  • Flexbox में flex-direction: row-reverse से card direction आसानी से flip किया जा सकता है
  • CSS Grid में line numbers इस्तेमाल करने पर direction बदलते समय column definition और हर child के grid-column values साथ में modify करने पड़ते हैं
  • Named areas इस्तेमाल करने पर card की image और content को areas के रूप में specify करके, केवल parent की area order बदलनी होती है
.card {
  display: grid;
  grid-template-columns: 150px 1fr;
  grid-template-areas: "thumb content";
}

.card__thumb {
  grid-area: thumb;
}

.card__content {
  grid-area: content;
}

.card--flip {
  grid-template-columns: 1fr 150px;
  grid-template-areas: "content thumb";
}
  • grid-template shorthand property से भी वही placement व्यक्त किया जा सकता है
.card--flip {
  grid-template: "content image" / 1fr 150px;
}
  • Shorthand property optional है, और लंबी properties अधिक readable लगती हैं—ऐसा विकल्प भी हो सकता है

Responsive header layout

  • Logo, navigation और action area वाला header शुरुआत में समान size के 3 columns से बनाया जा सकता है
  • Line numbers इस्तेमाल करने पर .logo, .nav, .actions प्रत्येक के लिए grid-column specify करना पड़ता है
  • Area names इस्तेमाल करने पर हर child को logo, nav, actions से map करके, viewport के अनुसार केवल parent का grid-template-areas बदला जाता है
.header {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-areas: "logo nav actions";
}

.logo {
  grid-area: logo;
}

.nav {
  grid-area: nav;
}

.actions {
  grid-area: actions;
}
  • छोटे size में logo और actions को पहली line में रखकर navigation को पूरी width दी जा सकती है
.header {
  grid-template-areas:
    "logo logo actions"
    "nav nav nav";
}
  • 380px या उससे ऊपर logo को left में और navigation व actions को right में रखा जा सकता है
@media (min-width: 380px) {
  .header {
    grid-template-areas:
      "logo nav nav"
      "logo actions actions";
  }

  .nav {
    justify-self: end;
  }
}
  • 900px या उससे ऊपर वापस single-line placement में लौटा जा सकता है
@media (min-width: 900px) {
  .header {
    grid-template-areas: "logo nav actions";
  }
}
  • Area string CSS के भीतर UI placement को सीधे दिखाने वाली mapping की तरह काम करती है

Editorial layout example

  • Title, text और image वाले section में grid-template-areas से viewport size के अनुसार placement आसानी से बदला जा सकता है
.section {
  display: grid;
  grid-template-areas:
    ". title title"
    "thumb content content";
  gap: 1rem;
}
  • Title के left में dot empty space दिखाने वाला null cell token है
  • time.com style section example में feature, secondary, most-read areas और दोनों ओर empty columns साथ में इस्तेमाल होते हैं
.featured-section {
  display: grid;
  grid-template-areas:
    ". feature most-read ."
    ". secondary most-read .";
  grid-template-columns: 1fr minmax(auto, 57.313rem) minmax(12rem, 18.75rem) 1fr;
  grid-template-rows: minmax(auto, 25rem) 1fr;
}
  • दोनों ओर empty columns मुख्य रूप से left-right spacing का काम करते हैं
  • Responsive version में small screen पर feature, secondary, most-read को vertical stack किया जाता है, और 500px900px या उससे ऊपर columns और area definitions बदली जाती हैं
  • grid-template-rows को area definition से replace किया जा सकता है, इसलिए यह जरूरी नहीं है

Threads-style post component

  • Threads app by Meta की CSS review करते हुए post component में CSS Grid के use cases देखे जा सकते हैं
  • Original example में grid-template-columns, grid-template-rows और line numbers से items place किए जाते हैं
.postBody {
  grid-column-start: 2;
  grid-row-start: 2;
  grid-row-end: span 3;
}
  • कई post variants को grid-template-areas से अधिक आसानी से व्यक्त किया जा सकता है
.post {
  grid-template-areas:
    "avatar header"
    "avatar body"
    ". body"
    ". footer";
}

.post--reply {
  grid-template-rows: 40px max-content max-content;
  grid-template-areas:
    "avatar header"
    "body body"
    "body body"
    "footer footer";
}

.post--nested {
  grid-template-areas:
    "avatar header"
    "avatar body"
    "line body"
    "footer footer";
}
  • Default, reply, और nested post variants को केवल area string देखकर अलग किया जा सकता है

Overlapping items और area names

  • grid-template-areas में एक ही नाम आयताकार होना चाहिए, इसलिए non-rectangular form में एक ही नाम दोहराना valid नहीं है
.layout {
  display: grid;
  grid-template-columns: 1fr 1fr fr;
  grid-template-areas:
    "card tag tag"
    "title title card";
}
  • ऊपर का example invalid है क्योंकि card आयताकार नहीं बनाता
  • Overlapping card में thumb-1, thumb-2 जैसे नए area names define करके, grid-column और grid-row में उन names का इस्तेमाल किया जा सकता है
.card {
  display: grid;
  grid-template-columns: auto auto 1fr;
  grid-template-rows: auto auto;
  grid-template-areas:
    "thumb-1 tag"
    "title thumb-2";
}

.thumb {
  grid-column: thumb-1 / thumb-2;
  grid-row: thumb-1 / thumb-2;
}
  • Tag और title को क्रमशः grid-area में place करके align-self, justify-self से align किया जा सकता है
  • जरूरत पड़ने पर child element की stacking order manage करनी पड़ सकती है, लेकिन example में source order से ही हल हो जाता है
  • यह overlapping example Oddbird’s Cascading Layouts page से inspired है

:has() और conditional layout

  • CSS :has() selector और Grid areas को combine करने से किसी specific element की मौजूदगी के आधार पर layout बदला जा सकता है
  • <figure> के अंदर figcaption होने और न होने पर अलग-अलग area definitions apply की जा सकती हैं
figure {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-areas: "img img img";
  gap: 0.5rem;
}

img {
  grid-area: img;
}

figcaption {
  grid-area: caption;
}

.card:has(figcaption) {
  grid-template-areas:
    "img img caption"
    "img img .";
}

LTR/RTL multi-language direction support

  • CSS Grid page direction LTR है या RTL, इसके अनुसार layout adjust करता है
  • Named grid areas भी page direction का पालन करते हैं, इसलिए RTL setting में layout flip हो जाता है
  • RTL layout लिखने से जुड़ा resource RTL Styling 101 guide में देखा जा सकता है

DevTools support differences

  • Chrome, Safari, Firefox सभी Grid areas के लिए DevTools देते हैं
  • Chrome
    • Area names को top-left में रखता है, जिससे areas overlapping दिख सकते हैं
    • Color overlay design के दिखने के तरीके को बदल सकता है
  • Safari
    • Pink outline items को स्पष्ट रूप से अलग करने में मदद करता है
    • Line names देखे जा सकते हैं
    • Line names display करने का तरीका lines को stack करके दिखाने जैसा है, जिसमें सुधार की गुंजाइश है
  • Firefox
    • Area names Chrome और Safari की तुलना में अधिक clear दिखते हैं
    • *-start, *-end जैसे custom names type करते समय autocomplete list देता है
    • Child item के grid-area को edit करते समय सभी संभावित line names की list देता है

References

1 टिप्पणियां

 
GN⁺ 2024-08-17
Hacker News राय
  • एनिमेशन डेमो काफी दिलचस्प था, लेकिन बाद में पता चला कि वह एनिमेशन CSS से बना ही नहीं था, इसलिए थोड़ी निराशा हुई
    Flexbox सीखने के बाद लगा कि “इतना काफी है”, और Grid को गहराई से नहीं सीखा। Grid को पसंद करने की वजहें दिखती हैं [0], लेकिन कुल मिलाकर ऐसा कोई काम नहीं आया जो सिर्फ Grid से ही हो सकता था, और data table के लिए असल में <table> ही इस्तेमाल करता हूं
    [0] https://css-tricks.com/css-grid-replace-flexbox/

    • ऐसा टूल सीखना अच्छी बात है जो आपकी सारी जरूरतें कवर कर दे
      Grid को मैंने सिर्फ https://labs.jensimmons.com/2016/examples/image-gallery-grid... जैसी responsive image gallery या https://every-layout.dev/demos/grid-cards/ जैसे responsive cards के लिए इस्तेमाल किया है। grid-template-columns सीखने लायक है और grid-gap सुविधाजनक है। बाकी मामलों में लगता है Flexbox लगभग सब संभाल लेता है
      हालांकि grid-template-areas अभी भी थोड़ा अस्पष्ट लगता है। लेख में breakpoint के हिसाब से layout adjustment या “जब team member को layout बदलना हो” तब आसान होने जैसी वजहें दी गई हैं, लेकिन शायद मैं ही target reader नहीं हूं
    • Grid सीखने के लिए एक मजेदार टूल: https://cssgridgarden.com/
    • Flex ज्यादातर मामलों में पर्याप्त है, लेकिन Grid की भी अपनी जगह है। जैसे 3-column card layout जो छोटे screen पर हर row में एक card तक सिमट जाता है, dedicated sidebar वाली page structure, या ऐसे elements जिनकी resizing के दौरान भी खास placement बनाए रखनी हो
      जरूरत के हिसाब से दोनों इस्तेमाल किए जा सकते हैं, और साथ मिलकर वे बेहद powerful layout tool बन जाते हैं
    • “नहीं, Flexbox ‘काफी अच्छा’ नहीं है”
      https://www.youtube.com/watch?v=MWWcZzossc8
  • रुको, 1/3 fraction नहीं बल्कि 1 से 3 तक की range है? समझ नहीं आता कि ऐसी syntax क्यों चुनी गई। programming में range दिखाने के लिए कई logical और well-known syntax हैं, जैसे 1..3

    • CSS के बारे में सबसे पहले समझने वाली बात यह है कि CSS programming language की अभिव्यक्ति नहीं है, बल्कि print layout की भाषा का इस्तेमाल करती है
      लगता है programmers को CSS में होने वाली काफी दिक्कतें इसी गलतफहमी से आती हैं
    • Grid feature अच्छा है, लेकिन इसकी syntax बाकी CSS से काफी अलग है, इसलिए उलझन होती है। लगता है जैसे इस हिस्से को अलग-थलग बनाकर बनाया गया हो, या “इस बार ठीक से करते हैं” वाला approach लिया गया हो
    • slash के दोनों तरफ सिर्फ numbers ही नहीं आते, कई words भी आ सकते हैं: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-column...
    • इसे ऐसे सोचिए जैसे किसी programmer को बताया जाए कि CSS में !important का मतलब “important नहीं” नहीं, बल्कि “important!” है
  • Grid भी और Flexbox भी ठीक से समझ में नहीं आए थे। आखिरी layout strategy जिसे मैं कुछ हद तक ठीक से संभाल पाता था, वह float थी। इस लेख को देखकर अगले layout को design करते समय CSS Grid आजमाने का confidence आया, और लेख भी अच्छी तरह बनाया गया है

    • अगर आपने float संभाला है, तो Grid और Flex कहीं ज्यादा आसान होंगे। एक-दो दिन निकालकर कुछ layouts बना कर देखिए। पुराने browsers से जूझने के उलट, ये दोनों बस ठीक से काम करते हैं, और सच कहें तो थोड़ा boring लगने लगते हैं
      अच्छे लेख बहुत हैं, लेकिन CSS-Tricks के ये दो लेख पढ़ना ही मेरे लिए काफी था
      https://css-tricks.com/snippets/css/a-guide-to-flexbox/
      https://css-tricks.com/snippets/css/complete-guide-grid/
    • Grid सीखे बिना भी कुछ हद तक काम चल सकता है, लेकिन Flexbox लगभग जरूरी है। क्योंकि यह पुराने float hacks से कहीं ज्यादा सुविधाजनक है और modern CSS में हर जगह मौजूद है
      ऊपर बताए CSS-Tricks लेखों के अलावा, MDN की Flexbox guide[1] और “CSS flexible box layout” reference document[2] की भी सिफारिश करता हूं। Flexbox के पीछे के concepts और properties, shorthand properties असल में कैसे काम करती हैं, इसे गहराई से समझने में मदद मिली
      [1]: https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layou...
      [2]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_flexibl...
    • Flexbox, float-based grid system का ठीक से बनाया गया version जैसा लगता है। child elements को vertical या horizontal किसी भी तरह रख सकते हैं, लेकिन clearfix hack इस्तेमाल करने वाली float पद्धति असल में लगभग सिर्फ row-level placement तक सीमित थी
      हालांकि Flexbox भी wrapping कर सकने वाला one-dimensional layout ही ज्यादा है, इसलिए nesting और stacking ही इसका तरीका है। Grid में templates होते हैं और direct children पहले से तय areas लेते हैं, इसलिए यह Flexbox से ज्यादा static है, और अंदर के nested elements पर असर नहीं डालने की सीमा है। फिर भी लगता है subgrid इस हिस्से को बदल देगा
    • अगर आपने float समझ लिया था, तो वह अपने आप में दुर्लभ उपलब्धि है, इसलिए Flex/Grid इस्तेमाल करना आपके लिए काफी मजेदार होगा
    • Grid में features बहुत हैं, लेकिन Flex पर्याप्त रूप से simple होते हुए भी अब भी बहुत powerful है
  • संबंधित सामग्री:
    Grid Garden https://cssgridgarden.com
    Flexbox Froggy https://flexboxfroggy.com

  • अच्छा होगा अगर इस दस्तावेज़ से भी ज़्यादा बुनियादी, “शुरुआत से पहले” वाला version हो। मैं intro वाले हिस्से से ही अटक गया और आगे नहीं बढ़ पाया। खासकर इस हिस्से पर: “Grid के अंदर child items को place करने के लिए grid-column से हर item की line number तय करनी होती है”; यहाँ line number क्या है, मुझे समझ नहीं आया
    सोचा कि context से समझ आ जाएगा और आगे बढ़ा, लेकिन तुरंत 1 / 3, 1 / 4 जैसे expressions पर फिर अटक गया

    • line number उन lines को कहते हैं जो columns के बीच boundary बनाती हैं। अगर 2 columns हैं, तो 3 lines होंगी: |a||b| में बीच की दो lines असल में एक ही गिनी जाती हैं, इसलिए कुल 3 होती हैं
      इसलिए 1/3 कोई fraction नहीं, बल्कि column range है, और इसका मतलब है “line 1 से शुरू होकर line 3 पर खत्म होता है”
    • थोड़ा नीचे scroll करेंगे तो एक live demo है, जिसमें आप खुद बदलकर देख सकते हैं कि क्या हो रहा है
      “line number” नाम बहुत अच्छा नहीं है, लेकिन असल में यह column की edge है। इसलिए 1/3 edge 1, यानी सबसे बाईं ओर से edge 3 तक जाता है, और पूरे 2 columns घेरता है
  • CSS Grid के लिए Jen Simmons Mondrian with auto flow की जोरदार सिफारिश करता हूँ। https://labs.jensimmons.com/2017/01-011.html पर C और D दबाकर देखें और window size बदलकर देखें। साथ में देखने के लिए YouTube video भी है: https://www.youtube.com/watch?v=qNtJ5p3h2A4
    वाकई शानदार है
    auto flow में जो बात मैं अभी समझना चाहता हूँ, वह है खाली जगहों को detect करके fill करने का तरीका। जब अलग-अलग sizes के objects randomly हों, तो auto flow को खाली जगह छोड़े बिना कैसे चलाया जाए? या क्या खाली जगह detect करके कुछ add किया जा सकता है?

  • उम्मीद है यह बेवकूफी भरा सवाल नहीं होगा, लेकिन syntax को 1/2, 3/4 की तरह slash से क्यों define किया गया? 1-2 जैसा, यानी column 1 से column 2 तक, या 1->2 जैसा कुछ ज़्यादा natural नहीं लगता?

    • column number negative भी हो सकता है। फिर 1--1, 1->-1, 1/-1 में से कौन बेहतर लगेगा?
    • arrow शायद संभव हो, लेकिन दोनों तरफ spaces होने की वजह है। वहाँ सिर्फ numbers ही नहीं आ सकते: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-column...
      CSS में values पहले से ही spaces से अलग होती हैं, और dash दिखने पर आम तौर पर जो intuition बनती है उसे ध्यान में रखें, तो नीचे वाला कहीं बेहतर है
      grid-column: 4 somegridarea / 6;
      grid-column: span 3 / 6;
      grid-column: span somegridarea / span someothergridarea;
      नीचे की तरह लिखने से यह कहीं ज़्यादा स्पष्ट है
      grid-column: 4 somegridarea-6;
      grid-column: span 3-6;
      grid-column: span 3->6;
      grid-column: span somegridarea-span someothergridarea;
      grid-column: span somegridarea->span someothergridarea;
  • ऐसे interactive blog posts मुझे बहुत पसंद हैं। Grid के लिए https://grid.layoutit.com/ जैसे tool में grid area को खुद हाथ लगाकर आज़माने की मैं जोरदार सिफारिश करता हूँ
    कई सालों से मैं उसी site से Grid layouts plan कर रहा हूँ, और spacing adjust करना बहुत आसान हो गया है

  • शायद यह पहली बार है जब मैंने CSS Grid को सच में समझा। number labels ने बहुत मदद की, और यह article आगे अक्सर refer करने लायक है

    • Firefox developer tools में भी वे numbers default रूप से दिखाए जा सकते हैं। Chrome के बारे में पक्का नहीं है
  • CSS Grid और areas का concept मुझे पसंद है, लेकिन मुझे अब भी सबसे मुश्किल हिस्सा खासकर mobile और desktop sizes के बीच responsive management लगता है। कौन सा UI element खुलना चाहिए, full screen होना चाहिए या नहीं—इन बातों के हिसाब से अक्सर grid-template-area और row/column sizes को JavaScript से update करना पड़ता है
    minmax या calc से हल होने वाली दुनिया मुझे अभी नहीं मिली है, और काश किसी को इसका जवाब पता हो

    • https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_contain...
    • ऐसे मामलों में Grid को वैसे ही रखते हुए row/column values को fixed values की जगह var(--foo) जैसी CSS variables में रखना अच्छा तरीका है
      तब JavaScript में सिर्फ उस variable की value update करनी होती है, और Grid वह value reflect कर देता है
    • हैरानी हुई कि article में template areas responsive design के लिए कितने अच्छे हैं, इस पर ज़ोर नहीं दिया गया। media queries का इस्तेमाल करके आप अलग-अलग screen sizes के लिए अलग Grid areas define कर सकते हैं, और हर element को उस screen size के हिसाब से desired placement पर move कर सकते हैं। अगर किसी खास size पर element छिपाना हो, तो उस size पर display: none दे दें
      एक बहुत simple example: https://codepen.io/trescenzi/pen/vYqpjvL
    • ऐसे कई cases शायद :has() या subgrid से solve हो सकते हैं, लेकिन मेरा direct experience ज़्यादा नहीं है
    • क्या आपने media queries इस्तेमाल करके देखी हैं?