[{"data":1,"prerenderedAt":2093},["ShallowReactive",2],{"page-\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fsubgrid-vs-nested-grid\u002F":3,"content-all-pages":1832},{"id":4,"title":5,"body":6,"description":1814,"extension":1815,"meta":1816,"navigation":488,"path":1828,"seo":1829,"stem":1830,"__hash__":1831},"content\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fsubgrid-vs-nested-grid\u002Findex.md","Subgrid vs an Independently Nested Grid",{"type":7,"value":8,"toc":1802},"minimark",[9,13,18,43,47,58,72,83,86,90,204,212,231,234,238,242,1479,1483,1488,1499,1501,1505,1512,1674,1689,1693,1700,1703,1706,1710,1721,1725,1731,1737,1743,1758,1762,1799],[10,11,5],"h1",{"id":12},"subgrid-vs-an-independently-nested-grid",[14,15,17],"h2",{"id":16},"the-narrow-problem","The narrow problem",[19,20,21,22,26,27,31,32,37,38,42],"p",{},"You have a row of cards. Each card contains a title, a body, and a footer, and each card is itself ",[23,24,25],"code",{},"display: grid"," so those three parts stack cleanly. Everything looks correct until real content arrives: one title runs to two lines, one body is a sentence longer than the rest, and now the footers sit at three different heights across the row. Making the cards equal height was easy — stretch does that for free. Making the ",[28,29,30],"em",{},"bands inside"," them line up is the part that a nested grid cannot do, no matter how you size its tracks. This page compares the two constructions directly, states the guarantee subgrid provides, and gives the criteria for choosing between them. It belongs to ",[33,34,36],"a",{"href":35},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002F","CSS Grid and Subgrid Layouts"," within ",[33,39,41],{"href":40},"\u002Fmastering-container-queries-responsive-layouts\u002F","Mastering Container Queries & Responsive Layouts",".",[14,44,46],{"id":45},"why-the-distinction-is-structural-not-stylistic","Why the distinction is structural, not stylistic",[19,48,49,50,53,54,57],{},"A grid container is normally an information boundary. Its track sizing algorithm looks at its own items and nothing else, and its items are invisible to any grid outside it. That isolation is deliberate and mostly desirable — it is what makes grids composable — but it means two sibling grids have no channel through which to agree on anything. Give them identical ",[23,51,52],{},"grid-template-rows: auto 1fr auto"," and they will still resolve those ",[23,55,56],{},"auto"," tracks to different pixel heights, because each measures different content.",[19,59,60,63,64,67,68,71],{},[23,61,62],{},"subgrid"," punches a controlled hole in that boundary. A child declared ",[23,65,66],{},"grid-template-rows: subgrid"," stops defining rows of its own and instead adopts the parent's row lines across the range it spans. Its items are then fed into the ",[28,69,70],{},"parent's"," track sizing algorithm. Because every sibling card is spanning the same parent rows, the parent sizes each band to the tallest contribution from any card, and all cards inherit that result. The alignment is not approximated; it falls out of a single sizing pass.",[19,73,74,75,78,79,82],{},"The alternatives all trade correctness for convenience. Fixed ",[23,76,77],{},"min-height"," per band is a guess that content will eventually break. Flexbox with ",[23,80,81],{},"align-items: stretch"," equalises the cards but not their interiors. Reading heights in script and writing them back works and is what the pre-2023 web did, but it costs a forced synchronous layout on every resize and reintroduces a class of bug — stale measurements after a font swap — that CSS simply does not have.",[84,85],"hr",{},[14,87,89],{"id":88},"what-each-construction-guarantees","What each construction guarantees",[91,92,98,99,98,103,98,107,98,114,98,119,98,123,98,133,98,136,98,139,98,149,98,153,98,160,98,163,98,166,98,171,98,174,98,178,98,181,98,185,98,188,98,193,98,196,98,201],"svg",{"viewBox":93,"role":94,"ariaLabel":95,"xmlns":96,"style":97},"0 0 720 340","img","Three cards aligned on shared subgrid row lines beside three cards with independently sized rows","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;height:auto;max-width:720px;margin:2rem 0","\n  ",[100,101,102],"title",{},"Subgrid row lines versus independent nested rows",[104,105,106],"desc",{},"On the left, three cards share two dashed horizontal lines because they subgrid onto the parent rows; on the right the same three cards have separators at six different heights.",[108,109,113],"text",{"x":110,"y":111,"style":112},"360","28","text-anchor:middle;fill:currentColor;font:700 17px sans-serif","the same three cards, two constructions",[108,115,62],{"x":116,"y":117,"style":118},"180","60","text-anchor:middle;fill:currentColor;font:13px ui-monospace,monospace",[108,120,122],{"x":121,"y":117,"style":118},"540","nested grid",[124,125],"rect",{"x":126,"y":127,"width":128,"height":129,"rx":130,"fill":131,"opacity":132},"38","80","88","170","8","#7aa2ff","0.16",[124,134],{"x":135,"y":127,"width":128,"height":129,"rx":130,"fill":131,"opacity":132},"136",[124,137],{"x":138,"y":127,"width":128,"height":129,"rx":130,"fill":131,"opacity":132},"234",[140,141],"line",{"x1":142,"y1":143,"x2":144,"y2":143,"stroke":131,"strokeWidth":145,"strokeDashArray":146},"30","118","330","2",[147,148],"6","4",[140,150],{"x1":142,"y1":151,"x2":144,"y2":151,"stroke":131,"strokeWidth":145,"strokeDashArray":152},"204",[147,148],[124,154],{"x":155,"y":127,"width":128,"height":129,"rx":130,"fill":156,"stroke":157,"strokeWidth":158,"opacity":159},"398","none","currentColor","1.5","0.5",[124,161],{"x":162,"y":127,"width":128,"height":129,"rx":130,"fill":156,"stroke":157,"strokeWidth":158,"opacity":159},"496",[124,164],{"x":165,"y":127,"width":128,"height":129,"rx":130,"fill":156,"stroke":157,"strokeWidth":158,"opacity":159},"594",[140,167],{"x1":155,"y1":168,"x2":169,"y2":168,"stroke":157,"strokeWidth":158,"opacity":170},"106","486","0.6",[140,172],{"x1":155,"y1":173,"x2":169,"y2":173,"stroke":157,"strokeWidth":158,"opacity":170},"192",[140,175],{"x1":162,"y1":176,"x2":177,"y2":176,"stroke":157,"strokeWidth":158,"opacity":170},"126","584",[140,179],{"x1":162,"y1":180,"x2":177,"y2":180,"stroke":157,"strokeWidth":158,"opacity":170},"178",[140,182],{"x1":165,"y1":183,"x2":184,"y2":183,"stroke":157,"strokeWidth":158,"opacity":170},"100","682",[140,186],{"x1":165,"y1":187,"x2":184,"y2":187,"stroke":157,"strokeWidth":158,"opacity":170},"214",[108,189,192],{"x":116,"y":190,"style":191},"284","text-anchor:middle;fill:currentColor;font:600 14px sans-serif","two shared lines",[108,194,195],{"x":121,"y":190,"style":191},"six unrelated lines",[108,197,200],{"x":116,"y":198,"style":199},"310","text-anchor:middle;fill:currentColor;font:12px sans-serif;opacity:0.65","parent sizes the bands once",[108,202,203],{"x":121,"y":198,"style":199},"each card sizes its own bands",[19,205,206,207,211],{},"Stated precisely: ",[208,209,210],"strong",{},"subgrid guarantees that items in different children which span the same parent track occupy that track's resolved size."," That is a guarantee about lines, not about content, which has two useful consequences. Alignment survives arbitrary content length, and it survives reordering — move a card and its bands still land on the same lines, because the lines belong to the parent.",[19,213,214,215,218,219,222,223,226,227,230],{},"A nested grid guarantees only that its own items are laid out on its own tracks. It cannot see a sibling, so it cannot match one. The commonly attempted workarounds fail for instructive reasons: ",[23,216,217],{},"1fr"," rows distribute the ",[28,220,221],{},"card's"," free space, which differs per card; ",[23,224,225],{},"align-content: space-between"," pins only the first and last bands and lets the middle drift; and ",[23,228,229],{},"grid-auto-rows"," on the parent affects the cards themselves, not their interiors.",[19,232,233],{},"The demo shows both at once. Drag the frame narrower until a title wraps — the subgrid row keeps its bands locked while the nested row goes ragged.",[235,236],"live-demo",{"name":237},"lp-subgrid-vs-nested",[14,239,241],{"id":240},"complete-working-implementation","Complete working implementation",[243,244,249],"pre",{"className":245,"code":246,"language":247,"meta":248,"style":248},"language-html shiki shiki-themes github-light-high-contrast github-dark-high-contrast","\u003C!doctype html>\n\u003Chtml lang=\"en\">\n\u003Chead>\n\u003Cmeta charset=\"utf-8\">\n\u003Cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\u003Ctitle>Subgrid versus nested grid\u003C\u002Ftitle>\n\u003Cstyle>\n  body { font: 16px\u002F1.4 system-ui, sans-serif; margin: 2rem; color: #1c2430; }\n  .head { margin: 0 0 0.5rem; font: 0.75rem ui-monospace, monospace; color: #666; }\n\n  .deck {\n    display: grid;\n    grid-template-columns: repeat(3, 1fr);\n    gap: 0.75rem;\n    margin-bottom: 1.75rem;\n  }\n\n  .card {\n    display: grid;\n    border: 1px solid #d4dbe8;\n    border-radius: 8px;\n    background: #fff;\n    padding: 0.6rem 0.7rem;\n    row-gap: 0.4rem;\n  }\n  .card h3 { margin: 0; font-size: 0.95rem; }\n  .card p { margin: 0; color: #5a6472; font-size: 0.85rem; }\n  .card footer {\n    padding-top: 0.35rem;\n    font-size: 0.8rem;\n    border-top: 1px solid #e6eaf2;\n    align-self: end;   \u002F* pin the footer to the bottom of its band *\u002F\n  }\n\n  \u002F* --- Construction A: subgrid ------------------------------------ *\u002F\n  \u002F* The parent declares the three bands ONCE. Because the deck has one\n     explicit row of cards, these become the implicit row pattern. *\u002F\n  .deck--sub { grid-auto-rows: auto 1fr auto; }\n\n  \u002F* Each card claims three parent rows and adopts their sizes rather\n     than computing rows of its own. *\u002F\n  .deck--sub .card {\n    grid-row: span 3;\n    grid-template-rows: subgrid;\n  }\n\n  \u002F* --- Construction B: independent nested grid --------------------- *\u002F\n  \u002F* Identical track list, but resolved separately inside every card,\n     so the resulting pixel heights differ card to card. *\u002F\n  .deck--nested .card { grid-template-rows: auto 1fr auto; }\n\n  \u002F* Baseline for engines without subgrid: construction B's behaviour. *\u002F\n  @supports not (grid-template-rows: subgrid) {\n    .deck--sub .card { grid-row: auto; grid-template-rows: auto 1fr auto; }\n  }\n\u003C\u002Fstyle>\n\u003C\u002Fhead>\n\u003Cbody>\n  \u003Ch2 class=\"head\">grid-template-rows: subgrid\u003C\u002Fh2>\n  \u003Cdiv class=\"deck deck--sub\">\n    \u003Carticle class=\"card\">\u003Ch3>Latency\u003C\u002Fh3>\u003Cp>Median round trip.\u003C\u002Fp>\u003Cfooter>p95 410ms\u003C\u002Ffooter>\u003C\u002Farticle>\n    \u003Carticle class=\"card\">\u003Ch3>Requests per second by region\u003C\u002Fh3>\u003Cp>Rolling five minute mean.\u003C\u002Fp>\u003Cfooter>peak 8.1k\u003C\u002Ffooter>\u003C\u002Farticle>\n    \u003Carticle class=\"card\">\u003Ch3>Errors\u003C\u002Fh3>\u003Cp>All 5xx.\u003C\u002Fp>\u003Cfooter>0.4%\u003C\u002Ffooter>\u003C\u002Farticle>\n  \u003C\u002Fdiv>\n\n  \u003Ch2 class=\"head\">independent nested grids\u003C\u002Fh2>\n  \u003Cdiv class=\"deck deck--nested\">\n    \u003Carticle class=\"card\">\u003Ch3>Latency\u003C\u002Fh3>\u003Cp>Median round trip.\u003C\u002Fp>\u003Cfooter>p95 410ms\u003C\u002Ffooter>\u003C\u002Farticle>\n    \u003Carticle class=\"card\">\u003Ch3>Requests per second by region\u003C\u002Fh3>\u003Cp>Rolling five minute mean.\u003C\u002Fp>\u003Cfooter>peak 8.1k\u003C\u002Ffooter>\u003C\u002Farticle>\n    \u003Carticle class=\"card\">\u003Ch3>Errors\u003C\u002Fh3>\u003Cp>All 5xx.\u003C\u002Fp>\u003Cfooter>0.4%\u003C\u002Ffooter>\u003C\u002Farticle>\n  \u003C\u002Fdiv>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>\n","html","",[23,250,251,270,290,300,318,343,357,367,430,483,490,499,513,541,555,570,576,581,589,600,620,634,647,666,681,686,716,754,764,779,794,813,831,836,841,847,853,859,883,888,894,900,910,923,935,940,945,951,957,963,988,993,999,1020,1053,1058,1068,1077,1087,1110,1127,1180,1226,1272,1282,1287,1307,1323,1366,1409,1452,1461,1470],{"__ignoreMap":248},[252,253,255,259,263,267],"span",{"class":140,"line":254},1,[252,256,258],{"class":257},"suds8","\u003C!",[252,260,262],{"class":261},"sne4z","doctype",[252,264,266],{"class":265},"s-5SL"," html",[252,268,269],{"class":257},">\n",[252,271,273,276,278,281,284,288],{"class":140,"line":272},2,[252,274,275],{"class":257},"\u003C",[252,277,247],{"class":261},[252,279,280],{"class":265}," lang",[252,282,283],{"class":257},"=",[252,285,287],{"class":286},"sT6z2","\"en\"",[252,289,269],{"class":257},[252,291,293,295,298],{"class":140,"line":292},3,[252,294,275],{"class":257},[252,296,297],{"class":261},"head",[252,299,269],{"class":257},[252,301,303,305,308,311,313,316],{"class":140,"line":302},4,[252,304,275],{"class":257},[252,306,307],{"class":261},"meta",[252,309,310],{"class":265}," charset",[252,312,283],{"class":257},[252,314,315],{"class":286},"\"utf-8\"",[252,317,269],{"class":257},[252,319,321,323,325,328,330,333,336,338,341],{"class":140,"line":320},5,[252,322,275],{"class":257},[252,324,307],{"class":261},[252,326,327],{"class":265}," name",[252,329,283],{"class":257},[252,331,332],{"class":286},"\"viewport\"",[252,334,335],{"class":265}," content",[252,337,283],{"class":257},[252,339,340],{"class":286},"\"width=device-width, initial-scale=1\"",[252,342,269],{"class":257},[252,344,346,348,350,353,355],{"class":140,"line":345},6,[252,347,275],{"class":257},[252,349,100],{"class":261},[252,351,352],{"class":257},">Subgrid versus nested grid\u003C\u002F",[252,354,100],{"class":261},[252,356,269],{"class":257},[252,358,360,362,365],{"class":140,"line":359},7,[252,361,275],{"class":257},[252,363,364],{"class":261},"style",[252,366,269],{"class":257},[252,368,370,373,376,379,382,385,389,392,395,398,401,404,407,410,412,414,417,419,422,424,427],{"class":140,"line":369},8,[252,371,372],{"class":261},"  body",[252,374,375],{"class":257}," { ",[252,377,378],{"class":265},"font",[252,380,381],{"class":257},": ",[252,383,384],{"class":265},"16",[252,386,388],{"class":387},"sHUrx","px",[252,390,391],{"class":257},"\u002F",[252,393,394],{"class":265},"1.4",[252,396,397],{"class":265}," system-ui",[252,399,400],{"class":257},", ",[252,402,403],{"class":265},"sans-serif",[252,405,406],{"class":257},"; ",[252,408,409],{"class":265},"margin",[252,411,381],{"class":257},[252,413,145],{"class":265},[252,415,416],{"class":387},"rem",[252,418,406],{"class":257},[252,420,421],{"class":265},"color",[252,423,381],{"class":257},[252,425,426],{"class":265},"#1c2430",[252,428,429],{"class":257},"; }\n",[252,431,433,436,438,440,442,445,448,451,453,455,457,459,462,464,467,469,472,474,476,478,481],{"class":140,"line":432},9,[252,434,435],{"class":265},"  .head",[252,437,375],{"class":257},[252,439,409],{"class":265},[252,441,381],{"class":257},[252,443,444],{"class":265},"0",[252,446,447],{"class":265}," 0",[252,449,450],{"class":265}," 0.5",[252,452,416],{"class":387},[252,454,406],{"class":257},[252,456,378],{"class":265},[252,458,381],{"class":257},[252,460,461],{"class":265},"0.75",[252,463,416],{"class":387},[252,465,466],{"class":265}," ui-monospace",[252,468,400],{"class":257},[252,470,471],{"class":265},"monospace",[252,473,406],{"class":257},[252,475,421],{"class":265},[252,477,381],{"class":257},[252,479,480],{"class":265},"#666",[252,482,429],{"class":257},[252,484,486],{"class":140,"line":485},10,[252,487,489],{"emptyLinePlaceholder":488},true,"\n",[252,491,493,496],{"class":140,"line":492},11,[252,494,495],{"class":265},"  .deck",[252,497,498],{"class":257}," {\n",[252,500,502,505,507,510],{"class":140,"line":501},12,[252,503,504],{"class":265},"    display",[252,506,381],{"class":257},[252,508,509],{"class":265},"grid",[252,511,512],{"class":257},";\n",[252,514,516,519,521,524,527,530,532,535,538],{"class":140,"line":515},13,[252,517,518],{"class":265},"    grid-template-columns",[252,520,381],{"class":257},[252,522,523],{"class":265},"repeat",[252,525,526],{"class":257},"(",[252,528,529],{"class":265},"3",[252,531,400],{"class":257},[252,533,534],{"class":265},"1",[252,536,537],{"class":387},"fr",[252,539,540],{"class":257},");\n",[252,542,544,547,549,551,553],{"class":140,"line":543},14,[252,545,546],{"class":265},"    gap",[252,548,381],{"class":257},[252,550,461],{"class":265},[252,552,416],{"class":387},[252,554,512],{"class":257},[252,556,558,561,563,566,568],{"class":140,"line":557},15,[252,559,560],{"class":265},"    margin-bottom",[252,562,381],{"class":257},[252,564,565],{"class":265},"1.75",[252,567,416],{"class":387},[252,569,512],{"class":257},[252,571,573],{"class":140,"line":572},16,[252,574,575],{"class":257},"  }\n",[252,577,579],{"class":140,"line":578},17,[252,580,489],{"emptyLinePlaceholder":488},[252,582,584,587],{"class":140,"line":583},18,[252,585,586],{"class":265},"  .card",[252,588,498],{"class":257},[252,590,592,594,596,598],{"class":140,"line":591},19,[252,593,504],{"class":265},[252,595,381],{"class":257},[252,597,509],{"class":265},[252,599,512],{"class":257},[252,601,603,606,608,610,612,615,618],{"class":140,"line":602},20,[252,604,605],{"class":265},"    border",[252,607,381],{"class":257},[252,609,534],{"class":265},[252,611,388],{"class":387},[252,613,614],{"class":265}," solid",[252,616,617],{"class":265}," #d4dbe8",[252,619,512],{"class":257},[252,621,623,626,628,630,632],{"class":140,"line":622},21,[252,624,625],{"class":265},"    border-radius",[252,627,381],{"class":257},[252,629,130],{"class":265},[252,631,388],{"class":387},[252,633,512],{"class":257},[252,635,637,640,642,645],{"class":140,"line":636},22,[252,638,639],{"class":265},"    background",[252,641,381],{"class":257},[252,643,644],{"class":265},"#fff",[252,646,512],{"class":257},[252,648,650,653,655,657,659,662,664],{"class":140,"line":649},23,[252,651,652],{"class":265},"    padding",[252,654,381],{"class":257},[252,656,170],{"class":265},[252,658,416],{"class":387},[252,660,661],{"class":265}," 0.7",[252,663,416],{"class":387},[252,665,512],{"class":257},[252,667,669,672,674,677,679],{"class":140,"line":668},24,[252,670,671],{"class":265},"    row-gap",[252,673,381],{"class":257},[252,675,676],{"class":265},"0.4",[252,678,416],{"class":387},[252,680,512],{"class":257},[252,682,684],{"class":140,"line":683},25,[252,685,575],{"class":257},[252,687,689,691,694,696,698,700,702,704,707,709,712,714],{"class":140,"line":688},26,[252,690,586],{"class":265},[252,692,693],{"class":261}," h3",[252,695,375],{"class":257},[252,697,409],{"class":265},[252,699,381],{"class":257},[252,701,444],{"class":265},[252,703,406],{"class":257},[252,705,706],{"class":265},"font-size",[252,708,381],{"class":257},[252,710,711],{"class":265},"0.95",[252,713,416],{"class":387},[252,715,429],{"class":257},[252,717,719,721,724,726,728,730,732,734,736,738,741,743,745,747,750,752],{"class":140,"line":718},27,[252,720,586],{"class":265},[252,722,723],{"class":261}," p",[252,725,375],{"class":257},[252,727,409],{"class":265},[252,729,381],{"class":257},[252,731,444],{"class":265},[252,733,406],{"class":257},[252,735,421],{"class":265},[252,737,381],{"class":257},[252,739,740],{"class":265},"#5a6472",[252,742,406],{"class":257},[252,744,706],{"class":265},[252,746,381],{"class":257},[252,748,749],{"class":265},"0.85",[252,751,416],{"class":387},[252,753,429],{"class":257},[252,755,757,759,762],{"class":140,"line":756},28,[252,758,586],{"class":265},[252,760,761],{"class":261}," footer",[252,763,498],{"class":257},[252,765,767,770,772,775,777],{"class":140,"line":766},29,[252,768,769],{"class":265},"    padding-top",[252,771,381],{"class":257},[252,773,774],{"class":265},"0.35",[252,776,416],{"class":387},[252,778,512],{"class":257},[252,780,782,785,787,790,792],{"class":140,"line":781},30,[252,783,784],{"class":265},"    font-size",[252,786,381],{"class":257},[252,788,789],{"class":265},"0.8",[252,791,416],{"class":387},[252,793,512],{"class":257},[252,795,797,800,802,804,806,808,811],{"class":140,"line":796},31,[252,798,799],{"class":265},"    border-top",[252,801,381],{"class":257},[252,803,534],{"class":265},[252,805,388],{"class":387},[252,807,614],{"class":265},[252,809,810],{"class":265}," #e6eaf2",[252,812,512],{"class":257},[252,814,816,819,821,824,827],{"class":140,"line":815},32,[252,817,818],{"class":265},"    align-self",[252,820,381],{"class":257},[252,822,823],{"class":265},"end",[252,825,826],{"class":257},";   ",[252,828,830],{"class":829},"sLBg1","\u002F* pin the footer to the bottom of its band *\u002F\n",[252,832,834],{"class":140,"line":833},33,[252,835,575],{"class":257},[252,837,839],{"class":140,"line":838},34,[252,840,489],{"emptyLinePlaceholder":488},[252,842,844],{"class":140,"line":843},35,[252,845,846],{"class":829},"  \u002F* --- Construction A: subgrid ------------------------------------ *\u002F\n",[252,848,850],{"class":140,"line":849},36,[252,851,852],{"class":829},"  \u002F* The parent declares the three bands ONCE. Because the deck has one\n",[252,854,856],{"class":140,"line":855},37,[252,857,858],{"class":829},"     explicit row of cards, these become the implicit row pattern. *\u002F\n",[252,860,862,865,867,869,871,873,876,878,881],{"class":140,"line":861},38,[252,863,864],{"class":265},"  .deck--sub",[252,866,375],{"class":257},[252,868,229],{"class":265},[252,870,381],{"class":257},[252,872,56],{"class":265},[252,874,875],{"class":265}," 1",[252,877,537],{"class":387},[252,879,880],{"class":265}," auto",[252,882,429],{"class":257},[252,884,886],{"class":140,"line":885},39,[252,887,489],{"emptyLinePlaceholder":488},[252,889,891],{"class":140,"line":890},40,[252,892,893],{"class":829},"  \u002F* Each card claims three parent rows and adopts their sizes rather\n",[252,895,897],{"class":140,"line":896},41,[252,898,899],{"class":829},"     than computing rows of its own. *\u002F\n",[252,901,903,905,908],{"class":140,"line":902},42,[252,904,864],{"class":265},[252,906,907],{"class":265}," .card",[252,909,498],{"class":257},[252,911,913,916,919,921],{"class":140,"line":912},43,[252,914,915],{"class":265},"    grid-row",[252,917,918],{"class":257},": span ",[252,920,529],{"class":265},[252,922,512],{"class":257},[252,924,926,929,931,933],{"class":140,"line":925},44,[252,927,928],{"class":265},"    grid-template-rows",[252,930,381],{"class":257},[252,932,62],{"class":265},[252,934,512],{"class":257},[252,936,938],{"class":140,"line":937},45,[252,939,575],{"class":257},[252,941,943],{"class":140,"line":942},46,[252,944,489],{"emptyLinePlaceholder":488},[252,946,948],{"class":140,"line":947},47,[252,949,950],{"class":829},"  \u002F* --- Construction B: independent nested grid --------------------- *\u002F\n",[252,952,954],{"class":140,"line":953},48,[252,955,956],{"class":829},"  \u002F* Identical track list, but resolved separately inside every card,\n",[252,958,960],{"class":140,"line":959},49,[252,961,962],{"class":829},"     so the resulting pixel heights differ card to card. *\u002F\n",[252,964,966,969,971,973,976,978,980,982,984,986],{"class":140,"line":965},50,[252,967,968],{"class":265},"  .deck--nested",[252,970,907],{"class":265},[252,972,375],{"class":257},[252,974,975],{"class":265},"grid-template-rows",[252,977,381],{"class":257},[252,979,56],{"class":265},[252,981,875],{"class":265},[252,983,537],{"class":387},[252,985,880],{"class":265},[252,987,429],{"class":257},[252,989,991],{"class":140,"line":990},51,[252,992,489],{"emptyLinePlaceholder":488},[252,994,996],{"class":140,"line":995},52,[252,997,998],{"class":829},"  \u002F* Baseline for engines without subgrid: construction B's behaviour. *\u002F\n",[252,1000,1002,1005,1008,1011,1013,1015,1017],{"class":140,"line":1001},53,[252,1003,1004],{"class":387},"  @supports",[252,1006,1007],{"class":387}," not",[252,1009,1010],{"class":257}," (",[252,1012,975],{"class":265},[252,1014,381],{"class":257},[252,1016,62],{"class":265},[252,1018,1019],{"class":257},") {\n",[252,1021,1023,1026,1028,1030,1033,1035,1037,1039,1041,1043,1045,1047,1049,1051],{"class":140,"line":1022},54,[252,1024,1025],{"class":265},"    .deck--sub",[252,1027,907],{"class":265},[252,1029,375],{"class":257},[252,1031,1032],{"class":265},"grid-row",[252,1034,381],{"class":257},[252,1036,56],{"class":265},[252,1038,406],{"class":257},[252,1040,975],{"class":265},[252,1042,381],{"class":257},[252,1044,56],{"class":265},[252,1046,875],{"class":265},[252,1048,537],{"class":387},[252,1050,880],{"class":265},[252,1052,429],{"class":257},[252,1054,1056],{"class":140,"line":1055},55,[252,1057,575],{"class":257},[252,1059,1061,1064,1066],{"class":140,"line":1060},56,[252,1062,1063],{"class":257},"\u003C\u002F",[252,1065,364],{"class":261},[252,1067,269],{"class":257},[252,1069,1071,1073,1075],{"class":140,"line":1070},57,[252,1072,1063],{"class":257},[252,1074,297],{"class":261},[252,1076,269],{"class":257},[252,1078,1080,1082,1085],{"class":140,"line":1079},58,[252,1081,275],{"class":257},[252,1083,1084],{"class":261},"body",[252,1086,269],{"class":257},[252,1088,1090,1093,1095,1098,1100,1103,1106,1108],{"class":140,"line":1089},59,[252,1091,1092],{"class":257},"  \u003C",[252,1094,14],{"class":261},[252,1096,1097],{"class":265}," class",[252,1099,283],{"class":257},[252,1101,1102],{"class":286},"\"head\"",[252,1104,1105],{"class":257},">grid-template-rows: subgrid\u003C\u002F",[252,1107,14],{"class":261},[252,1109,269],{"class":257},[252,1111,1113,1115,1118,1120,1122,1125],{"class":140,"line":1112},60,[252,1114,1092],{"class":257},[252,1116,1117],{"class":261},"div",[252,1119,1097],{"class":265},[252,1121,283],{"class":257},[252,1123,1124],{"class":286},"\"deck deck--sub\"",[252,1126,269],{"class":257},[252,1128,1130,1133,1136,1138,1140,1143,1146,1149,1152,1154,1156,1158,1161,1163,1165,1168,1171,1173,1176,1178],{"class":140,"line":1129},61,[252,1131,1132],{"class":257},"    \u003C",[252,1134,1135],{"class":261},"article",[252,1137,1097],{"class":265},[252,1139,283],{"class":257},[252,1141,1142],{"class":286},"\"card\"",[252,1144,1145],{"class":257},">\u003C",[252,1147,1148],{"class":261},"h3",[252,1150,1151],{"class":257},">Latency\u003C\u002F",[252,1153,1148],{"class":261},[252,1155,1145],{"class":257},[252,1157,19],{"class":261},[252,1159,1160],{"class":257},">Median round trip.\u003C\u002F",[252,1162,19],{"class":261},[252,1164,1145],{"class":257},[252,1166,1167],{"class":261},"footer",[252,1169,1170],{"class":257},">p95 410ms\u003C\u002F",[252,1172,1167],{"class":261},[252,1174,1175],{"class":257},">\u003C\u002F",[252,1177,1135],{"class":261},[252,1179,269],{"class":257},[252,1181,1183,1185,1187,1189,1191,1193,1195,1197,1200,1202,1204,1206,1209,1211,1213,1215,1218,1220,1222,1224],{"class":140,"line":1182},62,[252,1184,1132],{"class":257},[252,1186,1135],{"class":261},[252,1188,1097],{"class":265},[252,1190,283],{"class":257},[252,1192,1142],{"class":286},[252,1194,1145],{"class":257},[252,1196,1148],{"class":261},[252,1198,1199],{"class":257},">Requests per second by region\u003C\u002F",[252,1201,1148],{"class":261},[252,1203,1145],{"class":257},[252,1205,19],{"class":261},[252,1207,1208],{"class":257},">Rolling five minute mean.\u003C\u002F",[252,1210,19],{"class":261},[252,1212,1145],{"class":257},[252,1214,1167],{"class":261},[252,1216,1217],{"class":257},">peak 8.1k\u003C\u002F",[252,1219,1167],{"class":261},[252,1221,1175],{"class":257},[252,1223,1135],{"class":261},[252,1225,269],{"class":257},[252,1227,1229,1231,1233,1235,1237,1239,1241,1243,1246,1248,1250,1252,1255,1257,1259,1261,1264,1266,1268,1270],{"class":140,"line":1228},63,[252,1230,1132],{"class":257},[252,1232,1135],{"class":261},[252,1234,1097],{"class":265},[252,1236,283],{"class":257},[252,1238,1142],{"class":286},[252,1240,1145],{"class":257},[252,1242,1148],{"class":261},[252,1244,1245],{"class":257},">Errors\u003C\u002F",[252,1247,1148],{"class":261},[252,1249,1145],{"class":257},[252,1251,19],{"class":261},[252,1253,1254],{"class":257},">All 5xx.\u003C\u002F",[252,1256,19],{"class":261},[252,1258,1145],{"class":257},[252,1260,1167],{"class":261},[252,1262,1263],{"class":257},">0.4%\u003C\u002F",[252,1265,1167],{"class":261},[252,1267,1175],{"class":257},[252,1269,1135],{"class":261},[252,1271,269],{"class":257},[252,1273,1275,1278,1280],{"class":140,"line":1274},64,[252,1276,1277],{"class":257},"  \u003C\u002F",[252,1279,1117],{"class":261},[252,1281,269],{"class":257},[252,1283,1285],{"class":140,"line":1284},65,[252,1286,489],{"emptyLinePlaceholder":488},[252,1288,1290,1292,1294,1296,1298,1300,1303,1305],{"class":140,"line":1289},66,[252,1291,1092],{"class":257},[252,1293,14],{"class":261},[252,1295,1097],{"class":265},[252,1297,283],{"class":257},[252,1299,1102],{"class":286},[252,1301,1302],{"class":257},">independent nested grids\u003C\u002F",[252,1304,14],{"class":261},[252,1306,269],{"class":257},[252,1308,1310,1312,1314,1316,1318,1321],{"class":140,"line":1309},67,[252,1311,1092],{"class":257},[252,1313,1117],{"class":261},[252,1315,1097],{"class":265},[252,1317,283],{"class":257},[252,1319,1320],{"class":286},"\"deck deck--nested\"",[252,1322,269],{"class":257},[252,1324,1326,1328,1330,1332,1334,1336,1338,1340,1342,1344,1346,1348,1350,1352,1354,1356,1358,1360,1362,1364],{"class":140,"line":1325},68,[252,1327,1132],{"class":257},[252,1329,1135],{"class":261},[252,1331,1097],{"class":265},[252,1333,283],{"class":257},[252,1335,1142],{"class":286},[252,1337,1145],{"class":257},[252,1339,1148],{"class":261},[252,1341,1151],{"class":257},[252,1343,1148],{"class":261},[252,1345,1145],{"class":257},[252,1347,19],{"class":261},[252,1349,1160],{"class":257},[252,1351,19],{"class":261},[252,1353,1145],{"class":257},[252,1355,1167],{"class":261},[252,1357,1170],{"class":257},[252,1359,1167],{"class":261},[252,1361,1175],{"class":257},[252,1363,1135],{"class":261},[252,1365,269],{"class":257},[252,1367,1369,1371,1373,1375,1377,1379,1381,1383,1385,1387,1389,1391,1393,1395,1397,1399,1401,1403,1405,1407],{"class":140,"line":1368},69,[252,1370,1132],{"class":257},[252,1372,1135],{"class":261},[252,1374,1097],{"class":265},[252,1376,283],{"class":257},[252,1378,1142],{"class":286},[252,1380,1145],{"class":257},[252,1382,1148],{"class":261},[252,1384,1199],{"class":257},[252,1386,1148],{"class":261},[252,1388,1145],{"class":257},[252,1390,19],{"class":261},[252,1392,1208],{"class":257},[252,1394,19],{"class":261},[252,1396,1145],{"class":257},[252,1398,1167],{"class":261},[252,1400,1217],{"class":257},[252,1402,1167],{"class":261},[252,1404,1175],{"class":257},[252,1406,1135],{"class":261},[252,1408,269],{"class":257},[252,1410,1412,1414,1416,1418,1420,1422,1424,1426,1428,1430,1432,1434,1436,1438,1440,1442,1444,1446,1448,1450],{"class":140,"line":1411},70,[252,1413,1132],{"class":257},[252,1415,1135],{"class":261},[252,1417,1097],{"class":265},[252,1419,283],{"class":257},[252,1421,1142],{"class":286},[252,1423,1145],{"class":257},[252,1425,1148],{"class":261},[252,1427,1245],{"class":257},[252,1429,1148],{"class":261},[252,1431,1145],{"class":257},[252,1433,19],{"class":261},[252,1435,1254],{"class":257},[252,1437,19],{"class":261},[252,1439,1145],{"class":257},[252,1441,1167],{"class":261},[252,1443,1263],{"class":257},[252,1445,1167],{"class":261},[252,1447,1175],{"class":257},[252,1449,1135],{"class":261},[252,1451,269],{"class":257},[252,1453,1455,1457,1459],{"class":140,"line":1454},71,[252,1456,1277],{"class":257},[252,1458,1117],{"class":261},[252,1460,269],{"class":257},[252,1462,1464,1466,1468],{"class":140,"line":1463},72,[252,1465,1063],{"class":257},[252,1467,1084],{"class":261},[252,1469,269],{"class":257},[252,1471,1473,1475,1477],{"class":140,"line":1472},73,[252,1474,1063],{"class":257},[252,1476,247],{"class":261},[252,1478,269],{"class":257},[14,1480,1482],{"id":1481},"key-technique-the-span-is-half-the-mechanism","Key technique: the span is half the mechanism",[19,1484,1485,1487],{},[23,1486,66],{}," on its own is almost always a bug. It says \"use the parent's lines for the rows I occupy\" — and by default a card occupies exactly one row, so it inherits a single line pair and all three of its children pile into that one band. The span is what widens the range of adopted lines, which is why the two declarations only make sense together.",[19,1489,1490,1491,1494,1495,1498],{},"The same reasoning tells you which axis to subgrid. Ask what needs to align ",[28,1492,1493],{},"across"," elements. Bands stacked vertically across a horizontal row of cards means rows. A form where every row's label column must be the same width means columns, and then the child subgrids ",[23,1496,1497],{},"grid-template-columns"," and spans columns instead. Subgridding an axis you do not need alignment on costs you the ability to define your own tracks there for nothing in return, which is why one-axis subgrids are the common production shape.",[84,1500],{},[14,1502,1504],{"id":1503},"variation-subgrid-one-axis-keep-the-other-local","Variation: subgrid one axis, keep the other local",[19,1506,1507,1508,1511],{},"A card that must align its bands with siblings ",[28,1509,1510],{},"and"," run a two-column internal layout can do both, because the two axes are independent.",[243,1513,1517],{"className":1514,"code":1515,"language":1516,"meta":248,"style":248},"language-css shiki shiki-themes github-light-high-contrast github-dark-high-contrast",".deck--sub .card {\n  grid-row: span 3;\n  grid-template-rows: subgrid;      \u002F* rows come from the parent *\u002F\n  grid-template-columns: 3rem 1fr;  \u002F* columns are the card's own *\u002F\n}\n\n\u002F* An icon in the first local column, text in the second. *\u002F\n.card h3       { grid-column: 2; }\n.card p        { grid-column: 2; }\n.card .icon    { grid-column: 1; grid-row: 1; }\n.card footer   { grid-column: 1 \u002F -1; }\n","css",[23,1518,1519,1528,1539,1554,1575,1580,1584,1589,1608,1625,1651],{"__ignoreMap":248},[252,1520,1521,1524,1526],{"class":140,"line":254},[252,1522,1523],{"class":265},".deck--sub",[252,1525,907],{"class":265},[252,1527,498],{"class":257},[252,1529,1530,1533,1535,1537],{"class":140,"line":272},[252,1531,1532],{"class":265},"  grid-row",[252,1534,918],{"class":257},[252,1536,529],{"class":265},[252,1538,512],{"class":257},[252,1540,1541,1544,1546,1548,1551],{"class":140,"line":292},[252,1542,1543],{"class":265},"  grid-template-rows",[252,1545,381],{"class":257},[252,1547,62],{"class":265},[252,1549,1550],{"class":257},";      ",[252,1552,1553],{"class":829},"\u002F* rows come from the parent *\u002F\n",[252,1555,1556,1559,1561,1563,1565,1567,1569,1572],{"class":140,"line":302},[252,1557,1558],{"class":265},"  grid-template-columns",[252,1560,381],{"class":257},[252,1562,529],{"class":265},[252,1564,416],{"class":387},[252,1566,875],{"class":265},[252,1568,537],{"class":387},[252,1570,1571],{"class":257},";  ",[252,1573,1574],{"class":829},"\u002F* columns are the card's own *\u002F\n",[252,1576,1577],{"class":140,"line":320},[252,1578,1579],{"class":257},"}\n",[252,1581,1582],{"class":140,"line":345},[252,1583,489],{"emptyLinePlaceholder":488},[252,1585,1586],{"class":140,"line":359},[252,1587,1588],{"class":829},"\u002F* An icon in the first local column, text in the second. *\u002F\n",[252,1590,1591,1594,1596,1599,1602,1604,1606],{"class":140,"line":369},[252,1592,1593],{"class":265},".card",[252,1595,693],{"class":261},[252,1597,1598],{"class":257},"       { ",[252,1600,1601],{"class":265},"grid-column",[252,1603,381],{"class":257},[252,1605,145],{"class":265},[252,1607,429],{"class":257},[252,1609,1610,1612,1614,1617,1619,1621,1623],{"class":140,"line":432},[252,1611,1593],{"class":265},[252,1613,723],{"class":261},[252,1615,1616],{"class":257},"        { ",[252,1618,1601],{"class":265},[252,1620,381],{"class":257},[252,1622,145],{"class":265},[252,1624,429],{"class":257},[252,1626,1627,1629,1632,1635,1637,1639,1641,1643,1645,1647,1649],{"class":140,"line":485},[252,1628,1593],{"class":265},[252,1630,1631],{"class":265}," .icon",[252,1633,1634],{"class":257},"    { ",[252,1636,1601],{"class":265},[252,1638,381],{"class":257},[252,1640,534],{"class":265},[252,1642,406],{"class":257},[252,1644,1032],{"class":265},[252,1646,381],{"class":257},[252,1648,534],{"class":265},[252,1650,429],{"class":257},[252,1652,1653,1655,1657,1660,1662,1664,1666,1669,1672],{"class":140,"line":492},[252,1654,1593],{"class":265},[252,1656,761],{"class":261},[252,1658,1659],{"class":257},"   { ",[252,1661,1601],{"class":265},[252,1663,381],{"class":257},[252,1665,534],{"class":265},[252,1667,1668],{"class":257}," \u002F ",[252,1670,1671],{"class":265},"-1",[252,1673,429],{"class":257},[19,1675,1676,1677,1680,1681,1684,1685,1688],{},"Note the ",[23,1678,1679],{},"gap"," interaction, which surprises people: on a subgridded axis the child ignores its own ",[23,1682,1683],{},"row-gap"," and inherits the parent's, because the gaps are part of the track geometry it adopted. On the non-subgridded axis, the child's own ",[23,1686,1687],{},"column-gap"," applies as normal.",[14,1690,1692],{"id":1691},"markup-and-performance-tradeoffs","Markup and performance tradeoffs",[19,1694,1695,1696,1699],{},"Subgrid constrains your markup in one specific way: the card's aligned children must be direct children of the subgridded element. Wrapping the title and body in a ",[23,1697,1698],{},"\u003Cdiv>"," for styling convenience removes them from the grid and breaks the alignment, so a subgrid layout tends to have flatter markup than the equivalent nested one. That is usually an improvement, but it does mean the two constructions are not swap-in replacements for each other once wrappers exist.",[19,1701,1702],{},"On cost: a nested grid resolves in isolation, while subgrid track sizing must gather contributions from items in several grids before it can size a band, so it is a slightly heavier layout operation. The scale matters more than the constant — a deck of a dozen cards is unmeasurable, a virtualised table of thousands of subgridded rows is worth profiling. Compared against the JavaScript equalisation it replaces, subgrid wins outright, because that approach adds a second layout pass on every resize rather than a modest cost within the first one.",[19,1704,1705],{},"Choose the nested grid when a component's internals are genuinely private — a standalone hero, a modal, a chart's own axis layout. Choose subgrid the moment two or more siblings must agree.",[14,1707,1709],{"id":1708},"browser-support-note","Browser support note",[19,1711,1712,1713,1716,1717,1720],{},"Subgrid is supported in Firefox 71+, Safari 16+, and Chrome and Edge 117+, so every evergreen engine has it as of 2026. Because the failure mode is a graceful loss of alignment rather than a broken layout, a ",[23,1714,1715],{},"@supports not (grid-template-rows: subgrid)"," block that restores explicit rows — as in the implementation above — is enough for older builds. Note that ",[23,1718,1719],{},"@supports (display: grid)"," tells you nothing about subgrid; test the exact property-value pair.",[14,1722,1724],{"id":1723},"faq","FAQ",[19,1726,1727,1730],{},[208,1728,1729],{},"What can subgrid do that a nested grid cannot?","\nSubgrid lets a child participate in its parent's track sizing, so separate siblings share the same row or column lines. A nested grid computes its tracks only from its own contents and can never coordinate with a sibling.",[19,1732,1733,1736],{},[208,1734,1735],{},"Do I need grid-row: span on a subgrid item?","\nYes, whenever you subgrid an axis with more than one track. The item must claim the range of parent lines it intends to adopt; without a span it occupies a single track and inherits only that one line pair.",[19,1738,1739,1742],{},[208,1740,1741],{},"Is subgrid slower than a nested grid?","\nMarginally, because track sizing has to consider items from more than one grid before resolving. In practice it is far cheaper than the JavaScript measuring pass it replaces, and the difference is not observable at typical card counts.",[19,1744,1745,1748,1749,1751,1752,1754,1755,1757],{},[208,1746,1747],{},"Can I subgrid only one axis?","\nYes. ",[23,1750,975],{}," and ",[23,1753,1497],{}," take ",[23,1756,62],{}," independently, so a card can inherit the parent's rows for cross-card alignment while defining its own columns internally.",[14,1759,1761],{"id":1760},"related","Related",[1763,1764,1765,1771,1778,1785,1792],"ul",{},[1766,1767,1768,1770],"li",{},[33,1769,36],{"href":35}," — the parent guide to track sizing and grid architecture.",[1766,1772,1773,1777],{},[33,1774,1776],{"href":1775},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fbuilding-a-dashboard-with-subgrid\u002F","Building a Dashboard with Subgrid"," — a full metric-card dashboard applying the technique end to end.",[1766,1779,1780,1784],{},[33,1781,1783],{"href":1782},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fauto-fit-minmax-responsive-grids\u002F","auto-fit and minmax Responsive Grids"," — the column definition that decides how many cards share a row.",[1766,1786,1787,1791],{},[33,1788,1790],{"href":1789},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fholy-grail-layout-with-grid\u002F","Holy-Grail Layout with Grid"," — named areas for the page skeleton around the deck.",[1766,1793,1794,1798],{},[33,1795,1797],{"href":1796},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fcontainer-query-hover-affordances\u002F","Container Query Hover Affordances"," — cross-area: adding interaction to cards once they are aligned.",[364,1800,1801],{},"html pre.shiki code .suds8, html code.shiki .suds8{--shiki-default:#0E1116;--shiki-dark:#F0F3F6}html pre.shiki code .sne4z, html code.shiki .sne4z{--shiki-default:#024C1A;--shiki-dark:#72F088}html pre.shiki code .s-5SL, html code.shiki .s-5SL{--shiki-default:#023B95;--shiki-dark:#91CBFF}html pre.shiki code .sT6z2, html code.shiki .sT6z2{--shiki-default:#032563;--shiki-dark:#ADDCFF}html pre.shiki code .sHUrx, html code.shiki .sHUrx{--shiki-default:#A0111F;--shiki-dark:#FF9492}html pre.shiki code .sLBg1, html code.shiki .sLBg1{--shiki-default:#66707B;--shiki-dark:#BDC4CC}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":248,"searchDepth":272,"depth":272,"links":1803},[1804,1805,1806,1807,1808,1809,1810,1811,1812,1813],{"id":16,"depth":272,"text":17},{"id":45,"depth":272,"text":46},{"id":88,"depth":272,"text":89},{"id":240,"depth":272,"text":241},{"id":1481,"depth":272,"text":1482},{"id":1503,"depth":272,"text":1504},{"id":1691,"depth":272,"text":1692},{"id":1708,"depth":272,"text":1709},{"id":1723,"depth":272,"text":1724},{"id":1760,"depth":272,"text":1761},"The alignment guarantee subgrid gives that an independent nested grid cannot, plus the markup and performance tradeoffs, on a row of cards that must line up.","md",{"pageTitle":1817,"datePublished":1818,"dateModified":1818,"faq":1819},"Subgrid vs Nested Grid: Which to Use","2026-07-20",[1820,1822,1824,1826],{"q":1729,"a":1821},"Subgrid lets a child participate in its parent's track sizing, so separate siblings share the same row or column lines. A nested grid computes its tracks only from its own contents and can never coordinate with a sibling.",{"q":1735,"a":1823},"Yes, whenever you subgrid an axis with more than one track. The item must claim the range of parent lines it intends to adopt; without a span it occupies a single track and inherits only that one line pair.",{"q":1741,"a":1825},"Marginally, because track sizing has to consider items from more than one grid before resolving. In practice it is far cheaper than the JavaScript measuring pass it replaces, and the difference is not observable at typical card counts.",{"q":1747,"a":1827},"Yes. grid-template-rows and grid-template-columns take subgrid independently, so a card can inherit the parent's rows for cross-card alignment while defining its own columns internally.","\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fsubgrid-vs-nested-grid",{"title":5,"description":1814},"mastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fsubgrid-vs-nested-grid\u002Findex","61wDC5ECkbtx_IIlkwik48-1HJ4A9AAlEzU1bmugc4Q",[1833,1836,1839,1842,1845,1848,1851,1854,1857,1860,1863,1866,1869,1872,1875,1878,1881,1884,1887,1890,1893,1896,1899,1902,1905,1908,1911,1914,1917,1920,1923,1926,1929,1932,1935,1938,1941,1944,1947,1950,1953,1956,1959,1962,1965,1968,1971,1973,1976,1979,1982,1985,1988,1991,1994,1997,2000,2003,2006,2009,2012,2015,2018,2021,2024,2025,2028,2031,2034,2037,2040,2042,2045,2048,2051,2054,2057,2060,2063,2066,2069,2072,2075,2078,2081,2084,2087,2090],{"path":1834,"title":1835},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fcreating-accessible-focus-indicators","Creating Accessible Focus Indicators: Building a Ring That Survives Any Background",{"path":1837,"title":1838},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations","Accessibility in CSS Animations: Patterns, Specs & Best Practices",{"path":1840,"title":1841},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fprefers-reduced-motion-recipes","prefers-reduced-motion Recipes: A Reduction for Every Common Effect",{"path":1843,"title":1844},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Freducing-motion-preferences-in-css","Reducing Motion Preferences in CSS: How the Setting Becomes a Media Feature",{"path":1846,"title":1847},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Ftarget-size-and-pointer-accessibility","Target Size and Pointer Accessibility: Meeting 2.5.8 Without Redesigning",{"path":1849,"title":1850},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fvestibular-safe-animation-patterns","Vestibular-Safe Animation Patterns: Why Some Motion Makes People Sick",{"path":1852,"title":1853},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fwcag-motion-success-criteria","WCAG Motion Success Criteria: What Each One Actually Requires",{"path":1855,"title":1856},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fcontainer-query-hover-affordances","Container Query Hover Affordances: When Narrow Means Persistent, Not Hidden",{"path":1858,"title":1859},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion","Container-Aware Motion: Animation Sized by the Space a Component Actually Has",{"path":1861,"title":1862},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fmotion-that-scales-with-container-size","Motion That Scales with Container Size: cqi, cqb, and Derived Durations",{"path":1864,"title":1865},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fsuppressing-motion-in-small-containers","Suppressing Motion in Small Containers: Deliberately Animating Nothing",{"path":1867,"title":1868},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api","CSS Animation vs the Web Animations API: A Decision Guide",{"path":1870,"title":1871},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api\u002Fwhen-to-use-javascript-animation","When to Use JavaScript Instead of CSS for Animation",{"path":1873,"title":1874},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Fanimating-custom-properties-with-at-property","Animating Custom Properties with @property: Typed Variables That Interpolate",{"path":1876,"title":1877},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Ffluid-spacing-tokens-driving-transition-durations","Fluid Spacing Tokens That Drive Transition Durations",{"path":1879,"title":1880},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture","CSS Custom Properties Architecture: Scalable Design Systems & Dynamic UI",{"path":1882,"title":1883},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Fregistered-properties-and-type-safety","Registered Properties and Type Safety: @property as a Contract for Design Tokens",{"path":1885,"title":1886},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fcss-transition-timing-functions","CSS Transition Timing Functions: ease, cubic-bezier(), steps() and linear()",{"path":1888,"title":1889},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals","CSS Transition Fundamentals: Architecture, Performance & Patterns",{"path":1891,"title":1892},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fstarting-style-entry-animations","@starting-style: Animating an Element's Very First Style Change",{"path":1894,"title":1895},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransitioning-display-with-allow-discrete","Transitioning display with transition-behavior: allow-discrete and @starting-style",{"path":1897,"title":1898},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Faccessible-css-only-tooltips","Accessible CSS-Only Tooltips and Hover Cards With  and ",{"path":1900,"title":1901},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Ffocus-visible-vs-focus-polyfill-alternatives"," vs :focus: Why It Replaced the Focus-Ring Polyfill",{"path":1903,"title":1904},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Ffocus-within-form-patterns"," Form Patterns: Styling a Group From the Field Inside It",{"path":1906,"title":1907},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design","Hover & Focus State Design: Spec-Compliant Patterns for Modern UIs",{"path":1909,"title":1910},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Fpointer-and-hover-media-queries","Pointer and Hover Media Queries: Gating Affordances by Input Capability",{"path":1912,"title":1913},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Fsmooth-hover-effects-without-javascript","Smooth Hover Effects Without JavaScript: CSS-Only Patterns for Modern UI",{"path":1915,"title":1916},"\u002Fcss-only-micro-interactions-animations","CSS-Only Micro-Interactions & Animations: Architecture, Performance & Implementation",{"path":1918,"title":1919},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcontainer-query-triggered-keyframe-animations","Container-Query-Triggered Keyframe Animations: Animate Differently per Available Space",{"path":1921,"title":1922},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcss-only-accordions-and-disclosure","CSS-Only Accordions and Disclosure Widgets with details and summary",{"path":1924,"title":1925},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcss-only-loading-spinners-and-skeletons","CSS-Only Loading Spinners and Skeleton Shimmer Screens with @keyframes",{"path":1927,"title":1928},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcss-only-toggle-switches-and-checkboxes","CSS-Only Toggle Switches and Checkboxes That Keep the Native Input",{"path":1930,"title":1931},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns","Keyframe Animation Patterns: Spec-Compliant Architectures for Modern UIs",{"path":1933,"title":1934},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fstaggered-list-animations-with-custom-properties","Staggered List Animations Using --i Index Custom Properties",{"path":1936,"title":1937},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration","Performance & GPU Acceleration in CSS: A Developer’s Blueprint",{"path":1939,"title":1940},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Foptimizing-css-animations-for-60fps","Optimizing CSS Animations for 60fps: Budgeting the Frame",{"path":1942,"title":1943},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fprofiling-animations-in-devtools","Profiling CSS Animations in DevTools: Finding the Frame That Costs Too Much",{"path":1945,"title":1946},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fwill-change-and-the-compositor-thread","will-change and the Compositor Thread: Layer Promotion Without the Footguns",{"path":1948,"title":1949},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations","Scroll-Driven Animations: Binding Motion to Scroll Position in Pure CSS",{"path":1951,"title":1952},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-driven-animation-fallbacks","Shipping Scroll-Driven Animations Without Breaking Anything",{"path":1954,"title":1955},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-progress-bar-without-javascript","A Reading Progress Bar Driven by scroll(root)",{"path":1957,"title":1958},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-triggered-reveal-animations","Reveal-on-Scroll with view() and animation-range",{"path":1960,"title":1961},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers","View Transitions for CSS Developers: the Pseudo-Element Tree, Snapshots, and Named Elements",{"path":1963,"title":1964},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fsame-document-view-transitions","Writing a Same-Document View Transition: the CSS You Actually Author",{"path":1966,"title":1967},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transition-names-shared-elements","view-transition-name and Shared Elements: Morphing a Thumbnail into a Hero",{"path":1969,"title":1970},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transitions-with-reduced-motion","Honouring prefers-reduced-motion in View Transitions",{"path":391,"title":1972},"Modern CSS Layouts & Micro-Interactions",{"path":1974,"title":1975},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-positioned-tooltips","Anchor-Positioned Tooltips: Tethering, Flipping, and Getting the Semantics Right",{"path":1977,"title":1978},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-positioning-fallbacks","Anchor Positioning Fallbacks: A Graceful Floor for Older Browser Versions",{"path":1980,"title":1981},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays","CSS Anchor Positioning and Overlays: Tethering Elements Without JavaScript",{"path":1983,"title":1984},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fpopover-attribute-and-css-styling","The popover Attribute: Top-Layer Overlays With No JavaScript",{"path":1986,"title":1987},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Ffeature-detection-with-supports","Feature Detection with @supports: Syntax, Semantics, and the Traps",{"path":1989,"title":1990},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fhandling-container-query-fallbacks-for-older-browsers","Handling Container Query Fallbacks for Older Browsers",{"path":1992,"title":1993},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks","Container Query Fallbacks: Spec-Compliant CSS Strategies for Legacy Browsers",{"path":1995,"title":1996},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-query-units-cqi-cqb-explained","Container Query Units Explained: cqi, cqb, cqw, cqh, cqmin and cqmax",{"path":1998,"title":1999},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-type-size-vs-inline-size","Choosing container-type: inline-size, size, or normal",{"path":2001,"title":2002},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-vs-media-queries-comparison","Container vs Media Queries: Choosing the Right Reference Box",{"path":2004,"title":2005},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fhow-to-use-container-queries-in-production","How to Use Container Queries in Production Without a Rewrite",{"path":2007,"title":2008},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics","Container Query Syntax Basics",{"path":2010,"title":2011},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fnesting-and-naming-container-queries","Nesting and Naming Container Queries: Targeting the Right Ancestor",{"path":2013,"title":2014},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fauto-fit-minmax-responsive-grids","Responsive Grids with repeat(auto-fit, minmax())",{"path":2016,"title":2017},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fbuilding-a-dashboard-with-subgrid","Building a Responsive Dashboard Where Cards Align with Subgrid",{"path":2019,"title":2020},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fholy-grail-layout-with-grid","The Holy-Grail Layout with CSS Grid and Container Queries",{"path":2022,"title":2023},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts","CSS Grid and Subgrid Layouts for Responsive Interfaces",{"path":1828,"title":5},{"path":2026,"title":2027},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Fclamp-vs-media-query-typography","clamp() Fluid Type vs Media-Query Step Typography: Tradeoffs and Anatomy",{"path":2029,"title":2030},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-space-scale-with-clamp","Building a Fluid Spacing Scale with clamp() and Container Units",{"path":2032,"title":2033},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-type-accessibility-and-zoom","Fluid Type, Accessibility and Zoom: The vw-Only Trap",{"path":2035,"title":2036},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-typography-without-javascript","Fluid Typography Without JavaScript: A Precision CSS Reference",{"path":2038,"title":2039},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp","Fluid Typography with clamp(): A Practical Guide for Modern CSS",{"path":2041,"title":41},"\u002Fmastering-container-queries-responsive-layouts",{"path":2043,"title":2044},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Faspect-ratio-for-responsive-media","Using aspect-ratio for Responsive Media and Preventing Layout Shift",{"path":2046,"title":2047},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques","Intrinsic Sizing Techniques: Modern CSS Layouts for Responsive UI",{"path":2049,"title":2050},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fmin-max-fit-content-explained","min-content, max-content, and fit-content() Explained",{"path":2052,"title":2053},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fpreventing-flex-and-grid-overflow","The min-width: auto Trap in Flex and Grid Layouts",{"path":2055,"title":2056},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-for-reset-and-tokens","Cascade Layers for Reset and Design Tokens",{"path":2058,"title":2059},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-vs-specificity-hacks","Cascade Layers vs Specificity Hacks: Ordering Instead of Escalating",{"path":2061,"title":2062},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies","Modern CSS Reset Strategies: A Spec-Compliant Foundation",{"path":2064,"title":2065},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fbuilding-responsive-cards-with-container-queries","Building Responsive Cards with Container Queries: A Production-Ready Guide",{"path":2067,"title":2068},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fcontainer-query-data-tables","Container Query Data Tables: Reflowing Tables to Cards",{"path":2070,"title":2071},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fcontainer-query-sidebar-layouts","Container Query Sidebar Layouts That Travel Between Contexts",{"path":2073,"title":2074},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns","Responsive Component Patterns: Architecture & Implementation",{"path":2076,"title":2077},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-forms-with-container-queries","Responsive Forms with Container Queries: Reflow Without Losing the Wiring",{"path":2079,"title":2080},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-navigation-without-media-queries","Responsive Navigation Without Media Queries Using Container Queries",{"path":2082,"title":2083},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fcontainer-style-query-theming","Container Style Query Theming: One Token Instead of a Variant Class Matrix",{"path":2085,"title":2086},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state","Style Queries and Container State: Token-Driven Component Variants",{"path":2088,"title":2089},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fstyle-queries-with-custom-properties","Style Queries With Custom Properties: Declaring, Inheriting, and Matching Tokens",{"path":2091,"title":2092},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fstyle-query-fallbacks-and-support","Style Query Fallbacks and Support: Designing for Older Browser Versions",1784566157551]