[{"data":1,"prerenderedAt":2192},["ShallowReactive",2],{"page-\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflexbox-gap-and-spacing\u002F":3,"content-all-pages":1628,"live-demo:flexp-gap-toolbar":2186},{"id":4,"title":5,"body":6,"description":1606,"extension":1607,"meta":1608,"navigation":357,"path":1624,"seo":1625,"stem":1626,"__hash__":1627},"content\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflexbox-gap-and-spacing\u002Findex.md","Flexbox gap vs Margins: Spacing Items Without Edge Hacks",{"type":7,"value":8,"toc":1595},"minimark",[9,19,50,55,61,174,184,188,194,198,1023,1034,1038,1048,1116,1127,1139,1143,1148,1219,1233,1237,1252,1404,1417,1421,1432,1450,1468,1472,1490,1494,1507,1526,1541,1553,1557,1592],[10,11,13,14,18],"h1",{"id":12},"flexbox-gap-vs-margins-spacing-items-without-edge-hacks","Flexbox ",[15,16,17],"code",{},"gap"," vs Margins: Spacing Items Without Edge Hacks",[20,21,22,23,26,27,31,32,35,36,38,39,44,45,49],"p",{},"Every flex row of buttons, tags or cards needs space between its items and none outside them. For years that meant a margin on every item plus a ",[15,24,25],{},":last-child"," reset, and when the row wrapped the reset stopped working because the last item on each ",[28,29,30],"em",{},"line"," was not the last ",[28,33,34],{},"child",". The narrow question this page answers is how to space flex items so the spacing is correct at every width and in every direction, and what margins are still for once ",[15,37,17],{}," handles the common case. It is part of ",[40,41,43],"a",{"href":42},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002F","Flexbox Layout Patterns"," within the ",[40,46,48],{"href":47},"\u002Fmastering-container-queries-responsive-layouts\u002F","Mastering Container Queries & Responsive Layouts"," guide.",[51,52,54],"h2",{"id":53},"why-margins-fail-in-a-wrapping-row","Why margins fail in a wrapping row",[20,56,57,58,60],{},"Margins belong to items. The item has no idea which line it landed on or whether it is the last on that line, so any rule that tries to suppress the trailing margin has to guess from the DOM. In a single-line row the guess is right: ",[15,59,25],{}," really is the end of the line. In a wrapped row it is wrong on every line except the final one, and each line gains a trailing gutter that pushes it off-centre or breaks right alignment.",[62,63,69,70,69,74,69,78,69,86,69,92,69,104,69,112,69,115,69,118,69,123,69,126,69,128,69,130,69,132,69,135,69,140,69,144,69,147,69,151,69,154,69,158,69,160,69,162,69,164,69,166,69,169],"svg",{"viewBox":64,"role":65,"ariaLabel":66,"xmlns":67,"style":68},"0 0 720 300","img","A wrapped row spaced with margins shows trailing gutters on every line; the same row spaced with gap has none","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;height:auto;max-width:720px;margin:2rem 0","\n  ",[71,72,73],"title",{},"Margins versus gap in a wrapped row",[75,76,77],"desc",{},"Left, items with a right margin leave a gutter at the end of each line except the last. Right, gap places space only between items, so every line ends flush with the container.",[79,80,85],"text",{"textAnchor":81,"x":82,"y":83,"style":84},"middle","360","26","text-anchor:middle;fill:currentColor;font:700 17px sans-serif","The trailing gutter margins cannot see",[79,87,91],{"textAnchor":81,"x":88,"y":89,"style":90},"185","56","text-anchor:middle;fill:currentColor;font:600 13px ui-monospace,monospace","margin-right: 12px",[93,94],"rect",{"x":95,"y":96,"width":97,"height":98,"rx":99,"fill":100,"stroke":101,"strokeWidth":102,"opacity":103},"30","68","310","150","8","none","currentColor","1.5","0.55",[93,105],{"x":106,"y":107,"width":107,"height":108,"rx":109,"fill":110,"opacity":111},"42","80","36","5","#7aa2ff","0.3",[93,113],{"x":114,"y":107,"width":107,"height":108,"rx":109,"fill":110,"opacity":111},"134",[93,116],{"x":117,"y":107,"width":107,"height":108,"rx":109,"fill":110,"opacity":111},"226",[93,119],{"x":120,"y":107,"width":121,"height":108,"fill":101,"opacity":122},"306","12","0.35",[93,124],{"x":106,"y":125,"width":107,"height":108,"rx":109,"fill":110,"opacity":111},"128",[93,127],{"x":114,"y":125,"width":107,"height":108,"rx":109,"fill":110,"opacity":111},[93,129],{"x":117,"y":125,"width":107,"height":108,"rx":109,"fill":110,"opacity":111},[93,131],{"x":120,"y":125,"width":121,"height":108,"fill":101,"opacity":122},[93,133],{"x":106,"y":134,"width":107,"height":108,"rx":109,"fill":110,"opacity":111},"176",[79,136,139],{"textAnchor":81,"x":88,"y":137,"style":138},"246","text-anchor:middle;fill:currentColor;font:12px sans-serif","stray gutter on lines 1 and 2",[79,141,143],{"textAnchor":81,"x":142,"y":89,"style":90},"535","gap: 12px",[93,145],{"x":146,"y":96,"width":97,"height":98,"rx":99,"fill":100,"stroke":101,"strokeWidth":102,"opacity":103},"380",[93,148],{"x":149,"y":107,"width":150,"height":108,"rx":109,"fill":110,"opacity":111},"392","87",[93,152],{"x":153,"y":107,"width":150,"height":108,"rx":109,"fill":110,"opacity":111},"491",[93,155],{"x":156,"y":107,"width":157,"height":108,"rx":109,"fill":110,"opacity":111},"590","88",[93,159],{"x":149,"y":125,"width":150,"height":108,"rx":109,"fill":110,"opacity":111},[93,161],{"x":153,"y":125,"width":150,"height":108,"rx":109,"fill":110,"opacity":111},[93,163],{"x":156,"y":125,"width":157,"height":108,"rx":109,"fill":110,"opacity":111},[93,165],{"x":149,"y":134,"width":150,"height":108,"rx":109,"fill":110,"opacity":111},[79,167,168],{"textAnchor":81,"x":142,"y":137,"style":138},"every line ends flush",[79,170,173],{"textAnchor":81,"x":82,"y":171,"style":172},"284","text-anchor:middle;fill:currentColor;font:12px sans-serif;opacity:0.75","Gap is a property of the container, which is the only thing that knows where lines break.",[20,175,176,177,180,181,183],{},"The traditional workaround was a negative margin on the container equal to the item margin, which cancels the outer gutter at the cost of overflowing the container by that amount. It works until the container has a background, a border, or ",[15,178,179],{},"overflow: hidden",", all of which reveal the trick. ",[15,182,17],{}," removes the need for any of it because it belongs to the container, and the container is the one component in the system that knows where the lines break.",[51,185,187],{"id":186},"the-complete-implementation","The complete implementation",[20,189,190,191,193],{},"The toolbar below uses every spacing tool a flex row needs: ",[15,192,17],{}," for regular spacing, an auto margin for the one item that should sit at the far end, and a larger row gap for wrapped lines.",[195,196],"live-demo",{"name":197},"flexp-gap-toolbar",[199,200,205],"pre",{"className":201,"code":202,"language":203,"meta":204,"style":204},"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\u003Ctitle>Flex gap toolbar\u003C\u002Ftitle>\n\u003Cstyle>\n  body { font: 15px\u002F1.4 system-ui, sans-serif; margin: 1rem; }\n\n  .toolbar {\n    display: flex;\n    flex-wrap: wrap;\n    align-items: center;\n    \u002F* row-gap column-gap: wrapped lines get more air than neighbours,\n       so each line reads as its own group. *\u002F\n    gap: 0.75rem 0.5rem;\n    padding: 0.75rem;\n    border: 1px solid #94a3b8;\n    border-radius: 10px;\n  }\n\n  .toolbar button {\n    padding: 0.45rem 0.8rem;\n    border: 1px solid #94a3b8;\n    border-radius: 6px;\n    background: transparent;\n    font: inherit;\n  }\n\n  \u002F* The auto margin absorbs ALL remaining free space on the line,\n     pushing this item and everything after it to the far end.\n     Logical property, so it flips correctly in right-to-left text. *\u002F\n  .toolbar .push {\n    margin-inline-start: auto;\n  }\n\n  \u002F* A divider between groups without an extra wrapper: a pseudo-element\n     would be counted as a flex item, so draw it with a border instead. *\u002F\n  .toolbar .group-start {\n    padding-inline-start: 0.75rem;\n    border-inline-start: 1px solid #94a3b8;\n    align-self: stretch;   \u002F* an empty span is 0px tall under align-items: center *\u002F\n  }\n\n  .toolbar button:focus-visible {\n    outline: 2px solid #2d5bff;\n    outline-offset: 2px;\n  }\n\u003C\u002Fstyle>\n\u003C\u002Fhead>\n\u003Cbody>\n  \u003Cdiv class=\"toolbar\" role=\"toolbar\" aria-label=\"Formatting\">\n    \u003Cbutton type=\"button\">Bold\u003C\u002Fbutton>\n    \u003Cbutton type=\"button\">Italic\u003C\u002Fbutton>\n    \u003Cbutton type=\"button\">Link\u003C\u002Fbutton>\n    \u003Cspan class=\"group-start\">\u003C\u002Fspan>\n    \u003Cbutton type=\"button\">Bullet list\u003C\u002Fbutton>\n    \u003Cbutton type=\"button\">Numbered list\u003C\u002Fbutton>\n    \u003Cbutton type=\"button\" class=\"push\">Publish\u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>\n","html","",[15,206,207,226,246,256,274,288,298,352,359,368,382,395,408,415,421,441,455,475,490,496,501,511,530,547,561,574,587,592,597,603,609,615,625,638,643,648,654,660,670,684,702,719,724,729,741,761,775,780,790,799,809,843,867,887,907,928,948,968,995,1005,1014],{"__ignoreMap":204},[208,209,211,215,219,223],"span",{"class":30,"line":210},1,[208,212,214],{"class":213},"suds8","\u003C!",[208,216,218],{"class":217},"sne4z","doctype",[208,220,222],{"class":221},"s-5SL"," html",[208,224,225],{"class":213},">\n",[208,227,229,232,234,237,240,244],{"class":30,"line":228},2,[208,230,231],{"class":213},"\u003C",[208,233,203],{"class":217},[208,235,236],{"class":221}," lang",[208,238,239],{"class":213},"=",[208,241,243],{"class":242},"sT6z2","\"en\"",[208,245,225],{"class":213},[208,247,249,251,254],{"class":30,"line":248},3,[208,250,231],{"class":213},[208,252,253],{"class":217},"head",[208,255,225],{"class":213},[208,257,259,261,264,267,269,272],{"class":30,"line":258},4,[208,260,231],{"class":213},[208,262,263],{"class":217},"meta",[208,265,266],{"class":221}," charset",[208,268,239],{"class":213},[208,270,271],{"class":242},"\"utf-8\"",[208,273,225],{"class":213},[208,275,277,279,281,284,286],{"class":30,"line":276},5,[208,278,231],{"class":213},[208,280,71],{"class":217},[208,282,283],{"class":213},">Flex gap toolbar\u003C\u002F",[208,285,71],{"class":217},[208,287,225],{"class":213},[208,289,291,293,296],{"class":30,"line":290},6,[208,292,231],{"class":213},[208,294,295],{"class":217},"style",[208,297,225],{"class":213},[208,299,301,304,307,310,313,316,320,323,326,329,332,335,338,341,343,346,349],{"class":30,"line":300},7,[208,302,303],{"class":217},"  body",[208,305,306],{"class":213}," { ",[208,308,309],{"class":221},"font",[208,311,312],{"class":213},": ",[208,314,315],{"class":221},"15",[208,317,319],{"class":318},"sHUrx","px",[208,321,322],{"class":213},"\u002F",[208,324,325],{"class":221},"1.4",[208,327,328],{"class":221}," system-ui",[208,330,331],{"class":213},", ",[208,333,334],{"class":221},"sans-serif",[208,336,337],{"class":213},"; ",[208,339,340],{"class":221},"margin",[208,342,312],{"class":213},[208,344,345],{"class":221},"1",[208,347,348],{"class":318},"rem",[208,350,351],{"class":213},"; }\n",[208,353,355],{"class":30,"line":354},8,[208,356,358],{"emptyLinePlaceholder":357},true,"\n",[208,360,362,365],{"class":30,"line":361},9,[208,363,364],{"class":221},"  .toolbar",[208,366,367],{"class":213}," {\n",[208,369,371,374,376,379],{"class":30,"line":370},10,[208,372,373],{"class":221},"    display",[208,375,312],{"class":213},[208,377,378],{"class":221},"flex",[208,380,381],{"class":213},";\n",[208,383,385,388,390,393],{"class":30,"line":384},11,[208,386,387],{"class":221},"    flex-wrap",[208,389,312],{"class":213},[208,391,392],{"class":221},"wrap",[208,394,381],{"class":213},[208,396,398,401,403,406],{"class":30,"line":397},12,[208,399,400],{"class":221},"    align-items",[208,402,312],{"class":213},[208,404,405],{"class":221},"center",[208,407,381],{"class":213},[208,409,411],{"class":30,"line":410},13,[208,412,414],{"class":413},"sLBg1","    \u002F* row-gap column-gap: wrapped lines get more air than neighbours,\n",[208,416,418],{"class":30,"line":417},14,[208,419,420],{"class":413},"       so each line reads as its own group. *\u002F\n",[208,422,424,427,429,432,434,437,439],{"class":30,"line":423},15,[208,425,426],{"class":221},"    gap",[208,428,312],{"class":213},[208,430,431],{"class":221},"0.75",[208,433,348],{"class":318},[208,435,436],{"class":221}," 0.5",[208,438,348],{"class":318},[208,440,381],{"class":213},[208,442,444,447,449,451,453],{"class":30,"line":443},16,[208,445,446],{"class":221},"    padding",[208,448,312],{"class":213},[208,450,431],{"class":221},[208,452,348],{"class":318},[208,454,381],{"class":213},[208,456,458,461,463,465,467,470,473],{"class":30,"line":457},17,[208,459,460],{"class":221},"    border",[208,462,312],{"class":213},[208,464,345],{"class":221},[208,466,319],{"class":318},[208,468,469],{"class":221}," solid",[208,471,472],{"class":221}," #94a3b8",[208,474,381],{"class":213},[208,476,478,481,483,486,488],{"class":30,"line":477},18,[208,479,480],{"class":221},"    border-radius",[208,482,312],{"class":213},[208,484,485],{"class":221},"10",[208,487,319],{"class":318},[208,489,381],{"class":213},[208,491,493],{"class":30,"line":492},19,[208,494,495],{"class":213},"  }\n",[208,497,499],{"class":30,"line":498},20,[208,500,358],{"emptyLinePlaceholder":357},[208,502,504,506,509],{"class":30,"line":503},21,[208,505,364],{"class":221},[208,507,508],{"class":217}," button",[208,510,367],{"class":213},[208,512,514,516,518,521,523,526,528],{"class":30,"line":513},22,[208,515,446],{"class":221},[208,517,312],{"class":213},[208,519,520],{"class":221},"0.45",[208,522,348],{"class":318},[208,524,525],{"class":221}," 0.8",[208,527,348],{"class":318},[208,529,381],{"class":213},[208,531,533,535,537,539,541,543,545],{"class":30,"line":532},23,[208,534,460],{"class":221},[208,536,312],{"class":213},[208,538,345],{"class":221},[208,540,319],{"class":318},[208,542,469],{"class":221},[208,544,472],{"class":221},[208,546,381],{"class":213},[208,548,550,552,554,557,559],{"class":30,"line":549},24,[208,551,480],{"class":221},[208,553,312],{"class":213},[208,555,556],{"class":221},"6",[208,558,319],{"class":318},[208,560,381],{"class":213},[208,562,564,567,569,572],{"class":30,"line":563},25,[208,565,566],{"class":221},"    background",[208,568,312],{"class":213},[208,570,571],{"class":221},"transparent",[208,573,381],{"class":213},[208,575,577,580,582,585],{"class":30,"line":576},26,[208,578,579],{"class":221},"    font",[208,581,312],{"class":213},[208,583,584],{"class":221},"inherit",[208,586,381],{"class":213},[208,588,590],{"class":30,"line":589},27,[208,591,495],{"class":213},[208,593,595],{"class":30,"line":594},28,[208,596,358],{"emptyLinePlaceholder":357},[208,598,600],{"class":30,"line":599},29,[208,601,602],{"class":413},"  \u002F* The auto margin absorbs ALL remaining free space on the line,\n",[208,604,606],{"class":30,"line":605},30,[208,607,608],{"class":413},"     pushing this item and everything after it to the far end.\n",[208,610,612],{"class":30,"line":611},31,[208,613,614],{"class":413},"     Logical property, so it flips correctly in right-to-left text. *\u002F\n",[208,616,618,620,623],{"class":30,"line":617},32,[208,619,364],{"class":221},[208,621,622],{"class":221}," .push",[208,624,367],{"class":213},[208,626,628,631,633,636],{"class":30,"line":627},33,[208,629,630],{"class":221},"    margin-inline-start",[208,632,312],{"class":213},[208,634,635],{"class":221},"auto",[208,637,381],{"class":213},[208,639,641],{"class":30,"line":640},34,[208,642,495],{"class":213},[208,644,646],{"class":30,"line":645},35,[208,647,358],{"emptyLinePlaceholder":357},[208,649,651],{"class":30,"line":650},36,[208,652,653],{"class":413},"  \u002F* A divider between groups without an extra wrapper: a pseudo-element\n",[208,655,657],{"class":30,"line":656},37,[208,658,659],{"class":413},"     would be counted as a flex item, so draw it with a border instead. *\u002F\n",[208,661,663,665,668],{"class":30,"line":662},38,[208,664,364],{"class":221},[208,666,667],{"class":221}," .group-start",[208,669,367],{"class":213},[208,671,673,676,678,680,682],{"class":30,"line":672},39,[208,674,675],{"class":221},"    padding-inline-start",[208,677,312],{"class":213},[208,679,431],{"class":221},[208,681,348],{"class":318},[208,683,381],{"class":213},[208,685,687,690,692,694,696,698,700],{"class":30,"line":686},40,[208,688,689],{"class":221},"    border-inline-start",[208,691,312],{"class":213},[208,693,345],{"class":221},[208,695,319],{"class":318},[208,697,469],{"class":221},[208,699,472],{"class":221},[208,701,381],{"class":213},[208,703,705,708,710,713,716],{"class":30,"line":704},41,[208,706,707],{"class":221},"    align-self",[208,709,312],{"class":213},[208,711,712],{"class":221},"stretch",[208,714,715],{"class":213},";   ",[208,717,718],{"class":413},"\u002F* an empty span is 0px tall under align-items: center *\u002F\n",[208,720,722],{"class":30,"line":721},42,[208,723,495],{"class":213},[208,725,727],{"class":30,"line":726},43,[208,728,358],{"emptyLinePlaceholder":357},[208,730,732,734,736,739],{"class":30,"line":731},44,[208,733,364],{"class":221},[208,735,508],{"class":217},[208,737,738],{"class":221},":focus-visible",[208,740,367],{"class":213},[208,742,744,747,749,752,754,756,759],{"class":30,"line":743},45,[208,745,746],{"class":221},"    outline",[208,748,312],{"class":213},[208,750,751],{"class":221},"2",[208,753,319],{"class":318},[208,755,469],{"class":221},[208,757,758],{"class":221}," #2d5bff",[208,760,381],{"class":213},[208,762,764,767,769,771,773],{"class":30,"line":763},46,[208,765,766],{"class":221},"    outline-offset",[208,768,312],{"class":213},[208,770,751],{"class":221},[208,772,319],{"class":318},[208,774,381],{"class":213},[208,776,778],{"class":30,"line":777},47,[208,779,495],{"class":213},[208,781,783,786,788],{"class":30,"line":782},48,[208,784,785],{"class":213},"\u003C\u002F",[208,787,295],{"class":217},[208,789,225],{"class":213},[208,791,793,795,797],{"class":30,"line":792},49,[208,794,785],{"class":213},[208,796,253],{"class":217},[208,798,225],{"class":213},[208,800,802,804,807],{"class":30,"line":801},50,[208,803,231],{"class":213},[208,805,806],{"class":217},"body",[208,808,225],{"class":213},[208,810,812,815,818,821,823,826,829,831,833,836,838,841],{"class":30,"line":811},51,[208,813,814],{"class":213},"  \u003C",[208,816,817],{"class":217},"div",[208,819,820],{"class":221}," class",[208,822,239],{"class":213},[208,824,825],{"class":242},"\"toolbar\"",[208,827,828],{"class":221}," role",[208,830,239],{"class":213},[208,832,825],{"class":242},[208,834,835],{"class":221}," aria-label",[208,837,239],{"class":213},[208,839,840],{"class":242},"\"Formatting\"",[208,842,225],{"class":213},[208,844,846,849,852,855,857,860,863,865],{"class":30,"line":845},52,[208,847,848],{"class":213},"    \u003C",[208,850,851],{"class":217},"button",[208,853,854],{"class":221}," type",[208,856,239],{"class":213},[208,858,859],{"class":242},"\"button\"",[208,861,862],{"class":213},">Bold\u003C\u002F",[208,864,851],{"class":217},[208,866,225],{"class":213},[208,868,870,872,874,876,878,880,883,885],{"class":30,"line":869},53,[208,871,848],{"class":213},[208,873,851],{"class":217},[208,875,854],{"class":221},[208,877,239],{"class":213},[208,879,859],{"class":242},[208,881,882],{"class":213},">Italic\u003C\u002F",[208,884,851],{"class":217},[208,886,225],{"class":213},[208,888,890,892,894,896,898,900,903,905],{"class":30,"line":889},54,[208,891,848],{"class":213},[208,893,851],{"class":217},[208,895,854],{"class":221},[208,897,239],{"class":213},[208,899,859],{"class":242},[208,901,902],{"class":213},">Link\u003C\u002F",[208,904,851],{"class":217},[208,906,225],{"class":213},[208,908,910,912,914,916,918,921,924,926],{"class":30,"line":909},55,[208,911,848],{"class":213},[208,913,208],{"class":217},[208,915,820],{"class":221},[208,917,239],{"class":213},[208,919,920],{"class":242},"\"group-start\"",[208,922,923],{"class":213},">\u003C\u002F",[208,925,208],{"class":217},[208,927,225],{"class":213},[208,929,931,933,935,937,939,941,944,946],{"class":30,"line":930},56,[208,932,848],{"class":213},[208,934,851],{"class":217},[208,936,854],{"class":221},[208,938,239],{"class":213},[208,940,859],{"class":242},[208,942,943],{"class":213},">Bullet list\u003C\u002F",[208,945,851],{"class":217},[208,947,225],{"class":213},[208,949,951,953,955,957,959,961,964,966],{"class":30,"line":950},57,[208,952,848],{"class":213},[208,954,851],{"class":217},[208,956,854],{"class":221},[208,958,239],{"class":213},[208,960,859],{"class":242},[208,962,963],{"class":213},">Numbered list\u003C\u002F",[208,965,851],{"class":217},[208,967,225],{"class":213},[208,969,971,973,975,977,979,981,983,985,988,991,993],{"class":30,"line":970},58,[208,972,848],{"class":213},[208,974,851],{"class":217},[208,976,854],{"class":221},[208,978,239],{"class":213},[208,980,859],{"class":242},[208,982,820],{"class":221},[208,984,239],{"class":213},[208,986,987],{"class":242},"\"push\"",[208,989,990],{"class":213},">Publish\u003C\u002F",[208,992,851],{"class":217},[208,994,225],{"class":213},[208,996,998,1001,1003],{"class":30,"line":997},59,[208,999,1000],{"class":213},"  \u003C\u002F",[208,1002,817],{"class":217},[208,1004,225],{"class":213},[208,1006,1008,1010,1012],{"class":30,"line":1007},60,[208,1009,785],{"class":213},[208,1011,806],{"class":217},[208,1013,225],{"class":213},[208,1015,1017,1019,1021],{"class":30,"line":1016},61,[208,1018,785],{"class":213},[208,1020,203],{"class":217},[208,1022,225],{"class":213},[20,1024,1025,1026,1029,1030,1033],{},"Two decisions in that block are easy to miss. The group divider is a real element with a border rather than a ",[15,1027,1028],{},"::before"," on the button, because generated content on a flex container becomes a flex item and would receive a gap on both sides. And the auto margin sits on the item, not the container: auto margins resolve ",[28,1031,1032],{},"after"," gaps are placed, so the Publish button still keeps its gap from its neighbour and then takes every remaining pixel on its inline-start side.",[51,1035,1037],{"id":1036},"the-key-technique-gap-participates-in-line-breaking","The key technique: gap participates in line breaking",[20,1039,1040,1041,1043,1044,1047],{},"The reason ",[15,1042,17],{}," is more than a convenience is that the flex algorithm counts it when deciding where lines break. The hypothetical size of each line is the sum of its items' sizes ",[28,1045,1046],{},"plus"," the gaps between them, and a new line starts as soon as that sum would exceed the container. Nothing is subtracted after the fact.",[62,1049,69,1052,69,1055,69,1058,69,1061,69,1068,69,1074,69,1080,69,1083,69,1086,69,1090,69,1094,69,1097,69,1100,69,1103,69,1106,69,1110],{"viewBox":1050,"role":65,"ariaLabel":1051,"xmlns":67,"style":68},"0 0 720 280","Arithmetic showing three 200px items fit a 640px line with a 16px gap but wrap with a 32px gap",[71,1053,1054],{},"Gap in the line-break sum",[75,1056,1057],{},"Three 200 pixel items in a 640 pixel container: with 16 pixel gaps the line needs 632 pixels and fits; with 32 pixel gaps it needs 664 pixels and the third item wraps.",[79,1059,1060],{"textAnchor":81,"x":82,"y":83,"style":84},"The line must hold items plus gaps",[79,1062,1067],{"textAnchor":1063,"x":1064,"y":1065,"style":1066},"start","40","62","text-anchor:start;fill:currentColor;font:600 13px ui-monospace,monospace","gap 16px → 3 × 200 + 2 × 16 = 632 ≤ 640",[93,1069],{"x":1064,"y":1070,"width":1071,"height":1072,"rx":556,"fill":100,"stroke":101,"strokeWidth":102,"opacity":1073},"74","640","46","0.5",[93,1075],{"x":1076,"y":107,"width":1077,"height":1078,"rx":1079,"fill":110,"opacity":111},"44","200","34","4",[93,1081],{"x":1082,"y":107,"width":1077,"height":1078,"rx":1079,"fill":110,"opacity":111},"260",[93,1084],{"x":1085,"y":107,"width":1077,"height":1078,"rx":1079,"fill":110,"opacity":111},"476",[79,1087,1089],{"textAnchor":81,"x":82,"y":1088,"style":138},"102","fits on one line",[79,1091,1093],{"textAnchor":1063,"x":1064,"y":1092,"style":1066},"160","gap 32px → 3 × 200 + 2 × 32 = 664 > 640",[93,1095],{"x":1064,"y":1096,"width":1071,"height":157,"rx":556,"fill":100,"stroke":101,"strokeWidth":102,"opacity":1073},"172",[93,1098],{"x":1076,"y":1099,"width":1077,"height":1078,"rx":1079,"fill":110,"opacity":111},"178",[93,1101],{"x":1102,"y":1099,"width":1077,"height":1078,"rx":1079,"fill":110,"opacity":111},"276",[93,1104],{"x":1076,"y":1105,"width":1077,"height":1078,"rx":1079,"fill":110,"opacity":1073},"220",[79,1107,1109],{"textAnchor":81,"x":1108,"y":1077,"style":138},"580","no room left",[79,1111,1115],{"textAnchor":1063,"x":1112,"y":1113,"style":1114},"350","242","text-anchor:start;fill:currentColor;font:12px sans-serif","third item wraps",[20,1117,1118,1119,1121,1122,1126],{},"With margins, the same arithmetic counts the trailing margin of the last item on each line, so items wrap one gutter earlier than they should and the visible spacing never quite matches the numbers in the stylesheet. With ",[15,1120,17],{},", what you write is what the line-break sum uses, which makes wrap points predictable enough to reason about — the threshold behaviour described in ",[40,1123,1125],{"href":1124},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflex-wrap-intrinsic-responsive-rows\u002F","Breakpoint-Free Rows With flex-wrap"," relies on exactly this.",[20,1128,1129,1131,1132,1135,1136,1138],{},[15,1130,17],{}," also never collapses. Vertical margins between block siblings collapse to the larger of the two, but flex items do not collapse margins at all, and gaps are not margins, so a ",[15,1133,1134],{},"row-gap"," of 1rem is always 1rem. The mental model is simpler than block flow, which is one reason many teams now make every stack a flex or grid container purely to use ",[15,1137,17],{},".",[51,1140,1142],{"id":1141},"when-margins-are-still-the-right-tool","When margins are still the right tool",[20,1144,1145,1147],{},[15,1146,17],{}," is uniform: every pair of neighbours gets the same space. Real layouts often want exceptions, and those are still margin territory. The diagram below sorts the common cases.",[62,1149,69,1152,69,1155,69,1158,69,1161,69,1165,69,1169,69,1171,69,1174,69,1178,69,1183,69,1187,69,1190,69,1194,69,1198,69,1200,69,1203,69,1207,69,1209,69,1212,69,1215],{"viewBox":1150,"role":65,"ariaLabel":1151,"xmlns":67,"style":68},"0 0 720 290","Four spacing needs sorted between gap and margin",[71,1153,1154],{},"Gap or margin?",[75,1156,1157],{},"Uniform spacing and spacing between wrapped lines belong to gap; pushing one item to the far end and a one-off larger space before a heading belong to margins.",[79,1159,1160],{"textAnchor":81,"x":82,"y":83,"style":84},"Container spacing versus item exceptions",[93,1162],{"x":1064,"y":1072,"width":1163,"height":1078,"rx":99,"fill":110,"opacity":1164},"300","0.4",[79,1166,17],{"textAnchor":81,"x":1167,"y":96,"style":1168},"190","text-anchor:middle;fill:currentColor;font:600 14px ui-monospace,monospace",[93,1170],{"x":146,"y":1072,"width":1163,"height":1078,"rx":99,"fill":110,"opacity":1164},[79,1172,340],{"textAnchor":81,"x":1173,"y":96,"style":1168},"530",[93,1175],{"x":1064,"y":1176,"width":1163,"height":1177,"rx":99,"fill":100,"stroke":101,"strokeWidth":102,"opacity":103},"94","72",[79,1179,1182],{"textAnchor":81,"x":1167,"y":1180,"style":1181},"124","text-anchor:middle;fill:currentColor;font:13px sans-serif","Same space between",[79,1184,1186],{"textAnchor":81,"x":1167,"y":1185,"style":1181},"144","every pair of items",[93,1188],{"x":1064,"y":1189,"width":1163,"height":1177,"rx":99,"fill":100,"stroke":101,"strokeWidth":102,"opacity":103},"180",[79,1191,1193],{"textAnchor":81,"x":1167,"y":1192,"style":1181},"210","Space between",[79,1195,1197],{"textAnchor":81,"x":1167,"y":1196,"style":1181},"230","wrapped lines",[93,1199],{"x":146,"y":1176,"width":1163,"height":1177,"rx":99,"fill":100,"stroke":101,"strokeWidth":102,"opacity":103},[79,1201,1202],{"textAnchor":81,"x":1173,"y":1180,"style":1181},"Push one item to the end",[79,1204,1206],{"textAnchor":81,"x":1173,"y":1185,"style":1205},"text-anchor:middle;fill:currentColor;font:12px ui-monospace,monospace","margin-inline-start: auto",[93,1208],{"x":146,"y":1189,"width":1163,"height":1177,"rx":99,"fill":100,"stroke":101,"strokeWidth":102,"opacity":103},[79,1210,1211],{"textAnchor":81,"x":1173,"y":1192,"style":1181},"Extra space before one",[79,1213,1214],{"textAnchor":81,"x":1173,"y":1196,"style":1181},"item, added to the gap",[79,1216,1218],{"textAnchor":81,"x":82,"y":1217,"style":172},"280","A margin on a flex item adds to the gap rather than replacing it.",[20,1220,1221,1222,1225,1226,1229,1230,1232],{},"Remember that margins and gaps add. An item with ",[15,1223,1224],{},"margin-block-start: 1rem"," in a column container with ",[15,1227,1228],{},"gap: 1rem"," sits 2rem below its neighbour. That additive behaviour is useful — a heading inside a stack can take ",[15,1231,1224],{}," to get \"the usual gap plus a bit more\" without redefining the stack — but it surprises anyone expecting margins to collapse into the gap the way they collapse into each other in block flow.",[51,1234,1236],{"id":1235},"variation-a-fluid-gap-that-scales-with-the-container","Variation: a fluid gap that scales with the container",[20,1238,1239,1240,1242,1243,1247,1248,1251],{},"A fixed gap looks cramped on a wide dashboard and wasteful on a narrow card. Because ",[15,1241,17],{}," accepts any length, it can use ",[40,1244,1246],{"href":1245},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-query-units-cqi-cqb-explained\u002F","container query units"," inside ",[15,1249,1250],{},"clamp()",", so spacing scales with the component rather than the viewport.",[199,1253,1257],{"className":1254,"code":1255,"language":1256,"meta":204,"style":204},"language-css shiki shiki-themes github-light-high-contrast github-dark-high-contrast",".card-row-wrapper {\n  container-type: inline-size;\n}\n\n.card-row {\n  display: flex;\n  flex-wrap: wrap;\n  \u002F* 0.5rem on tiny containers, 1.5rem on wide ones, 3% of the\n     container's inline size in between. The rem floor and ceiling\n     keep the gap sensible under text zoom. *\u002F\n  gap: clamp(0.5rem, 3cqi, 1.5rem);\n}\n\n.card-row > * {\n  flex: 1 1 14rem;\n}\n","css",[15,1258,1259,1266,1274,1279,1283,1290,1301,1312,1317,1322,1327,1361,1365,1369,1381,1400],{"__ignoreMap":204},[208,1260,1261,1264],{"class":30,"line":210},[208,1262,1263],{"class":221},".card-row-wrapper",[208,1265,367],{"class":213},[208,1267,1268,1271],{"class":30,"line":228},[208,1269,1270],{"class":221},"  container-type",[208,1272,1273],{"class":213},": inline-size;\n",[208,1275,1276],{"class":30,"line":248},[208,1277,1278],{"class":213},"}\n",[208,1280,1281],{"class":30,"line":258},[208,1282,358],{"emptyLinePlaceholder":357},[208,1284,1285,1288],{"class":30,"line":276},[208,1286,1287],{"class":221},".card-row",[208,1289,367],{"class":213},[208,1291,1292,1295,1297,1299],{"class":30,"line":290},[208,1293,1294],{"class":221},"  display",[208,1296,312],{"class":213},[208,1298,378],{"class":221},[208,1300,381],{"class":213},[208,1302,1303,1306,1308,1310],{"class":30,"line":300},[208,1304,1305],{"class":221},"  flex-wrap",[208,1307,312],{"class":213},[208,1309,392],{"class":221},[208,1311,381],{"class":213},[208,1313,1314],{"class":30,"line":354},[208,1315,1316],{"class":413},"  \u002F* 0.5rem on tiny containers, 1.5rem on wide ones, 3% of the\n",[208,1318,1319],{"class":30,"line":361},[208,1320,1321],{"class":413},"     container's inline size in between. The rem floor and ceiling\n",[208,1323,1324],{"class":30,"line":370},[208,1325,1326],{"class":413},"     keep the gap sensible under text zoom. *\u002F\n",[208,1328,1329,1332,1334,1337,1340,1342,1344,1346,1349,1352,1354,1356,1358],{"class":30,"line":384},[208,1330,1331],{"class":221},"  gap",[208,1333,312],{"class":213},[208,1335,1336],{"class":221},"clamp",[208,1338,1339],{"class":213},"(",[208,1341,1073],{"class":221},[208,1343,348],{"class":318},[208,1345,331],{"class":213},[208,1347,1348],{"class":221},"3",[208,1350,1351],{"class":318},"cqi",[208,1353,331],{"class":213},[208,1355,102],{"class":221},[208,1357,348],{"class":318},[208,1359,1360],{"class":213},");\n",[208,1362,1363],{"class":30,"line":397},[208,1364,1278],{"class":213},[208,1366,1367],{"class":30,"line":410},[208,1368,358],{"emptyLinePlaceholder":357},[208,1370,1371,1373,1376,1379],{"class":30,"line":417},[208,1372,1287],{"class":221},[208,1374,1375],{"class":318}," >",[208,1377,1378],{"class":217}," *",[208,1380,367],{"class":213},[208,1382,1383,1386,1388,1390,1393,1396,1398],{"class":30,"line":423},[208,1384,1385],{"class":221},"  flex",[208,1387,312],{"class":213},[208,1389,345],{"class":221},[208,1391,1392],{"class":221}," 1",[208,1394,1395],{"class":221}," 14",[208,1397,348],{"class":318},[208,1399,381],{"class":213},[208,1401,1402],{"class":30,"line":443},[208,1403,1278],{"class":213},[20,1405,1406,1407,1411,1412,1416],{},"Because the gap is part of the line-break sum, a fluid gap also shifts the wrap points slightly as the container grows. That is usually desirable — the row keeps its proportions — but it is worth knowing when a test asserts an exact wrap width. For a whole spacing system built this way, ",[40,1408,1410],{"href":1409},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-space-scale-with-clamp\u002F","Fluid Space Scale With clamp()"," builds matched steps rather than one-off values. The same custom-property approach can drive motion as well: ",[40,1413,1415],{"href":1414},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Ffluid-spacing-tokens-driving-transition-durations\u002F","fluid spacing tokens driving transition durations"," ties a component's timing to the same scale.",[51,1418,1420],{"id":1419},"migrating-an-existing-margin-based-system","Migrating an existing margin-based system",[20,1422,1423,1424,1427,1428,1431],{},"Most codebases do not start fresh. They have a utility such as ",[15,1425,1426],{},".stack > * + * { margin-block-start: 1rem }"," — the \"lobotomized owl\" selector — or a ",[15,1429,1430],{},".row > * { margin-right: 1rem }"," with a last-child reset scattered across components. Replacing them all at once is risky because some components depend on the margin for reasons nobody documented, such as a card that relies on its own bottom margin when it is used outside the stack.",[20,1433,1434,1435,1438,1439,1442,1443,1445,1446,1449],{},"A safe migration runs in three passes. First, add ",[15,1436,1437],{},"display: flex; flex-direction: column; gap: var(--stack-space)"," to the stack utility ",[28,1440,1441],{},"alongside"," the owl rule, and set the owl margin to the same custom property. For one release, both exist, and because flex items do not collapse margins, every gap is temporarily doubled — which is visible, testable, and easy to find in a screenshot diff. Second, delete the owl rule. The doubling disappears and the spacing returns to the intended value, now produced by the container. Third, search for ",[15,1444,25],{}," and ",[15,1447,1448],{},":first-child"," margin resets and delete those that only existed to cancel the old gutter.",[20,1451,1452,1453,1456,1457,1460,1461,1463,1464,1467],{},"Two things change behaviour during the switch and should be checked on real pages. Hidden children — elements with ",[15,1454,1455],{},"display: none"," — never received the owl margin and never receive a gap, so they are safe, but elements hidden with ",[15,1458,1459],{},"visibility: hidden"," or zero opacity still occupy a flex slot and still get gaps on both sides. And absolutely positioned children are taken out of flow, so they are skipped by ",[15,1462,17],{}," exactly as they were by the owl selector's adjacency, but a ",[15,1465,1466],{},"position: sticky"," child is still in flow and still gets spaced. Neither is a bug, but both can move a pixel-perfect layout by a gap's width.",[51,1469,1471],{"id":1470},"browser-support","Browser support",[20,1473,1474,1476,1477,1479,1480,1483,1484,1486,1487,1489],{},[15,1475,17],{}," for flex containers is supported in every current engine; it shipped years after grid gap, so very old browsers that support flexbox but not flex ",[15,1478,17],{}," render items touching, which is a cosmetic failure rather than a broken layout. Logical margin properties such as ",[15,1481,1482],{},"margin-inline-start"," are equally universal in current browsers. The container query units in the variation need Chrome and Edge 105+, Firefox 110+ or Safari 16+, and ",[15,1485,1250],{}," needs Chrome and Edge 79+, Firefox 75+ or Safari 13.1+. A plain ",[15,1488,1228],{}," before the fluid declaration covers anything older.",[51,1491,1493],{"id":1492},"faq","FAQ",[20,1495,1496,1503,1504,1506],{},[1497,1498,1499,1500,1502],"strong",{},"Does ",[15,1501,17],{}," add space before the first item or after the last one?","\nNo. ",[15,1505,17],{}," only inserts space between adjacent items and between adjacent lines, never along the container's edges. That is the main reason to prefer it over margins, which need a first-child or last-child exception to avoid an outer gutter.",[20,1508,1509,1515,1516,1519,1520,1522,1523,1525],{},[1497,1510,1511,1512,1514],{},"Can ",[15,1513,17],{}," take a percentage value in a flex container?","\nYes, it resolves against the container's content box in the relevant axis. In a row container a percentage ",[15,1517,1518],{},"column-gap"," is a share of the width. A percentage ",[15,1521,1134],{}," needs a definite container height, otherwise it behaves as zero, so use a length or a fluid ",[15,1524,1250],{}," value for rows.",[20,1527,1528,1534,1535,1537,1538,1540],{},[1497,1529,1530,1531,1533],{},"Are auto margins still useful now that ",[15,1532,17],{}," exists?","\nYes, for a completely different job. ",[15,1536,17],{}," sets fixed spacing between every pair of items, while ",[15,1539,1206],{}," absorbs all free space on one side of a single item, which is how you push a logout button to the far end of a toolbar.",[20,1542,1543,1549,1550,1552],{},[1497,1544,1545,1546,1548],{},"Why does my row wrap earlier after I increased ",[15,1547,17],{},"?","\nBecause ",[15,1551,17],{}," is included in the line-break calculation. Each item plus the gaps before it must fit in the line, so a larger gap leaves less room for items and the line breaks sooner. This is correct behaviour and one of the advantages over margins.",[51,1554,1556],{"id":1555},"related","Related",[1558,1559,1560,1566,1573,1580,1585],"ul",{},[1561,1562,1563,1565],"li",{},[40,1564,43],{"href":42}," — the parent guide for flex-based components.",[1561,1567,1568,1572],{},[40,1569,1571],{"href":1570},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflex-basis-vs-width\u002F","flex-basis vs width"," — the item sizes that the gap is added to.",[1561,1574,1575,1579],{},[40,1576,1578],{"href":1577},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fcentering-in-css-every-method\u002F","Centering in CSS: Every Method"," — auto margins used for alignment rather than spacing.",[1561,1581,1582,1584],{},[40,1583,1410],{"href":1409}," — a whole spacing system for gaps.",[1561,1586,1587,1591],{},[40,1588,1590],{"href":1589},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fstaggered-list-animations-with-custom-properties\u002F","Staggered List Animations With Custom Properties"," — animating the items a gap separates.",[295,1593,1594],{},"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":204,"searchDepth":228,"depth":228,"links":1596},[1597,1598,1599,1600,1601,1602,1603,1604,1605],{"id":53,"depth":228,"text":54},{"id":186,"depth":228,"text":187},{"id":1036,"depth":228,"text":1037},{"id":1141,"depth":228,"text":1142},{"id":1235,"depth":228,"text":1236},{"id":1419,"depth":228,"text":1420},{"id":1470,"depth":228,"text":1471},{"id":1492,"depth":228,"text":1493},{"id":1555,"depth":228,"text":1556},"Replace margin hacks with gap in flex layouts: how gap takes part in wrapping, why margins leave gutters at line ends, and where auto margins still win.","md",{"pageTitle":1609,"datePublished":1610,"dateModified":1610,"faq":1611},"Flexbox gap vs Margins for Spacing","2026-09-18",[1612,1615,1618,1621],{"q":1613,"a":1614},"Does gap add space before the first item or after the last one?","No. gap only inserts space between adjacent items and between adjacent lines, never along the container's edges. That is the main reason to prefer it over margins, which need a first-child or last-child exception to avoid an outer gutter.",{"q":1616,"a":1617},"Can gap take a percentage value in a flex container?","Yes, it resolves against the container's content box in the relevant axis. In a row container a percentage column-gap is a share of the width. A percentage row-gap needs a definite container height, otherwise it behaves as zero, so use a length or a fluid clamp() value for rows.",{"q":1619,"a":1620},"Are auto margins still useful now that gap exists?","Yes, for a completely different job. gap sets fixed spacing between every pair of items, while margin-inline-start: auto absorbs all free space on one side of a single item, which is how you push a logout button to the far end of a toolbar.",{"q":1622,"a":1623},"Why does my row wrap earlier after I increased gap?","Because gap is included in the line-break calculation. Each item plus the gaps before it must fit in the line, so a larger gap leaves less room for items and the line breaks sooner. This is correct behaviour and one of the advantages over margins.","\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflexbox-gap-and-spacing",{"title":5,"description":1606},"mastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflexbox-gap-and-spacing\u002Findex","mcwqiD8gaYks_hfsQ-ppVvcfpMyEtaLGv3WddfNAYs4",[1629,1632,1635,1638,1641,1644,1647,1650,1653,1656,1659,1662,1665,1668,1671,1674,1677,1680,1683,1686,1689,1692,1695,1698,1701,1704,1707,1710,1713,1716,1719,1722,1725,1728,1731,1734,1737,1740,1743,1746,1749,1752,1755,1758,1761,1764,1767,1770,1773,1776,1779,1782,1785,1788,1791,1794,1797,1800,1803,1806,1809,1812,1815,1818,1821,1824,1827,1830,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,1910,1913,1916,1919,1922,1925,1928,1931,1934,1937,1940,1943,1946,1949,1952,1955,1958,1961,1964,1967,1970,1973,1976,1979,1982,1985,1988,1991,1994,1997,2000,2003,2006,2009,2012,2015,2016,2019,2022,2025,2028,2031,2034,2037,2040,2043,2046,2048,2051,2054,2057,2060,2063,2066,2069,2072,2075,2078,2081,2084,2087,2090,2093,2096,2099,2102,2105,2108,2111,2114,2117,2120,2123,2126,2129,2132,2135,2138,2141,2144,2147,2150,2153,2156,2159,2162,2165,2168,2171,2174,2177,2180,2183],{"path":1630,"title":1631},"\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":1633,"title":1634},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fflashing-content-and-seizure-thresholds","Flashing Content and Seizure Thresholds",{"path":1636,"title":1637},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fforced-colors-mode-and-animations","Forced Colors Mode and Animations",{"path":1639,"title":1640},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations","Accessibility in CSS Animations: Patterns, Specs & Best Practices",{"path":1642,"title":1643},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fpause-controls-for-looping-animations","Pause Controls for Looping CSS Animations: Meeting WCAG 2.2.2",{"path":1645,"title":1646},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fprefers-reduced-motion-recipes","prefers-reduced-motion Recipes: A Reduction for Every Common Effect",{"path":1648,"title":1649},"\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":1651,"title":1652},"\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":1654,"title":1655},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fvestibular-safe-animation-patterns","Vestibular-Safe Animation Patterns: Why Some Motion Makes People Sick",{"path":1657,"title":1658},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fwcag-motion-success-criteria","WCAG Motion Success Criteria: What Each One Actually Requires",{"path":1660,"title":1661},"\u002Fcss-only-micro-interactions-animations\u002Fclip-path-and-mask-animations\u002Fanimated-gradient-borders-with-property","Animated Gradient Borders With @property: A Spinning Highlight Without Extra Elements",{"path":1663,"title":1664},"\u002Fcss-only-micro-interactions-animations\u002Fclip-path-and-mask-animations\u002Fclip-path-reveal-animations","Clip-Path Reveal Animations: Wipes, Irises and Corners Without Extra Markup",{"path":1666,"title":1667},"\u002Fcss-only-micro-interactions-animations\u002Fclip-path-and-mask-animations","Clip-Path & Mask Animations: Animating Visibility Instead of Position",{"path":1669,"title":1670},"\u002Fcss-only-micro-interactions-animations\u002Fclip-path-and-mask-animations\u002Fmask-image-fade-edges","Fading Edges With mask-image: Soft Boundaries That Work on Any Background",{"path":1672,"title":1673},"\u002Fcss-only-micro-interactions-animations\u002Fclip-path-and-mask-animations\u002Fmorphing-shapes-with-clip-path-polygon","Morphing Shapes With clip-path: polygon(): Point-Matched Transitions",{"path":1675,"title":1676},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions\u002Fanimating-gradients","Animating CSS Gradients: Smooth Colour Motion Without Jumps",{"path":1678,"title":1679},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions\u002Fcolor-mix-hover-states","Hover and Active States With color-mix(): One Token, Every Shade",{"path":1681,"title":1682},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions","Color & Theme Transitions: Colour as Part of the Motion System",{"path":1684,"title":1685},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions\u002Flight-dark-function-for-themes","Light and Dark Themes With light-dark(): One Declaration per Colour",{"path":1687,"title":1688},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions\u002Fsmooth-theme-switching-transitions","Smooth Theme Switching: Crossfades, Circular Reveals and No Flash",{"path":1690,"title":1691},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fcontainer-query-hover-affordances","Container Query Hover Affordances: When Narrow Means Persistent, Not Hidden",{"path":1693,"title":1694},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion","Container-Aware Motion: Animation Sized by the Space a Component Actually Has",{"path":1696,"title":1697},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Flayout-change-animations-at-container-breakpoints","Animating Changes at Container Breakpoints",{"path":1699,"title":1700},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fmotion-driven-by-container-style-queries","Motion Driven by Container Style Queries",{"path":1702,"title":1703},"\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":1705,"title":1706},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fsuppressing-motion-in-small-containers","Suppressing Motion in Small Containers: Deliberately Animating Nothing",{"path":1708,"title":1709},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api\u002Fcontrolling-css-animations-from-javascript","Controlling CSS Animations From JavaScript",{"path":1711,"title":1712},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api","CSS Animation vs the Web Animations API: A Decision Guide",{"path":1714,"title":1715},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api\u002Fwaapi-vs-css-for-interruptible-ui","Interruptible UI: CSS Transitions vs WAAPI",{"path":1717,"title":1718},"\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":1720,"title":1721},"\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":1723,"title":1724},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Fcustom-property-fallbacks-and-invalid-values","Custom Property Fallbacks and Invalid Values",{"path":1726,"title":1727},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Ffluid-spacing-tokens-driving-transition-durations","Fluid Spacing Tokens That Drive Transition Durations",{"path":1729,"title":1730},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture","CSS Custom Properties Architecture: Scalable Design Systems & Dynamic UI",{"path":1732,"title":1733},"\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":1735,"title":1736},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Fscoping-custom-properties-to-components","Scoping Custom Properties to Components",{"path":1738,"title":1739},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fcss-transition-timing-functions","CSS Transition Timing Functions: ease, cubic-bezier(), steps() and linear()",{"path":1741,"title":1742},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals","CSS Transition Fundamentals: Architecture, Performance & Patterns",{"path":1744,"title":1745},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Finterrupted-and-reversing-transitions","Interrupted and Reversing Transitions: What Happens Mid-Flight",{"path":1747,"title":1748},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fstarting-style-entry-animations","@starting-style: Animating an Element's Very First Style Change",{"path":1750,"title":1751},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransition-delay-choreography","Choreographing Motion With transition-delay",{"path":1753,"title":1754},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransition-shorthand-and-multiple-properties","The transition Shorthand and Multiple Properties",{"path":1756,"title":1757},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransitioning-display-with-allow-discrete","Transitioning display with transition-behavior: allow-discrete and @starting-style",{"path":1759,"title":1760},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Fanimating-dialog-open-and-close","Animating \u003Cdialog> Open and Close: Both Directions, No Library",{"path":1762,"title":1763},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Fbackdrop-animations","Animating ::backdrop: Fades and Blurs Behind Dialogs and Popovers",{"path":1765,"title":1766},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations","Dialog & Popover Animations: Motion for the Top Layer",{"path":1768,"title":1769},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Finterpolate-size-for-height-auto-animation","Animating to height: auto With interpolate-size and calc-size()",{"path":1771,"title":1772},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Fpopover-entry-and-exit-transitions","Popover Menus That Animate From Their Anchor",{"path":1774,"title":1775},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fchoosing-animation-durations","Choosing Animation Durations: How Long Motion Should Last",{"path":1777,"title":1778},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fcubic-bezier-overshoot-and-anticipation","Overshoot and Anticipation With cubic-bezier(): Motion With Character",{"path":1780,"title":1781},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fentry-vs-exit-easing","Entry vs Exit Easing: Different Curves for Arriving and Leaving",{"path":1783,"title":1784},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design","Easing & Motion Design: Making CSS Motion Feel Intentional",{"path":1786,"title":1787},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Flinear-easing-function-for-springs","Spring and Bounce Easing With linear(): Physical Motion Without JavaScript",{"path":1789,"title":1790},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fsteps-easing-for-sprite-animations","steps() Easing: Sprite Sheets, Typewriters and Other Frame-by-Frame Effects",{"path":1792,"title":1793},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Faccessible-css-only-tooltips","Accessible CSS-Only Tooltips and Hover Cards With  and ",{"path":1795,"title":1796},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Fbutton-press-and-active-states","Button Press and  States",{"path":1798,"title":1799},"\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":1801,"title":1802},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Ffocus-within-form-patterns"," Form Patterns: Styling a Group From the Field Inside It",{"path":1804,"title":1805},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Fhover-intent-delays-with-transition-delay","Hover Intent Delays With transition-delay: Menus That Don't Flicker",{"path":1807,"title":1808},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design","Hover & Focus State Design: Spec-Compliant Patterns for Modern UIs",{"path":1810,"title":1811},"\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":1813,"title":1814},"\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":1816,"title":1817},"\u002Fcss-only-micro-interactions-animations","CSS-Only Micro-Interactions & Animations: Architecture, Performance & Implementation",{"path":1819,"title":1820},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fanimation-composition-and-stacking","Stacking Animations With animation-composition",{"path":1822,"title":1823},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fanimation-fill-mode-explained","animation-fill-mode: What an Animation Applies Before and After It Runs",{"path":1825,"title":1826},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcontainer-query-triggered-keyframe-animations","Container-Query-Triggered Keyframe Animations: Animate Differently per Available Space",{"path":1828,"title":1829},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcss-only-accordions-and-disclosure","CSS-Only Accordions and Disclosure Widgets with details and summary",{"path":1831,"title":1832},"\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":1834,"title":1835},"\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":1837,"title":1838},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns","Keyframe Animation Patterns: Spec-Compliant Architectures for Modern UIs",{"path":1840,"title":1841},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fmulti-step-keyframes-and-per-keyframe-easing","Multi-Step Keyframes and Per-Keyframe Easing",{"path":1843,"title":1844},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fstaggered-list-animations-with-custom-properties","Staggered List Animations Using --i Index Custom Properties",{"path":1846,"title":1847},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fanimating-box-shadow-and-filters-cheaply","Animating box-shadow and Filters Cheaply",{"path":1849,"title":1850},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fcontain-property-for-animation-performance","The contain Property for Animation Performance",{"path":1852,"title":1853},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fcss-triggers-layout-paint-composite","Layout, Paint and Composite: What Triggers What",{"path":1855,"title":1856},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration","Performance & GPU Acceleration in CSS: A Developer’s Blueprint",{"path":1858,"title":1859},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Foptimizing-css-animations-for-60fps","Optimizing CSS Animations for 60fps: Budgeting the Frame",{"path":1861,"title":1862},"\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":1864,"title":1865},"\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":1867,"title":1868},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations","Scroll-Driven Animations: Binding Motion to Scroll Position in Pure CSS",{"path":1870,"title":1871},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-driven-animation-fallbacks","Shipping Scroll-Driven Animations Without Breaking Anything",{"path":1873,"title":1874},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-driven-parallax-effects","Scroll-Driven Parallax Effects in CSS",{"path":1876,"title":1877},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-progress-bar-without-javascript","A Reading Progress Bar Driven by scroll(root)",{"path":1879,"title":1880},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-triggered-reveal-animations","Reveal-on-Scroll with view() and animation-range",{"path":1882,"title":1883},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Ftimeline-scope-for-cross-element-animations","timeline-scope for Cross-Element Animations",{"path":1885,"title":1886},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fview-timeline-and-animation-range","View Timelines and animation-range",{"path":1888,"title":1889},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fcross-document-view-transitions","Cross-Document View Transitions",{"path":1891,"title":1892},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers","View Transitions for CSS Developers: the Pseudo-Element Tree, Snapshots, and Named Elements",{"path":1894,"title":1895},"\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":1897,"title":1898},"\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":1900,"title":1901},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transition-types-and-classes","View Transition Types and Classes",{"path":1903,"title":1904},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transitions-for-list-reordering","View Transitions for List Reordering",{"path":1906,"title":1907},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transitions-with-reduced-motion","Honouring prefers-reduced-motion in View Transitions",{"path":322,"title":1909},"Modern CSS Layouts & Micro-Interactions",{"path":1911,"title":1912},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-positioned-tooltips","Anchor-Positioned Tooltips: Tethering, Flipping, and Getting the Semantics Right",{"path":1914,"title":1915},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-positioning-fallbacks","Anchor Positioning Fallbacks: A Graceful Floor for Older Browser Versions",{"path":1917,"title":1918},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-size-for-matching-widths","anchor-size(): Overlays That Match Their Trigger's Size",{"path":1920,"title":1921},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays","CSS Anchor Positioning and Overlays: Tethering Elements Without JavaScript",{"path":1923,"title":1924},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fpopover-attribute-and-css-styling","The popover Attribute: Top-Layer Overlays With No JavaScript",{"path":1926,"title":1927},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fpopover-light-dismiss-and-stacking","Popover Light Dismiss, Nesting and Stacking",{"path":1929,"title":1930},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fposition-area-grid-explained","position-area: The Anchor Placement Grid",{"path":1932,"title":1933},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fcontainer-query-polyfill-tradeoffs","Container Query Polyfills: What They Cost and When to Skip Them",{"path":1935,"title":1936},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Ffeature-detection-with-supports","Feature Detection with @supports: Syntax, Semantics, and the Traps",{"path":1938,"title":1939},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fhandling-container-query-fallbacks-for-older-browsers","Handling Container Query Fallbacks for Older Browsers",{"path":1941,"title":1942},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks","Container Query Fallbacks: Spec-Compliant CSS Strategies for Legacy Browsers",{"path":1944,"title":1945},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fintrinsic-layout-fallbacks-without-queries","Intrinsic Layout Fallbacks: Baselines That Adapt Without Any Query",{"path":1947,"title":1948},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Ftesting-fallbacks-without-old-browsers","Testing CSS Fallbacks Without an Old Browser",{"path":1950,"title":1951},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-queries-inside-css-nesting","Container Queries Inside CSS Nesting: Keeping Responses Next to the Styles They Change",{"path":1953,"title":1954},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-query-range-and-logic-operators","Container Query Range Syntax and Logic Operators",{"path":1956,"title":1957},"\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":1959,"title":1960},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-type-size-vs-inline-size","Choosing container-type: inline-size, size, or normal",{"path":1962,"title":1963},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-vs-media-queries-comparison","Container vs Media Queries: Choosing the Right Reference Box",{"path":1965,"title":1966},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fdebugging-container-queries-in-devtools","Debugging Container Queries in DevTools: Why a Rule Doesn't Match",{"path":1968,"title":1969},"\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":1971,"title":1972},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics","Container Query Syntax Basics",{"path":1974,"title":1975},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fnesting-and-naming-container-queries","Nesting and Naming Container Queries: Targeting the Right Ancestor",{"path":1977,"title":1978},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fauto-fit-minmax-responsive-grids","Responsive Grids with repeat(auto-fit, minmax())",{"path":1980,"title":1981},"\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":1983,"title":1984},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fgrid-auto-flow-dense-packing","grid-auto-flow: dense for Packed Layouts",{"path":1986,"title":1987},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fgrid-template-areas-responsive-layouts","Responsive Layouts With grid-template-areas: Rearranging Regions by Name",{"path":1989,"title":1990},"\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":1992,"title":1993},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts","CSS Grid and Subgrid Layouts for Responsive Interfaces",{"path":1995,"title":1996},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fmasonry-style-layouts-with-grid","Masonry-Style Layouts With the CSS That Ships Today",{"path":1998,"title":1999},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Foverlapping-elements-with-grid-stacking","Overlapping Elements With Grid Stacking: Layers Without position: absolute",{"path":2001,"title":2002},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fsubgrid-vs-nested-grid","Subgrid vs an Independently Nested Grid",{"path":2004,"title":2005},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fcentering-in-css-every-method","Centering in CSS: Every Modern Method and When Each One Breaks",{"path":2007,"title":2008},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflex-basis-vs-width","flex-basis vs width: Which Size a Flex Item Actually Starts From",{"path":2010,"title":2011},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflex-grow-and-flex-shrink-explained","flex-grow and flex-shrink Explained",{"path":2013,"title":2014},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflex-wrap-intrinsic-responsive-rows","Breakpoint-Free Responsive Rows With flex-wrap and flex-basis",{"path":1624,"title":5},{"path":2017,"title":2018},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns","Flexbox Layout Patterns: One-Dimensional Layout for Real Components",{"path":2020,"title":2021},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fsticky-footer-with-flexbox-and-grid","Sticky Footer With Flexbox or Grid: Pinning the Footer on Short Pages",{"path":2023,"title":2024},"\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":2026,"title":2027},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Fdebugging-clamp-values","Debugging clamp(): Values That Are Ignored, Stuck or Never Fluid",{"path":2029,"title":2030},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-line-height-and-measure","Fluid Line Height and Measure: Keeping Text Readable as It Scales",{"path":2032,"title":2033},"\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":2035,"title":2036},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-type-accessibility-and-zoom","Fluid Type, Accessibility and Zoom: The vw-Only Trap",{"path":2038,"title":2039},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-typography-without-javascript","Fluid Typography Without JavaScript: A Precision CSS Reference",{"path":2041,"title":2042},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp","Fluid Typography with clamp(): A Practical Guide for Modern CSS",{"path":2044,"title":2045},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ftext-wrap-balance-and-pretty","text-wrap: balance and pretty: Better Line Breaks Without Manual Breaks",{"path":2047,"title":48},"\u002Fmastering-container-queries-responsive-layouts",{"path":2049,"title":2050},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Faspect-ratio-for-responsive-media","Using aspect-ratio for Responsive Media and Preventing Layout Shift",{"path":2052,"title":2053},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fcontent-visibility-and-contain-intrinsic-size","content-visibility and contain-intrinsic-size: Rendering Only What Is Near the Screen",{"path":2055,"title":2056},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques","Intrinsic Sizing Techniques: Modern CSS Layouts for Responsive UI",{"path":2058,"title":2059},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Flayout-widths-with-min-max-clamp","Layout Widths With min(), max() and clamp(): Sizing Without Breakpoints",{"path":2061,"title":2062},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fmin-max-fit-content-explained","min-content, max-content, and fit-content() Explained",{"path":2064,"title":2065},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fobject-fit-and-object-position","object-fit and object-position: Images That Fit Any Box",{"path":2067,"title":2068},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fpreventing-flex-and-grid-overflow","The min-width: auto Trap in Flex and Grid Layouts",{"path":2070,"title":2071},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-for-reset-and-tokens","Cascade Layers for Reset and Design Tokens",{"path":2073,"title":2074},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-vs-specificity-hacks","Cascade Layers vs Specificity Hacks: Ordering Instead of Escalating",{"path":2076,"title":2077},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcss-scope-for-component-styles","@scope for Component Styles: Short Selectors That Cannot Leak",{"path":2079,"title":2080},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies","Modern CSS Reset Strategies: A Spec-Compliant Foundation",{"path":2082,"title":2083},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Frevert-layer-and-revert-keywords","initial, inherit, unset, revert and revert-layer: Undoing Styles Correctly",{"path":2085,"title":2086},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fwriting-a-minimal-modern-reset","Writing a Minimal Modern CSS Reset: Every Line Justified",{"path":2088,"title":2089},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has\u002Fcontent-aware-card-layouts-with-has","Content-Aware Card Layouts With :has(): One Component, Many Shapes",{"path":2091,"title":2092},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has\u002Fempty-and-loading-states-with-has","Empty and Loading States With ()",{"path":2094,"title":2095},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has\u002Fform-validation-layouts-with-has","Form Validation Layouts With :has(): Styling Groups From Field State",{"path":2097,"title":2098},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has\u002Fhas-selector-performance",":has() Selector Performance: What Is Cheap, What Is Not, and How to Measure",{"path":2100,"title":2101},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has\u002Fhas-vs-container-style-queries",":has() vs Container Style Queries: Discovered State and Published State",{"path":2103,"title":2104},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has","Parent-Aware Layouts With :has(): Letting Containers React to Their Contents",{"path":2106,"title":2107},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has\u002Fquantity-queries-with-has","Quantity Queries With :has(): Layouts That Respond to How Many Items There Are",{"path":2109,"title":2110},"\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":2112,"title":2113},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fcontainer-query-data-tables","Container Query Data Tables: Reflowing Tables to Cards",{"path":2115,"title":2116},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fcontainer-query-sidebar-layouts","Container Query Sidebar Layouts That Travel Between Contexts",{"path":2118,"title":2119},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns","Responsive Component Patterns: Architecture & Implementation",{"path":2121,"title":2122},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-forms-with-container-queries","Responsive Forms with Container Queries: Reflow Without Losing the Wiring",{"path":2124,"title":2125},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-hero-sections-with-container-queries","Responsive Hero Sections With Container Queries",{"path":2127,"title":2128},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-navigation-without-media-queries","Responsive Navigation Without Media Queries Using Container Queries",{"path":2130,"title":2131},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-pricing-tables","Responsive Pricing Tables: Aligned Features, a Clear Recommendation, Any Width",{"path":2133,"title":2134},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Ftabs-that-become-accordions","Tabs That Become an Accordion: One Component, Two Layouts",{"path":2136,"title":2137},"\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts\u002Fcss-only-carousel-with-scroll-snap","A CSS-Only Carousel With Scroll Snap",{"path":2139,"title":2140},"\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts\u002Fhorizontal-scrolling-card-rows","Horizontal Scrolling Card Rows: Swipeable Lists That Stay in Their Lane",{"path":2142,"title":2143},"\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts","Scroll Snap & Overflow Layouts: Designing Components That Scroll on Purpose",{"path":2145,"title":2146},"\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts\u002Foverscroll-behavior-for-nested-scrolling","overscroll-behavior: Taming Nested Scrolling, Pull-to-Refresh and Back-Swipe",{"path":2148,"title":2149},"\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts\u002Fscroll-margin-and-scroll-padding-for-sticky-headers","scroll-margin and scroll-padding: Keeping Targets Clear of Sticky Headers",{"path":2151,"title":2152},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fcombining-size-and-style-queries","Combining Size and Style Container Queries",{"path":2154,"title":2155},"\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":2157,"title":2158},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state","Style Queries and Container State: Token-Driven Component Variants",{"path":2160,"title":2161},"\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":2163,"title":2164},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fstyle-query-component-variants","Component Variants With Style Queries: One Token, Many Looks",{"path":2166,"title":2167},"\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",{"path":2169,"title":2170},"\u002Fmastering-container-queries-responsive-layouts\u002Fviewport-units-and-mobile-layout\u002Fdvh-svh-lvh-mobile-viewport-units","dvh, svh and lvh: Choosing the Right Mobile Viewport Unit",{"path":2172,"title":2173},"\u002Fmastering-container-queries-responsive-layouts\u002Fviewport-units-and-mobile-layout\u002Ffull-bleed-sections-in-constrained-layouts","Full-Bleed Sections in a Constrained Layout: Breaking Out Without Breaking the Page",{"path":2175,"title":2176},"\u002Fmastering-container-queries-responsive-layouts\u002Fviewport-units-and-mobile-layout","Viewport Units & Mobile Layout: Designing for the Screen You Actually Get",{"path":2178,"title":2179},"\u002Fmastering-container-queries-responsive-layouts\u002Fviewport-units-and-mobile-layout\u002Fsafe-area-insets-for-notched-screens","Safe Area Insets: Designing Around Notches, Corners and Home Indicators",{"path":2181,"title":2182},"\u002Fmastering-container-queries-responsive-layouts\u002Fviewport-units-and-mobile-layout\u002Fviewport-units-vs-container-units","Viewport Units vs Container Units: Choosing the Right Reference Box",{"path":2184,"title":2185},"\u002Fmastering-container-queries-responsive-layouts\u002Fviewport-units-and-mobile-layout\u002Fvirtual-keyboard-and-interactive-widget","Layouts That Survive the Virtual Keyboard",{"title":2187,"caption":2188,"height":2189,"resizable":357,"html":2190,"css":2191},"Toolbar spaced with gap and one auto margin","Narrow the frame until the toolbar wraps: lines stay flush, and Publish keeps to the far end of its line.",200,"\n\u003Cdiv class=\"toolbar\" role=\"toolbar\" aria-label=\"Formatting\">\n  \u003Cbutton type=\"button\">Bold\u003C\u002Fbutton>\n  \u003Cbutton type=\"button\">Italic\u003C\u002Fbutton>\n  \u003Cbutton type=\"button\">Link\u003C\u002Fbutton>\n  \u003Cspan class=\"group-start\">\u003C\u002Fspan>\n  \u003Cbutton type=\"button\">Bullet list\u003C\u002Fbutton>\n  \u003Cbutton type=\"button\">Numbered list\u003C\u002Fbutton>\n  \u003Cbutton type=\"button\" class=\"push\">Publish\u003C\u002Fbutton>\n\u003C\u002Fdiv>","\n.toolbar {\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  gap: 0.75rem 0.5rem;\n  padding: 0.75rem;\n  border: 1px solid var(--demo-border);\n  border-radius: 10px;\n}\n.toolbar button {\n  padding: 0.45rem 0.8rem;\n  border: 1px solid var(--demo-border);\n  border-radius: 6px;\n  background: transparent;\n  color: inherit;\n  font: inherit;\n}\n.toolbar .push { margin-inline-start: auto; }\n.toolbar .group-start {\n  padding-inline-start: 0.75rem;\n  border-inline-start: 1px solid var(--demo-border);\n  align-self: stretch;\n}\n.toolbar button:focus-visible {\n  outline: 2px solid var(--demo-accent);\n  outline-offset: 2px;\n}",1789717746067]