[{"data":1,"prerenderedAt":1878},["ShallowReactive",2],{"page-\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fstyle-queries-with-custom-properties\u002F":3,"content-all-pages":1618},{"id":4,"title":5,"body":6,"description":1599,"extension":1600,"meta":1601,"navigation":356,"path":1614,"seo":1615,"stem":1616,"__hash__":1617},"content\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fstyle-queries-with-custom-properties\u002Findex.md","Style Queries With Custom Properties: Declaring, Inheriting, and Matching Tokens",{"type":7,"value":8,"toc":1586},"minimark",[9,13,37,40,45,48,55,66,68,72,168,171,175,177,181,184,1062,1079,1081,1085,1088,1103,1127,1175,1193,1198,1204,1250,1257,1259,1263,1266,1280,1297,1317,1327,1329,1333,1340,1473,1484,1486,1490,1504,1506,1510,1516,1525,1534,1540,1542,1546,1583],[10,11,5],"h1",{"id":12},"style-queries-with-custom-properties-declaring-inheriting-and-matching-tokens",[14,15,16,17,21,22,25,26,31,32,36],"p",{},"You write ",[18,19,20],"code",{},"@container style(--variant: compact)",", set ",[18,23,24],{},"--variant: compact"," on the element you expect to change, and nothing happens. There is no console warning and no invalid-property strikethrough in DevTools — the block is simply never applied. This page works through the exact mechanics of matching a custom property with a style query: where the declaration has to live, what the engine compares, and the four inheritance behaviours that make an otherwise correct query evaluate false. It sits inside the ",[27,28,30],"a",{"href":29},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002F","style queries and container state"," guide, part of ",[27,33,35],{"href":34},"\u002Fmastering-container-queries-responsive-layouts\u002F","Mastering Container Queries & Responsive Layouts",".",[38,39],"hr",{},[41,42,44],"h2",{"id":43},"why-css-solves-this-and-javascript-should-not","Why CSS solves this and JavaScript should not",[14,46,47],{},"The instinct when a component needs to react to a piece of state is to compute that state in script and set a class. That works, but it puts a runtime dependency between state and appearance: the class must be applied before first paint or the component flashes its default, and every consumer of the component must know the class vocabulary.",[14,49,50,51,54],{},"A custom property carries the same information declaratively. It inherits, so it can be set once at a region boundary and read at any depth without being threaded through props or wrappers. It is available at style-computation time, so there is no flash. And it degrades to nothing — an engine that cannot evaluate ",[18,52,53],{},"style()"," simply keeps the default branch, which is the behaviour you want anyway.",[14,56,57,58,62,63,36],{},"The tradeoff is that a custom property is invisible to assistive technology. A token change is a purely visual event; where the state is semantically meaningful the markup must carry it too, via an ARIA attribute or real text. Use tokens to decide ",[59,60,61],"em",{},"how"," something looks, never as the sole record of ",[59,64,65],{},"what it is",[38,67],{},[41,69,71],{"id":70},"the-ancestor-rule-in-one-diagram","The ancestor rule, in one diagram",[73,74,80,81,80,85,80,89,80,96,80,102,80,107,80,118,80,123,80,128,80,137,80,141,80,145,80,152,80,157,80,160,80,162,80,165],"svg",{"viewBox":75,"role":76,"ariaLabel":77,"xmlns":78,"style":79},"0 0 720 330","img","Comparison of a token declared on a parent element, which matches, against a token declared on the queried element itself, which does not","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;height:auto;max-width:720px;margin:2rem 0","\n  ",[82,83,84],"title",{},"Where the token must be declared",[86,87,88],"desc",{},"A style query matches when the custom property is declared on an ancestor and fails when it is declared on the queried element.",[90,91,95],"text",{"x":92,"y":93,"style":94},"360","28","text-anchor:middle;fill:currentColor;font:700 17px sans-serif","Where the token must live",[90,97,101],{"x":98,"y":99,"style":100},"190","58","text-anchor:middle;fill:#7aa2ff;font:600 14px sans-serif","matches",[90,103,106],{"x":104,"y":99,"style":105},"530","text-anchor:middle;fill:currentColor;font:600 14px sans-serif;opacity:0.7","never matches",[108,109],"rect",{"x":110,"y":111,"width":112,"height":113,"rx":114,"fill":115,"opacity":116,"stroke":115,"strokeWidth":117},"40","72","300","86","10","#7aa2ff","0.18","1.5",[90,119,122],{"x":98,"y":120,"style":121},"100","text-anchor:middle;fill:currentColor;font:12px sans-serif;opacity:0.85","parent element",[90,124,127],{"x":98,"y":125,"style":126},"126","text-anchor:middle;fill:currentColor;font:12px ui-monospace,monospace","--state: on",[108,129],{"x":130,"y":131,"width":132,"height":133,"rx":134,"fill":135,"stroke":136,"strokeWidth":117},"76","176","228","66","8","none","currentColor",[90,138,140],{"x":98,"y":139,"style":121},"200","queried child",[90,142,144],{"x":98,"y":143,"style":126},"224","style(--state: on)",[108,146],{"x":147,"y":111,"width":112,"height":113,"rx":114,"fill":135,"stroke":136,"strokeWidth":117,"strokeDashArray":148,"opacity":151},"380",[149,150],"5","4","0.5",[90,153,156],{"x":104,"y":154,"style":155},"122","text-anchor:middle;fill:currentColor;font:12px sans-serif;opacity:0.7","parent declares nothing",[108,158],{"x":159,"y":131,"width":132,"height":133,"rx":134,"fill":135,"stroke":136,"strokeWidth":117},"416",[90,161,127],{"x":104,"y":139,"style":126},[90,163,144],{"x":104,"y":143,"style":164},"text-anchor:middle;fill:currentColor;font:12px ui-monospace,monospace;opacity:0.7",[90,166,167],{"x":92,"y":112,"style":155},"the query reads the parent, never the element's own declarations",[14,169,170],{},"Both notes in the demo below declare the same token with the same value. Only the one whose parent declares it is restyled.",[172,173],"live-demo",{"name":174},"style-queries-nearest-ancestor",[38,176],{},[41,178,180],{"id":179},"complete-working-implementation","Complete working implementation",[14,182,183],{},"The following is self-contained. It shows the correct placement, the incorrect placement side by side, and a component root that supplies its own default — the pattern you will actually ship.",[185,186,191],"pre",{"className":187,"code":188,"language":189,"meta":190,"style":190},"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>Style query token placement\u003C\u002Ftitle>\n\u003Cstyle>\n  body { font: 400 16px\u002F1.5 system-ui, sans-serif; margin: 2rem; color: #101828; }\n\n  .stack { display: grid; gap: .9rem; max-width: 34rem; }\n\n  \u002F* CORRECT: the token sits on an ancestor of the element the query restyles. *\u002F\n  .holder { --state: highlight; }\n\n  \u002F* INCORRECT: the token sits on the element being queried. The element is not\n     its own style query container, so style(--state: highlight) is false here. *\u002F\n  .note--self { --state: highlight; }\n\n  .note {\n    margin: 0;\n    padding: .8rem 1rem;\n    border: 1px dashed #d0d5dd;\n    border-radius: 8px;\n    background: #fff;\n    color: #667085;\n  }\n\n  @container style(--state: highlight) {\n    .note {\n      border-style: solid;\n      border-color: #7aa2ff;\n      color: #101828;\n      box-shadow: inset 3px 0 0 #7aa2ff;\n    }\n  }\n\n  \u002F* The shipping pattern: a component root declares its own default token, and the\n     query restyles the root's DESCENDANTS. The ancestor requirement is satisfied\n     because .widget is an ancestor of .widget__label. *\u002F\n  .widget { --mode: idle; padding: 1rem; border: 1px solid #d0d5dd; border-radius: 10px; }\n  .widget[data-mode=\"busy\"] { --mode: busy; }\n  .widget__label { margin: 0; font-weight: 600; }\n\n  @container style(--mode: busy) {\n    .widget__label::after { content: \" · working\"; color: #667085; font-weight: 400; }\n  }\n\u003C\u002Fstyle>\n\u003C\u002Fhead>\n\u003Cbody>\n  \u003Cdiv class=\"stack\">\n    \u003Cdiv class=\"holder\">\n      \u003Cp class=\"note\">Parent declares the token — this note is highlighted.\u003C\u002Fp>\n    \u003C\u002Fdiv>\n\n    \u003Cp class=\"note note--self\">This note declares the token on itself — unchanged.\u003C\u002Fp>\n\n    \u003Cdiv class=\"widget\" data-mode=\"busy\">\n      \u003Cp class=\"widget__label\">Export\u003C\u002Fp>\n    \u003C\u002Fdiv>\n  \u003C\u002Fdiv>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>\n","html","",[18,192,193,213,233,243,261,275,285,351,358,400,405,412,432,437,443,449,465,470,479,493,513,534,548,561,574,580,585,594,602,615,627,639,665,671,676,681,687,693,699,751,775,801,806,814,848,853,863,872,882,901,918,940,950,955,976,981,1004,1025,1034,1044,1053],{"__ignoreMap":190},[194,195,198,202,206,210],"span",{"class":196,"line":197},"line",1,[194,199,201],{"class":200},"suds8","\u003C!",[194,203,205],{"class":204},"sne4z","doctype",[194,207,209],{"class":208},"s-5SL"," html",[194,211,212],{"class":200},">\n",[194,214,216,219,221,224,227,231],{"class":196,"line":215},2,[194,217,218],{"class":200},"\u003C",[194,220,189],{"class":204},[194,222,223],{"class":208}," lang",[194,225,226],{"class":200},"=",[194,228,230],{"class":229},"sT6z2","\"en\"",[194,232,212],{"class":200},[194,234,236,238,241],{"class":196,"line":235},3,[194,237,218],{"class":200},[194,239,240],{"class":204},"head",[194,242,212],{"class":200},[194,244,246,248,251,254,256,259],{"class":196,"line":245},4,[194,247,218],{"class":200},[194,249,250],{"class":204},"meta",[194,252,253],{"class":208}," charset",[194,255,226],{"class":200},[194,257,258],{"class":229},"\"utf-8\"",[194,260,212],{"class":200},[194,262,264,266,268,271,273],{"class":196,"line":263},5,[194,265,218],{"class":200},[194,267,82],{"class":204},[194,269,270],{"class":200},">Style query token placement\u003C\u002F",[194,272,82],{"class":204},[194,274,212],{"class":200},[194,276,278,280,283],{"class":196,"line":277},6,[194,279,218],{"class":200},[194,281,282],{"class":204},"style",[194,284,212],{"class":200},[194,286,288,291,294,297,300,303,306,310,313,315,318,321,324,327,330,332,335,338,340,343,345,348],{"class":196,"line":287},7,[194,289,290],{"class":204},"  body",[194,292,293],{"class":200}," { ",[194,295,296],{"class":208},"font",[194,298,299],{"class":200},": ",[194,301,302],{"class":208},"400",[194,304,305],{"class":208}," 16",[194,307,309],{"class":308},"sHUrx","px",[194,311,312],{"class":200},"\u002F",[194,314,117],{"class":208},[194,316,317],{"class":208}," system-ui",[194,319,320],{"class":200},", ",[194,322,323],{"class":208},"sans-serif",[194,325,326],{"class":200},"; ",[194,328,329],{"class":208},"margin",[194,331,299],{"class":200},[194,333,334],{"class":208},"2",[194,336,337],{"class":308},"rem",[194,339,326],{"class":200},[194,341,342],{"class":208},"color",[194,344,299],{"class":200},[194,346,347],{"class":208},"#101828",[194,349,350],{"class":200},"; }\n",[194,352,354],{"class":196,"line":353},8,[194,355,357],{"emptyLinePlaceholder":356},true,"\n",[194,359,361,364,366,369,371,374,376,379,381,384,386,388,391,393,396,398],{"class":196,"line":360},9,[194,362,363],{"class":208},"  .stack",[194,365,293],{"class":200},[194,367,368],{"class":208},"display",[194,370,299],{"class":200},[194,372,373],{"class":208},"grid",[194,375,326],{"class":200},[194,377,378],{"class":208},"gap",[194,380,299],{"class":200},[194,382,383],{"class":208},".9",[194,385,337],{"class":308},[194,387,326],{"class":200},[194,389,390],{"class":208},"max-width",[194,392,299],{"class":200},[194,394,395],{"class":208},"34",[194,397,337],{"class":308},[194,399,350],{"class":200},[194,401,403],{"class":196,"line":402},10,[194,404,357],{"emptyLinePlaceholder":356},[194,406,408],{"class":196,"line":407},11,[194,409,411],{"class":410},"sLBg1","  \u002F* CORRECT: the token sits on an ancestor of the element the query restyles. *\u002F\n",[194,413,415,418,420,424,426,430],{"class":196,"line":414},12,[194,416,417],{"class":208},"  .holder",[194,419,293],{"class":200},[194,421,423],{"class":422},"soyes","--state",[194,425,299],{"class":200},[194,427,429],{"class":428},"sh5d0","highlight",[194,431,350],{"class":200},[194,433,435],{"class":196,"line":434},13,[194,436,357],{"emptyLinePlaceholder":356},[194,438,440],{"class":196,"line":439},14,[194,441,442],{"class":410},"  \u002F* INCORRECT: the token sits on the element being queried. The element is not\n",[194,444,446],{"class":196,"line":445},15,[194,447,448],{"class":410},"     its own style query container, so style(--state: highlight) is false here. *\u002F\n",[194,450,452,455,457,459,461,463],{"class":196,"line":451},16,[194,453,454],{"class":208},"  .note--self",[194,456,293],{"class":200},[194,458,423],{"class":422},[194,460,299],{"class":200},[194,462,429],{"class":428},[194,464,350],{"class":200},[194,466,468],{"class":196,"line":467},17,[194,469,357],{"emptyLinePlaceholder":356},[194,471,473,476],{"class":196,"line":472},18,[194,474,475],{"class":208},"  .note",[194,477,478],{"class":200}," {\n",[194,480,482,485,487,490],{"class":196,"line":481},19,[194,483,484],{"class":208},"    margin",[194,486,299],{"class":200},[194,488,489],{"class":208},"0",[194,491,492],{"class":200},";\n",[194,494,496,499,501,504,506,509,511],{"class":196,"line":495},20,[194,497,498],{"class":208},"    padding",[194,500,299],{"class":200},[194,502,503],{"class":208},".8",[194,505,337],{"class":308},[194,507,508],{"class":208}," 1",[194,510,337],{"class":308},[194,512,492],{"class":200},[194,514,516,519,521,524,526,529,532],{"class":196,"line":515},21,[194,517,518],{"class":208},"    border",[194,520,299],{"class":200},[194,522,523],{"class":208},"1",[194,525,309],{"class":308},[194,527,528],{"class":208}," dashed",[194,530,531],{"class":208}," #d0d5dd",[194,533,492],{"class":200},[194,535,537,540,542,544,546],{"class":196,"line":536},22,[194,538,539],{"class":208},"    border-radius",[194,541,299],{"class":200},[194,543,134],{"class":208},[194,545,309],{"class":308},[194,547,492],{"class":200},[194,549,551,554,556,559],{"class":196,"line":550},23,[194,552,553],{"class":208},"    background",[194,555,299],{"class":200},[194,557,558],{"class":208},"#fff",[194,560,492],{"class":200},[194,562,564,567,569,572],{"class":196,"line":563},24,[194,565,566],{"class":208},"    color",[194,568,299],{"class":200},[194,570,571],{"class":208},"#667085",[194,573,492],{"class":200},[194,575,577],{"class":196,"line":576},25,[194,578,579],{"class":200},"  }\n",[194,581,583],{"class":196,"line":582},26,[194,584,357],{"emptyLinePlaceholder":356},[194,586,588,591],{"class":196,"line":587},27,[194,589,590],{"class":308},"  @container",[194,592,593],{"class":200}," style(--state: highlight) {\n",[194,595,597,600],{"class":196,"line":596},28,[194,598,599],{"class":208},"    .note",[194,601,478],{"class":200},[194,603,605,608,610,613],{"class":196,"line":604},29,[194,606,607],{"class":208},"      border-style",[194,609,299],{"class":200},[194,611,612],{"class":208},"solid",[194,614,492],{"class":200},[194,616,618,621,623,625],{"class":196,"line":617},30,[194,619,620],{"class":208},"      border-color",[194,622,299],{"class":200},[194,624,115],{"class":208},[194,626,492],{"class":200},[194,628,630,633,635,637],{"class":196,"line":629},31,[194,631,632],{"class":208},"      color",[194,634,299],{"class":200},[194,636,347],{"class":208},[194,638,492],{"class":200},[194,640,642,645,647,650,653,655,658,660,663],{"class":196,"line":641},32,[194,643,644],{"class":208},"      box-shadow",[194,646,299],{"class":200},[194,648,649],{"class":208},"inset",[194,651,652],{"class":208}," 3",[194,654,309],{"class":308},[194,656,657],{"class":208}," 0",[194,659,657],{"class":208},[194,661,662],{"class":208}," #7aa2ff",[194,664,492],{"class":200},[194,666,668],{"class":196,"line":667},33,[194,669,670],{"class":200},"    }\n",[194,672,674],{"class":196,"line":673},34,[194,675,579],{"class":200},[194,677,679],{"class":196,"line":678},35,[194,680,357],{"emptyLinePlaceholder":356},[194,682,684],{"class":196,"line":683},36,[194,685,686],{"class":410},"  \u002F* The shipping pattern: a component root declares its own default token, and the\n",[194,688,690],{"class":196,"line":689},37,[194,691,692],{"class":410},"     query restyles the root's DESCENDANTS. The ancestor requirement is satisfied\n",[194,694,696],{"class":196,"line":695},38,[194,697,698],{"class":410},"     because .widget is an ancestor of .widget__label. *\u002F\n",[194,700,702,705,707,710,713,716,718,720,722,724,727,729,731,733,736,738,740,743,745,747,749],{"class":196,"line":701},39,[194,703,704],{"class":208},"  .widget",[194,706,293],{"class":200},[194,708,709],{"class":422},"--mode",[194,711,712],{"class":200},": idle; ",[194,714,715],{"class":208},"padding",[194,717,299],{"class":200},[194,719,523],{"class":208},[194,721,337],{"class":308},[194,723,326],{"class":200},[194,725,726],{"class":208},"border",[194,728,299],{"class":200},[194,730,523],{"class":208},[194,732,309],{"class":308},[194,734,735],{"class":208}," solid",[194,737,531],{"class":208},[194,739,326],{"class":200},[194,741,742],{"class":208},"border-radius",[194,744,299],{"class":200},[194,746,114],{"class":208},[194,748,309],{"class":308},[194,750,350],{"class":200},[194,752,754,756,759,762,764,767,770,772],{"class":196,"line":753},40,[194,755,704],{"class":208},[194,757,758],{"class":200},"[",[194,760,761],{"class":208},"data-mode",[194,763,226],{"class":308},[194,765,766],{"class":229},"\"busy\"",[194,768,769],{"class":200},"] { ",[194,771,709],{"class":422},[194,773,774],{"class":200},": busy; }\n",[194,776,778,781,783,785,787,789,791,794,796,799],{"class":196,"line":777},41,[194,779,780],{"class":208},"  .widget__label",[194,782,293],{"class":200},[194,784,329],{"class":208},[194,786,299],{"class":200},[194,788,489],{"class":208},[194,790,326],{"class":200},[194,792,793],{"class":208},"font-weight",[194,795,299],{"class":200},[194,797,798],{"class":208},"600",[194,800,350],{"class":200},[194,802,804],{"class":196,"line":803},42,[194,805,357],{"emptyLinePlaceholder":356},[194,807,809,811],{"class":196,"line":808},43,[194,810,590],{"class":308},[194,812,813],{"class":200}," style(--mode: busy) {\n",[194,815,817,820,822,825,827,830,832,834,836,838,840,842,844,846],{"class":196,"line":816},44,[194,818,819],{"class":208},"    .widget__label::after",[194,821,293],{"class":200},[194,823,824],{"class":208},"content",[194,826,299],{"class":200},[194,828,829],{"class":229},"\" · working\"",[194,831,326],{"class":200},[194,833,342],{"class":208},[194,835,299],{"class":200},[194,837,571],{"class":208},[194,839,326],{"class":200},[194,841,793],{"class":208},[194,843,299],{"class":200},[194,845,302],{"class":208},[194,847,350],{"class":200},[194,849,851],{"class":196,"line":850},45,[194,852,579],{"class":200},[194,854,856,859,861],{"class":196,"line":855},46,[194,857,858],{"class":200},"\u003C\u002F",[194,860,282],{"class":204},[194,862,212],{"class":200},[194,864,866,868,870],{"class":196,"line":865},47,[194,867,858],{"class":200},[194,869,240],{"class":204},[194,871,212],{"class":200},[194,873,875,877,880],{"class":196,"line":874},48,[194,876,218],{"class":200},[194,878,879],{"class":204},"body",[194,881,212],{"class":200},[194,883,885,888,891,894,896,899],{"class":196,"line":884},49,[194,886,887],{"class":200},"  \u003C",[194,889,890],{"class":204},"div",[194,892,893],{"class":208}," class",[194,895,226],{"class":200},[194,897,898],{"class":229},"\"stack\"",[194,900,212],{"class":200},[194,902,904,907,909,911,913,916],{"class":196,"line":903},50,[194,905,906],{"class":200},"    \u003C",[194,908,890],{"class":204},[194,910,893],{"class":208},[194,912,226],{"class":200},[194,914,915],{"class":229},"\"holder\"",[194,917,212],{"class":200},[194,919,921,924,926,928,930,933,936,938],{"class":196,"line":920},51,[194,922,923],{"class":200},"      \u003C",[194,925,14],{"class":204},[194,927,893],{"class":208},[194,929,226],{"class":200},[194,931,932],{"class":229},"\"note\"",[194,934,935],{"class":200},">Parent declares the token — this note is highlighted.\u003C\u002F",[194,937,14],{"class":204},[194,939,212],{"class":200},[194,941,943,946,948],{"class":196,"line":942},52,[194,944,945],{"class":200},"    \u003C\u002F",[194,947,890],{"class":204},[194,949,212],{"class":200},[194,951,953],{"class":196,"line":952},53,[194,954,357],{"emptyLinePlaceholder":356},[194,956,958,960,962,964,966,969,972,974],{"class":196,"line":957},54,[194,959,906],{"class":200},[194,961,14],{"class":204},[194,963,893],{"class":208},[194,965,226],{"class":200},[194,967,968],{"class":229},"\"note note--self\"",[194,970,971],{"class":200},">This note declares the token on itself — unchanged.\u003C\u002F",[194,973,14],{"class":204},[194,975,212],{"class":200},[194,977,979],{"class":196,"line":978},55,[194,980,357],{"emptyLinePlaceholder":356},[194,982,984,986,988,990,992,995,998,1000,1002],{"class":196,"line":983},56,[194,985,906],{"class":200},[194,987,890],{"class":204},[194,989,893],{"class":208},[194,991,226],{"class":200},[194,993,994],{"class":229},"\"widget\"",[194,996,997],{"class":208}," data-mode",[194,999,226],{"class":200},[194,1001,766],{"class":229},[194,1003,212],{"class":200},[194,1005,1007,1009,1011,1013,1015,1018,1021,1023],{"class":196,"line":1006},57,[194,1008,923],{"class":200},[194,1010,14],{"class":204},[194,1012,893],{"class":208},[194,1014,226],{"class":200},[194,1016,1017],{"class":229},"\"widget__label\"",[194,1019,1020],{"class":200},">Export\u003C\u002F",[194,1022,14],{"class":204},[194,1024,212],{"class":200},[194,1026,1028,1030,1032],{"class":196,"line":1027},58,[194,1029,945],{"class":200},[194,1031,890],{"class":204},[194,1033,212],{"class":200},[194,1035,1037,1040,1042],{"class":196,"line":1036},59,[194,1038,1039],{"class":200},"  \u003C\u002F",[194,1041,890],{"class":204},[194,1043,212],{"class":200},[194,1045,1047,1049,1051],{"class":196,"line":1046},60,[194,1048,858],{"class":200},[194,1050,879],{"class":204},[194,1052,212],{"class":200},[194,1054,1056,1058,1060],{"class":196,"line":1055},61,[194,1057,858],{"class":200},[194,1059,189],{"class":204},[194,1061,212],{"class":200},[14,1063,1064,1065,1068,1069,1071,1072,1075,1076,1078],{},"The ",[18,1066,1067],{},".widget"," block is the important one. It looks like self-querying and is not: the declaration is on ",[18,1070,1067],{},", the query restyles ",[18,1073,1074],{},".widget__label",", and ",[18,1077,1067],{}," is that label's ancestor. Almost every real style query has this shape, which is why the rule feels invisible until the day you try to restyle the token-bearing element itself.",[38,1080],{},[41,1082,1084],{"id":1083},"key-technique-match-on-computed-value-not-declared-value","Key technique: match on computed value, not declared value",[14,1086,1087],{},"The engine does not compare source text. It computes the custom property on the ancestor first, then compares the resulting token sequence with the one in the query. Three consequences follow.",[14,1089,1090,1094,1095,1098,1099,1102],{},[1091,1092,1093],"strong",{},"Substitution resolves first."," If the ancestor has ",[18,1096,1097],{},"--state: var(--incoming, highlight)",", the query sees whatever ",[18,1100,1101],{},"var()"," produced. You can therefore drive a query from a value passed down through several indirections, which is how design-token layers stay composable.",[14,1104,1105,1108,1109,1112,1113,1116,1117,1075,1120,1116,1123,1126],{},[1091,1106,1107],{},"Unregistered properties compare tokens literally."," A custom property with no ",[18,1110,1111],{},"@property"," registration has no type; its computed value is essentially its trimmed token stream. ",[18,1114,1115],{},"--ratio: 1.0"," does not match ",[18,1118,1119],{},"style(--ratio: 1)",[18,1121,1122],{},"--tone: Dusk",[18,1124,1125],{},"style(--tone: dusk)",". Registering the property fixes the numeric case because registration forces computation to the declared syntax:",[185,1128,1132],{"className":1129,"code":1130,"language":1131,"meta":190,"style":190},"language-css shiki shiki-themes github-light-high-contrast github-dark-high-contrast","@property --ratio {\n  syntax: \"\u003Cnumber>\";\n  inherits: true;\n  initial-value: 1;\n}\n\u002F* Now --ratio: 1.0 computes to 1 and style(--ratio: 1) matches. *\u002F\n","css",[18,1133,1134,1141,1152,1157,1165,1170],{"__ignoreMap":190},[194,1135,1136,1138],{"class":196,"line":197},[194,1137,1111],{"class":308},[194,1139,1140],{"class":200}," --ratio {\n",[194,1142,1143,1146,1149],{"class":196,"line":215},[194,1144,1145],{"class":200},"  syntax: \"\u003Cnumber",[194,1147,1148],{"class":308},">",[194,1150,1151],{"class":200},"\";\n",[194,1153,1154],{"class":196,"line":235},[194,1155,1156],{"class":200},"  inherits: true;\n",[194,1158,1159,1162],{"class":196,"line":245},[194,1160,1161],{"class":204},"  initial-value",[194,1163,1164],{"class":200},": 1;\n",[194,1166,1167],{"class":196,"line":263},[194,1168,1169],{"class":200},"}\n",[194,1171,1172],{"class":196,"line":277},[194,1173,1174],{"class":410},"\u002F* Now --ratio: 1.0 computes to 1 and style(--ratio: 1) matches. *\u002F\n",[14,1176,1177,1180,1181,1184,1185,1188,1189,1192],{},[1091,1178,1179],{},"Leading and trailing whitespace is normalised, internal whitespace is not."," ",[18,1182,1183],{},"--gap:  8px"," matches ",[18,1186,1187],{},"style(--gap: 8px)",", but ",[18,1190,1191],{},"--font: system-ui,  sans-serif"," will not match a query written with a single space. Keep queried tokens to single keywords wherever you can; they are identifiers, not values you should be pretty-printing.",[1194,1195,1197],"h3",{"id":1196},"the-boolean-form","The boolean form",[14,1199,1200,1203],{},[18,1201,1202],{},"style(--token)"," with no value tests whether the property holds anything other than its initial guaranteed-invalid value. It is the right tool for optional tokens:",[185,1205,1207],{"className":1129,"code":1206,"language":1131,"meta":190,"style":190},"\u002F* Applies whenever an ancestor has set --accent to anything at all. *\u002F\n@container style(--accent) {\n  .chip { border-color: var(--accent); }\n}\n",[18,1208,1209,1214,1222,1246],{"__ignoreMap":190},[194,1210,1211],{"class":196,"line":197},[194,1212,1213],{"class":410},"\u002F* Applies whenever an ancestor has set --accent to anything at all. *\u002F\n",[194,1215,1216,1219],{"class":196,"line":215},[194,1217,1218],{"class":308},"@container",[194,1220,1221],{"class":200}," style(--accent) {\n",[194,1223,1224,1227,1229,1232,1234,1237,1240,1243],{"class":196,"line":235},[194,1225,1226],{"class":208},"  .chip",[194,1228,293],{"class":200},[194,1230,1231],{"class":208},"border-color",[194,1233,299],{"class":200},[194,1235,1236],{"class":208},"var",[194,1238,1239],{"class":200},"(",[194,1241,1242],{"class":422},"--accent",[194,1244,1245],{"class":200},"); }\n",[194,1247,1248],{"class":196,"line":245},[194,1249,1169],{"class":200},[14,1251,1252,1253,1256],{},"Note that a property explicitly set to ",[18,1254,1255],{},"initial"," fails this test, while one set to an empty value technically passes — an easy way to produce a query that is true with no useful value behind it. Prefer explicit keyword values over presence-testing when the distinction matters.",[38,1258],{},[41,1260,1262],{"id":1261},"inheritance-gotchas","Inheritance gotchas",[14,1264,1265],{},"Four behaviours account for nearly every query that fails despite correct placement.",[14,1267,1268,1271,1272,1275,1276,1279],{},[1091,1269,1270],{},"Redeclaration on an intermediate element wins."," Inheritance stops at the nearest declaration. If a wrapper between your region and your component sets ",[18,1273,1274],{},"--theme: light"," — even as a reset — descendants read ",[18,1277,1278],{},"light",", not the region's value. Search for the property name across the whole stylesheet before assuming the region's value reaches the leaf.",[14,1281,1282,1288,1289,1292,1293,36],{},[1091,1283,1284,1287],{},[18,1285,1286],{},"all: revert"," and aggressive resets can strip tokens."," A reset that applies ",[18,1290,1291],{},"all: unset"," to a wrapper removes inherited custom properties on that element, silently cutting the chain. Scope such resets narrowly, and keep token declarations in their own layer as described in ",[27,1294,1296],{"href":1295},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-for-reset-and-tokens\u002F","cascade layers for reset and tokens",[14,1298,1299,1180,1302,1304,1305,1308,1309,1312,1313,1316],{},[1091,1300,1301],{},"Registered properties can be non-inheriting.",[18,1303,1111],{}," with ",[18,1306,1307],{},"inherits: false"," produces a property that does ",[59,1310,1311],{},"not"," flow to descendants. A query on a child then reads the initial value, not the parent's. If you register a token that a style query will read, ",[18,1314,1315],{},"inherits: true"," is almost always what you want.",[14,1318,1319,1322,1323,1326],{},[1091,1320,1321],{},"Shadow boundaries pass values but not declarations."," Custom properties inherit into shadow trees, so a token set on a host element is readable by a style query inside its shadow root. But a token set ",[59,1324,1325],{},"inside"," the shadow root is invisible outside it. Components that expose theming through a host-level token work with style queries; components that hide their tokens do not.",[38,1328],{},[41,1330,1332],{"id":1331},"variation-naming-the-container-to-skip-intermediate-declarations","Variation: naming the container to skip intermediate declarations",[14,1334,1335,1336,1339],{},"When several ancestors legitimately declare the same token — a page region and a nested card both setting ",[18,1337,1338],{},"--density"," — an unnamed query resolves against whichever is nearest. Naming the container pins resolution to a specific level:",[185,1341,1343],{"className":1129,"code":1342,"language":1131,"meta":190,"style":190},".region {\n  container-name: region;\n  --density: comfortable;\n}\n\n.card { --density: compact; }\n\n\u002F* Reads the CARD's value, because .card is nearest. *\u002F\n@container style(--density: compact) {\n  .card__body { padding: .5rem; }\n}\n\n\u002F* Reads the REGION's value, skipping .card entirely. *\u002F\n@container region style(--density: comfortable) {\n  .card__footer { padding-block: .75rem; }\n}\n",[18,1344,1345,1352,1364,1372,1376,1380,1396,1400,1405,1412,1430,1434,1438,1443,1450,1469],{"__ignoreMap":190},[194,1346,1347,1350],{"class":196,"line":197},[194,1348,1349],{"class":208},".region",[194,1351,478],{"class":200},[194,1353,1354,1357,1359,1362],{"class":196,"line":215},[194,1355,1356],{"class":208},"  container-name",[194,1358,299],{"class":200},[194,1360,1361],{"class":208},"region",[194,1363,492],{"class":200},[194,1365,1366,1369],{"class":196,"line":235},[194,1367,1368],{"class":422},"  --density",[194,1370,1371],{"class":200},": comfortable;\n",[194,1373,1374],{"class":196,"line":245},[194,1375,1169],{"class":200},[194,1377,1378],{"class":196,"line":263},[194,1379,357],{"emptyLinePlaceholder":356},[194,1381,1382,1385,1387,1389,1391,1394],{"class":196,"line":277},[194,1383,1384],{"class":208},".card",[194,1386,293],{"class":200},[194,1388,1338],{"class":422},[194,1390,299],{"class":200},[194,1392,1393],{"class":208},"compact",[194,1395,350],{"class":200},[194,1397,1398],{"class":196,"line":287},[194,1399,357],{"emptyLinePlaceholder":356},[194,1401,1402],{"class":196,"line":353},[194,1403,1404],{"class":410},"\u002F* Reads the CARD's value, because .card is nearest. *\u002F\n",[194,1406,1407,1409],{"class":196,"line":360},[194,1408,1218],{"class":308},[194,1410,1411],{"class":200}," style(--density: compact) {\n",[194,1413,1414,1417,1419,1421,1423,1426,1428],{"class":196,"line":402},[194,1415,1416],{"class":208},"  .card__body",[194,1418,293],{"class":200},[194,1420,715],{"class":208},[194,1422,299],{"class":200},[194,1424,1425],{"class":208},".5",[194,1427,337],{"class":308},[194,1429,350],{"class":200},[194,1431,1432],{"class":196,"line":407},[194,1433,1169],{"class":200},[194,1435,1436],{"class":196,"line":414},[194,1437,357],{"emptyLinePlaceholder":356},[194,1439,1440],{"class":196,"line":434},[194,1441,1442],{"class":410},"\u002F* Reads the REGION's value, skipping .card entirely. *\u002F\n",[194,1444,1445,1447],{"class":196,"line":439},[194,1446,1218],{"class":308},[194,1448,1449],{"class":200}," region style(--density: comfortable) {\n",[194,1451,1452,1455,1457,1460,1462,1465,1467],{"class":196,"line":445},[194,1453,1454],{"class":208},"  .card__footer",[194,1456,293],{"class":200},[194,1458,1459],{"class":208},"padding-block",[194,1461,299],{"class":200},[194,1463,1464],{"class":208},".75",[194,1466,337],{"class":308},[194,1468,350],{"class":200},[194,1470,1471],{"class":196,"line":451},[194,1472,1169],{"class":200},[14,1474,1475,1476,1479,1480,36],{},"A named style query still walks up to the nearest ancestor carrying that ",[18,1477,1478],{},"container-name",", so naming is the disambiguation tool here exactly as it is for size queries — the general rules are in ",[27,1481,1483],{"href":1482},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fnesting-and-naming-container-queries\u002F","nesting and naming container queries",[38,1485],{},[41,1487,1489],{"id":1488},"browser-support","Browser support",[14,1491,1492,1493,1496,1497,1499,1500,36],{},"Custom-property style queries ship in Chrome and Edge 111+, Firefox 151+, and Safari 18+ — every current engine evaluates them. The support question that remains is about older versions still in circulation, where the block is dropped at parse time and the default branch renders instead. Because ",[18,1494,1495],{},"@supports"," has no dependable test for the feature, the practical safeguard is structural rather than conditional: never put anything load-bearing inside a ",[18,1498,53],{}," block, and verify the page is complete with those blocks removed. The full strategy is in ",[27,1501,1503],{"href":1502},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fstyle-query-fallbacks-and-support\u002F","style query fallbacks and support",[38,1505],{},[41,1507,1509],{"id":1508},"faq","FAQ",[14,1511,1512,1515],{},[1091,1513,1514],{},"Where exactly must the custom property be declared?","\nOn an ancestor of the element you want to restyle. The nearest ancestor's computed value is what the query tests, and the element's own declarations are never consulted.",[14,1517,1518,1521,1522,1524],{},[1091,1519,1520],{},"Does the value have to match exactly?","\nFor unregistered properties the comparison is on the computed token sequence, so casing and unit notation matter. Registering the property with ",[18,1523,1111],{}," normalises the value first and makes matching predictable.",[14,1526,1527,1533],{},[1091,1528,1529,1530,1532],{},"What does the boolean form ",[18,1531,1202],{}," test?","\nIt is true when the custom property has any value other than its initial guaranteed-invalid value. It is the way to test whether a token is set at all, rather than testing it against a specific value.",[14,1535,1536,1539],{},[1091,1537,1538],{},"Can a component set its own default and still be queried?","\nYes, if the default is declared on the component root and the queried rules target its descendants. The root supplies the value and the children read it, which satisfies the ancestor requirement.",[38,1541],{},[41,1543,1545],{"id":1544},"related","Related",[1547,1548,1549,1559,1566,1573],"ul",{},[1550,1551,1552,1555,1556,1558],"li",{},[27,1553,1554],{"href":29},"Style queries and container state"," — the parent guide covering the whole ",[18,1557,53],{}," model.",[1550,1560,1561,1565],{},[27,1562,1564],{"href":1563},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fcontainer-style-query-theming\u002F","Container style query theming"," — applying these rules to a full theme axis.",[1550,1567,1568,1572],{},[27,1569,1571],{"href":1570},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002F","Container Query Syntax Basics"," — the size-query half of the same at-rule.",[1550,1574,1575,1579,1580,1582],{},[27,1576,1578],{"href":1577},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Fregistered-properties-and-type-safety\u002F","Registered properties and type safety"," — why ",[18,1581,1111],{}," makes token comparison deterministic.",[282,1584,1585],{},"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 pre.shiki code .soyes, html code.shiki .soyes{--shiki-default:#702C00;--shiki-dark:#FFB757}html pre.shiki code .sh5d0, html code.shiki .sh5d0{--shiki-default:#6E011A;--shiki-default-font-style:italic;--shiki-dark:#FFB1AF;--shiki-dark-font-style:italic}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":190,"searchDepth":215,"depth":215,"links":1587},[1588,1589,1590,1591,1594,1595,1596,1597,1598],{"id":43,"depth":215,"text":44},{"id":70,"depth":215,"text":71},{"id":179,"depth":215,"text":180},{"id":1083,"depth":215,"text":1084,"children":1592},[1593],{"id":1196,"depth":235,"text":1197},{"id":1261,"depth":215,"text":1262},{"id":1331,"depth":215,"text":1332},{"id":1488,"depth":215,"text":1489},{"id":1508,"depth":215,"text":1509},{"id":1544,"depth":215,"text":1545},"Query a CSS custom property with @container style(): where to declare the token, why the queried element cannot read its own value, and inheritance gotchas.","md",{"pageTitle":1602,"datePublished":1603,"dateModified":1603,"faq":1604},"Style Queries With Custom Properties","2026-07-20",[1605,1607,1609,1612],{"q":1514,"a":1606},"On an ancestor of the element you want to restyle. The nearest ancestor's computed value is what the query tests, and the element's own declarations are never consulted.",{"q":1520,"a":1608},"For unregistered properties the comparison is on the computed token sequence, so casing and unit notation matter. Registering the property with @property normalises the value first and makes matching predictable.",{"q":1610,"a":1611},"What does the boolean form style(--token) test?","It is true when the custom property has any value other than its initial guaranteed-invalid value. It is the way to test whether a token is set at all, rather than testing it against a specific value.",{"q":1538,"a":1613},"Yes, if the default is declared on the component root and the queried rules target its descendants. The root supplies the value and the children read it, which satisfies the ancestor requirement.","\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fstyle-queries-with-custom-properties",{"title":5,"description":1599},"mastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fstyle-queries-with-custom-properties\u002Findex","UhVKvh0GkgSfe8eu98cy1Gbab-WeF78NZYRPXtAJeO8",[1619,1622,1625,1628,1631,1634,1637,1640,1643,1646,1649,1652,1655,1658,1661,1664,1667,1670,1673,1676,1679,1682,1685,1688,1691,1694,1697,1700,1703,1706,1709,1712,1715,1718,1721,1724,1727,1730,1733,1736,1739,1742,1745,1748,1751,1754,1757,1759,1762,1765,1768,1771,1774,1777,1780,1783,1786,1789,1792,1794,1797,1800,1803,1806,1809,1812,1815,1818,1821,1824,1827,1829,1832,1835,1838,1841,1844,1847,1850,1853,1856,1859,1862,1865,1868,1871,1874,1875],{"path":1620,"title":1621},"\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":1623,"title":1624},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations","Accessibility in CSS Animations: Patterns, Specs & Best Practices",{"path":1626,"title":1627},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fprefers-reduced-motion-recipes","prefers-reduced-motion Recipes: A Reduction for Every Common Effect",{"path":1629,"title":1630},"\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":1632,"title":1633},"\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":1635,"title":1636},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fvestibular-safe-animation-patterns","Vestibular-Safe Animation Patterns: Why Some Motion Makes People Sick",{"path":1638,"title":1639},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fwcag-motion-success-criteria","WCAG Motion Success Criteria: What Each One Actually Requires",{"path":1641,"title":1642},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fcontainer-query-hover-affordances","Container Query Hover Affordances: When Narrow Means Persistent, Not Hidden",{"path":1644,"title":1645},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion","Container-Aware Motion: Animation Sized by the Space a Component Actually Has",{"path":1647,"title":1648},"\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":1650,"title":1651},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fsuppressing-motion-in-small-containers","Suppressing Motion in Small Containers: Deliberately Animating Nothing",{"path":1653,"title":1654},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api","CSS Animation vs the Web Animations API: A Decision Guide",{"path":1656,"title":1657},"\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":1659,"title":1660},"\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":1662,"title":1663},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Ffluid-spacing-tokens-driving-transition-durations","Fluid Spacing Tokens That Drive Transition Durations",{"path":1665,"title":1666},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture","CSS Custom Properties Architecture: Scalable Design Systems & Dynamic UI",{"path":1668,"title":1669},"\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":1671,"title":1672},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fcss-transition-timing-functions","CSS Transition Timing Functions: ease, cubic-bezier(), steps() and linear()",{"path":1674,"title":1675},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals","CSS Transition Fundamentals: Architecture, Performance & Patterns",{"path":1677,"title":1678},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fstarting-style-entry-animations","@starting-style: Animating an Element's Very First Style Change",{"path":1680,"title":1681},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransitioning-display-with-allow-discrete","Transitioning display with transition-behavior: allow-discrete and @starting-style",{"path":1683,"title":1684},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Faccessible-css-only-tooltips","Accessible CSS-Only Tooltips and Hover Cards With  and ",{"path":1686,"title":1687},"\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":1689,"title":1690},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Ffocus-within-form-patterns"," Form Patterns: Styling a Group From the Field Inside It",{"path":1692,"title":1693},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design","Hover & Focus State Design: Spec-Compliant Patterns for Modern UIs",{"path":1695,"title":1696},"\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":1698,"title":1699},"\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":1701,"title":1702},"\u002Fcss-only-micro-interactions-animations","CSS-Only Micro-Interactions & Animations: Architecture, Performance & Implementation",{"path":1704,"title":1705},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcontainer-query-triggered-keyframe-animations","Container-Query-Triggered Keyframe Animations: Animate Differently per Available Space",{"path":1707,"title":1708},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcss-only-accordions-and-disclosure","CSS-Only Accordions and Disclosure Widgets with details and summary",{"path":1710,"title":1711},"\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":1713,"title":1714},"\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":1716,"title":1717},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns","Keyframe Animation Patterns: Spec-Compliant Architectures for Modern UIs",{"path":1719,"title":1720},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fstaggered-list-animations-with-custom-properties","Staggered List Animations Using --i Index Custom Properties",{"path":1722,"title":1723},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration","Performance & GPU Acceleration in CSS: A Developer’s Blueprint",{"path":1725,"title":1726},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Foptimizing-css-animations-for-60fps","Optimizing CSS Animations for 60fps: Budgeting the Frame",{"path":1728,"title":1729},"\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":1731,"title":1732},"\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":1734,"title":1735},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations","Scroll-Driven Animations: Binding Motion to Scroll Position in Pure CSS",{"path":1737,"title":1738},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-driven-animation-fallbacks","Shipping Scroll-Driven Animations Without Breaking Anything",{"path":1740,"title":1741},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-progress-bar-without-javascript","A Reading Progress Bar Driven by scroll(root)",{"path":1743,"title":1744},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-triggered-reveal-animations","Reveal-on-Scroll with view() and animation-range",{"path":1746,"title":1747},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers","View Transitions for CSS Developers: the Pseudo-Element Tree, Snapshots, and Named Elements",{"path":1749,"title":1750},"\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":1752,"title":1753},"\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":1755,"title":1756},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transitions-with-reduced-motion","Honouring prefers-reduced-motion in View Transitions",{"path":312,"title":1758},"Modern CSS Layouts & Micro-Interactions",{"path":1760,"title":1761},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-positioned-tooltips","Anchor-Positioned Tooltips: Tethering, Flipping, and Getting the Semantics Right",{"path":1763,"title":1764},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-positioning-fallbacks","Anchor Positioning Fallbacks: A Graceful Floor for Older Browser Versions",{"path":1766,"title":1767},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays","CSS Anchor Positioning and Overlays: Tethering Elements Without JavaScript",{"path":1769,"title":1770},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fpopover-attribute-and-css-styling","The popover Attribute: Top-Layer Overlays With No JavaScript",{"path":1772,"title":1773},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Ffeature-detection-with-supports","Feature Detection with @supports: Syntax, Semantics, and the Traps",{"path":1775,"title":1776},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fhandling-container-query-fallbacks-for-older-browsers","Handling Container Query Fallbacks for Older Browsers",{"path":1778,"title":1779},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks","Container Query Fallbacks: Spec-Compliant CSS Strategies for Legacy Browsers",{"path":1781,"title":1782},"\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":1784,"title":1785},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-type-size-vs-inline-size","Choosing container-type: inline-size, size, or normal",{"path":1787,"title":1788},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-vs-media-queries-comparison","Container vs Media Queries: Choosing the Right Reference Box",{"path":1790,"title":1791},"\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":1793,"title":1571},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics",{"path":1795,"title":1796},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fnesting-and-naming-container-queries","Nesting and Naming Container Queries: Targeting the Right Ancestor",{"path":1798,"title":1799},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fauto-fit-minmax-responsive-grids","Responsive Grids with repeat(auto-fit, minmax())",{"path":1801,"title":1802},"\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":1804,"title":1805},"\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":1807,"title":1808},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts","CSS Grid and Subgrid Layouts for Responsive Interfaces",{"path":1810,"title":1811},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fsubgrid-vs-nested-grid","Subgrid vs an Independently Nested Grid",{"path":1813,"title":1814},"\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":1816,"title":1817},"\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":1819,"title":1820},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-type-accessibility-and-zoom","Fluid Type, Accessibility and Zoom: The vw-Only Trap",{"path":1822,"title":1823},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-typography-without-javascript","Fluid Typography Without JavaScript: A Precision CSS Reference",{"path":1825,"title":1826},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp","Fluid Typography with clamp(): A Practical Guide for Modern CSS",{"path":1828,"title":35},"\u002Fmastering-container-queries-responsive-layouts",{"path":1830,"title":1831},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Faspect-ratio-for-responsive-media","Using aspect-ratio for Responsive Media and Preventing Layout Shift",{"path":1833,"title":1834},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques","Intrinsic Sizing Techniques: Modern CSS Layouts for Responsive UI",{"path":1836,"title":1837},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fmin-max-fit-content-explained","min-content, max-content, and fit-content() Explained",{"path":1839,"title":1840},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fpreventing-flex-and-grid-overflow","The min-width: auto Trap in Flex and Grid Layouts",{"path":1842,"title":1843},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-for-reset-and-tokens","Cascade Layers for Reset and Design Tokens",{"path":1845,"title":1846},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-vs-specificity-hacks","Cascade Layers vs Specificity Hacks: Ordering Instead of Escalating",{"path":1848,"title":1849},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies","Modern CSS Reset Strategies: A Spec-Compliant Foundation",{"path":1851,"title":1852},"\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":1854,"title":1855},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fcontainer-query-data-tables","Container Query Data Tables: Reflowing Tables to Cards",{"path":1857,"title":1858},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fcontainer-query-sidebar-layouts","Container Query Sidebar Layouts That Travel Between Contexts",{"path":1860,"title":1861},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns","Responsive Component Patterns: Architecture & Implementation",{"path":1863,"title":1864},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-forms-with-container-queries","Responsive Forms with Container Queries: Reflow Without Losing the Wiring",{"path":1866,"title":1867},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-navigation-without-media-queries","Responsive Navigation Without Media Queries Using Container Queries",{"path":1869,"title":1870},"\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":1872,"title":1873},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state","Style Queries and Container State: Token-Driven Component Variants",{"path":1614,"title":5},{"path":1876,"title":1877},"\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",1784566156606]