[{"data":1,"prerenderedAt":1880},["ShallowReactive",2],{"page-\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fcontainer-style-query-theming\u002F":3,"content-all-pages":1619},{"id":4,"title":5,"body":6,"description":1599,"extension":1600,"meta":1601,"navigation":337,"path":1615,"seo":1616,"stem":1617,"__hash__":1618},"content\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fcontainer-style-query-theming\u002Findex.md","Container Style Query Theming: One Token Instead of a Variant Class Matrix",{"type":7,"value":8,"toc":1590},"minimark",[9,13,38,41,46,53,64,80,83,187,190,194,196,200,203,1275,1278,1280,1284,1303,1306,1317,1334,1344,1346,1350,1357,1485,1488,1490,1494,1505,1507,1511,1520,1526,1532,1541,1543,1547,1587],[10,11,5],"h1",{"id":12},"container-style-query-theming-one-token-instead-of-a-variant-class-matrix",[14,15,16,17,21,22,27,28,32,33,37],"p",{},"A themable panel usually acquires a class for every theme it supports, and every rule inside the panel acquires a compound selector for every one of those classes. Add a second axis — density, brand, emphasis — and the rule count multiplies rather than adds. Style queries collapse that: the panel gets no theme class at all, one ",[18,19,20],"code",{},"--theme"," token is set anywhere above it, and one block per theme value restyles the whole subtree. This page belongs to the ",[23,24,26],"a",{"href":25},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002F","style queries and container state"," guide within ",[23,29,31],{"href":30},"\u002Fmastering-container-queries-responsive-layouts\u002F","Mastering Container Queries & Responsive Layouts",", and assumes the matching rules covered in ",[23,34,36],{"href":35},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fstyle-queries-with-custom-properties\u002F","style queries with custom properties",".",[39,40],"hr",{},[42,43,45],"h2",{"id":44},"why-a-token-beats-a-class-here","Why a token beats a class here",[14,47,48,49,52],{},"The class approach is not wrong, it is just structurally expensive. ",[18,50,51],{},".panel--dusk .panel__title"," names both the theme and the part, so the theme name is baked into every selector that responds to it. Renaming a theme means a sweep of the stylesheet; adding one means duplicating a block per themed part. Worse, the compound selector outranks the base rule by construction, so the base rule can never be adjusted without checking what the theme selectors are doing to it.",[14,54,55,56,59,60,63],{},"The ",[18,57,58],{},"data-"," attribute approach — ",[18,61,62],{},"[data-theme=\"dusk\"] .panel__title"," — reads better and can be toggled from script cheaply, but it has the same shape. It is still a descendant selector, still specificity-heavier than the base rule, and still requires the attribute to sit at a known ancestor that every rule can reach through the combinator.",[14,65,66,67,71,72,75,76,79],{},"A token changes what is coupled. The theme value travels by inheritance, not by selector matching, so the selectors inside the theme block are the ",[68,69,70],"em",{},"same selectors"," as the base rules — ",[18,73,74],{},".panel__title",", not ",[18,77,78],{},".something .panel__title",". Equal specificity, resolved by source order, which is the cascade behaving the way you would explain it to someone learning it.",[14,81,82],{},"There is a real cost to weigh: a token is invisible in the DOM inspector's markup view and cannot be targeted by a selector, so debugging means reading computed styles rather than scanning attributes. And on a browser version predating style queries an attribute still matches while the query block is dropped, so the token approach needs its base rules to stand on their own.",[84,85,91,92,91,96,91,100,91,106,91,118,91,124,91,129,91,134,91,138,91,143,91,146,91,149,91,152,91,155,91,158,91,160,91,165,91,169,91,172,91,176,91,179,91,183],"svg",{"viewBox":86,"role":87,"ariaLabel":88,"xmlns":89,"style":90},"0 0 720 320","img","Three theming approaches compared on selector shape and specificity: variant classes, data attributes, and a style query token","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;height:auto;max-width:720px;margin:2rem 0","\n  ",[93,94,95],"title",{},"Three ways to express a theme",[97,98,99],"desc",{},"Variant classes and data attributes both raise specificity through descendant selectors, while a style query token adds none.",[101,102,95],"text",{"x":103,"y":104,"style":105},"360","30","text-anchor:middle;fill:currentColor;font:700 17px sans-serif",[107,108],"rect",{"x":109,"y":110,"width":111,"height":112,"rx":113,"fill":114,"stroke":115,"strokeWidth":116,"opacity":117},"20","56","216","200","10","none","currentColor","1.5","0.5",[101,119,123],{"x":120,"y":121,"style":122},"128","86","text-anchor:middle;fill:currentColor;font:600 14px sans-serif","variant classes",[101,125,128],{"x":120,"y":126,"style":127},"120","text-anchor:middle;fill:currentColor;font:12px ui-monospace,monospace",".card--dusk .t",[101,130,133],{"x":120,"y":131,"style":132},"156","text-anchor:middle;fill:currentColor;font:12px sans-serif;opacity:0.75","one class per theme",[101,135,137],{"x":120,"y":136,"style":132},"182","on every themed part",[101,139,142],{"x":120,"y":140,"style":141},"220","text-anchor:middle;fill:currentColor;font:12px sans-serif;opacity:0.6","specificity: 0,2,0",[107,144],{"x":145,"y":110,"width":111,"height":112,"rx":113,"fill":114,"stroke":115,"strokeWidth":116,"opacity":117},"252",[101,147,148],{"x":103,"y":121,"style":122},"data attributes",[101,150,151],{"x":103,"y":126,"style":127},"[data-theme] .t",[101,153,154],{"x":103,"y":131,"style":132},"one shared hook",[101,156,157],{"x":103,"y":136,"style":132},"still a descendant",[101,159,142],{"x":103,"y":140,"style":141},[107,161],{"x":162,"y":110,"width":111,"height":112,"rx":113,"fill":163,"opacity":164,"stroke":163,"strokeWidth":116},"484","#7aa2ff","0.16",[101,166,168],{"x":167,"y":121,"style":122},"592","token query",[101,170,171],{"x":167,"y":126,"style":127},"style(--theme)",[101,173,175],{"x":167,"y":131,"style":174},"text-anchor:middle;fill:currentColor;font:12px sans-serif;opacity:0.85","one inherited token",[101,177,178],{"x":167,"y":136,"style":174},"selector unchanged",[101,180,182],{"x":167,"y":140,"style":181},"text-anchor:middle;fill:currentColor;font:12px sans-serif;opacity:0.7","specificity: 0,1,0",[101,184,186],{"x":103,"y":185,"style":181},"296","only the token approach leaves the base selector's weight untouched",[14,188,189],{},"The token is set once on an outer region in the demo below; the panel inside carries no theme class of its own.",[191,192],"live-demo",{"name":193},"style-queries-theme-token",[39,195],{},[42,197,199],{"id":198},"complete-working-implementation","Complete working implementation",[14,201,202],{},"A settings panel that themes from an ancestor token, with the user's colour-scheme preference feeding the same token so there is exactly one place a theme is decided.",[204,205,210],"pre",{"className":206,"code":207,"language":208,"meta":209,"style":209},"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>Token-themed panel\u003C\u002Ftitle>\n\u003Cstyle>\n  \u002F* The token's only job is to name a theme. It carries no colours itself, so a\n     region can switch theme without knowing what any component does with it. *\u002F\n  :root { --theme: day; }\n\n  \u002F* One rule maps the OS preference onto the token. Every style query below\n     responds without being duplicated inside a media query. *\u002F\n  @media (prefers-color-scheme: dark) {\n    :root { --theme: dusk; }\n  }\n\n  \u002F* Any region can override for its own subtree — no selector changes required. *\u002F\n  .region--dusk { --theme: dusk; }\n  .region--day  { --theme: day; }\n\n  body { font: 400 16px\u002F1.5 system-ui, sans-serif; margin: 0; padding: 2rem; }\n\n  .panel {\n    max-inline-size: 32rem;\n    padding: 1.25rem;\n    border: 1px solid #d0d5dd;\n    border-radius: 12px;\n    background: #ffffff;\n    color: #101828;\n  }\n  .panel__title  { margin: 0 0 .4rem; font: 600 1.05rem\u002F1.3 system-ui, sans-serif; }\n  .panel__body   { margin: 0 0 1rem; color: #667085; }\n  .panel__action {\n    padding: .5rem 1rem;\n    border: 1px solid #d0d5dd;\n    border-radius: 8px;\n    background: #f9fafb;\n    color: #101828;\n    font: 600 .875rem\u002F1 system-ui, sans-serif;\n    cursor: pointer;\n  }\n  .panel__action:focus-visible { outline: 2px solid #7aa2ff; outline-offset: 2px; }\n\n  \u002F* The theme block. Note the selectors: identical to the base rules above, not\n     prefixed with any theme selector. Same specificity, later source order. *\u002F\n  @container style(--theme: dusk) {\n    .panel         { background: #1c2333; border-color: #33405c; color: #e8ecf7; }\n    .panel__body   { color: #a9b4cc; }\n    .panel__action { background: #26304a; border-color: #3c4a69; color: #e8ecf7; }\n    .panel__action:focus-visible { outline-color: #9dbaff; }\n  }\n\u003C\u002Fstyle>\n\u003C\u002Fhead>\n\u003Cbody>\n  \u003Cdiv class=\"region region--dusk\">\n    \u003Csection class=\"panel\">\n      \u003Ch2 class=\"panel__title\">Deployment window\u003C\u002Fh2>\n      \u003Cp class=\"panel__body\">Changes are applied during the next maintenance window.\u003C\u002Fp>\n      \u003Cbutton class=\"panel__action\" type=\"button\">Review changes\u003C\u002Fbutton>\n    \u003C\u002Fsection>\n  \u003C\u002Fdiv>\n\n  \u003Cdiv class=\"region region--day\">\n    \u003Csection class=\"panel\">\n      \u003Ch2 class=\"panel__title\">Audit log\u003C\u002Fh2>\n      \u003Cp class=\"panel__body\">Retained for ninety days, then archived.\u003C\u002Fp>\n      \u003Cbutton class=\"panel__action\" type=\"button\">Open log\u003C\u002Fbutton>\n    \u003C\u002Fsection>\n  \u003C\u002Fdiv>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>\n","html","",[18,211,212,232,252,262,280,294,304,311,317,332,339,345,351,361,374,380,385,391,403,416,421,485,490,499,515,530,551,566,579,592,597,646,680,688,706,723,737,749,760,787,800,805,840,845,851,857,866,904,921,955,973,978,988,997,1007,1026,1044,1066,1087,1117,1127,1137,1142,1158,1173,1193,1213,1239,1248,1257,1266],{"__ignoreMap":209},[213,214,217,221,225,229],"span",{"class":215,"line":216},"line",1,[213,218,220],{"class":219},"suds8","\u003C!",[213,222,224],{"class":223},"sne4z","doctype",[213,226,228],{"class":227},"s-5SL"," html",[213,230,231],{"class":219},">\n",[213,233,235,238,240,243,246,250],{"class":215,"line":234},2,[213,236,237],{"class":219},"\u003C",[213,239,208],{"class":223},[213,241,242],{"class":227}," lang",[213,244,245],{"class":219},"=",[213,247,249],{"class":248},"sT6z2","\"en\"",[213,251,231],{"class":219},[213,253,255,257,260],{"class":215,"line":254},3,[213,256,237],{"class":219},[213,258,259],{"class":223},"head",[213,261,231],{"class":219},[213,263,265,267,270,273,275,278],{"class":215,"line":264},4,[213,266,237],{"class":219},[213,268,269],{"class":223},"meta",[213,271,272],{"class":227}," charset",[213,274,245],{"class":219},[213,276,277],{"class":248},"\"utf-8\"",[213,279,231],{"class":219},[213,281,283,285,287,290,292],{"class":215,"line":282},5,[213,284,237],{"class":219},[213,286,93],{"class":223},[213,288,289],{"class":219},">Token-themed panel\u003C\u002F",[213,291,93],{"class":223},[213,293,231],{"class":219},[213,295,297,299,302],{"class":215,"line":296},6,[213,298,237],{"class":219},[213,300,301],{"class":223},"style",[213,303,231],{"class":219},[213,305,307],{"class":215,"line":306},7,[213,308,310],{"class":309},"sLBg1","  \u002F* The token's only job is to name a theme. It carries no colours itself, so a\n",[213,312,314],{"class":215,"line":313},8,[213,315,316],{"class":309},"     region can switch theme without knowing what any component does with it. *\u002F\n",[213,318,320,323,326,329],{"class":215,"line":319},9,[213,321,322],{"class":227},"  :root",[213,324,325],{"class":219}," { ",[213,327,20],{"class":328},"soyes",[213,330,331],{"class":219},": day; }\n",[213,333,335],{"class":215,"line":334},10,[213,336,338],{"emptyLinePlaceholder":337},true,"\n",[213,340,342],{"class":215,"line":341},11,[213,343,344],{"class":309},"  \u002F* One rule maps the OS preference onto the token. Every style query below\n",[213,346,348],{"class":215,"line":347},12,[213,349,350],{"class":309},"     responds without being duplicated inside a media query. *\u002F\n",[213,352,354,358],{"class":215,"line":353},13,[213,355,357],{"class":356},"sHUrx","  @media",[213,359,360],{"class":219}," (prefers-color-scheme: dark) {\n",[213,362,364,367,369,371],{"class":215,"line":363},14,[213,365,366],{"class":227},"    :root",[213,368,325],{"class":219},[213,370,20],{"class":328},[213,372,373],{"class":219},": dusk; }\n",[213,375,377],{"class":215,"line":376},15,[213,378,379],{"class":219},"  }\n",[213,381,383],{"class":215,"line":382},16,[213,384,338],{"emptyLinePlaceholder":337},[213,386,388],{"class":215,"line":387},17,[213,389,390],{"class":309},"  \u002F* Any region can override for its own subtree — no selector changes required. *\u002F\n",[213,392,394,397,399,401],{"class":215,"line":393},18,[213,395,396],{"class":227},"  .region--dusk",[213,398,325],{"class":219},[213,400,20],{"class":328},[213,402,373],{"class":219},[213,404,406,409,412,414],{"class":215,"line":405},19,[213,407,408],{"class":227},"  .region--day",[213,410,411],{"class":219},"  { ",[213,413,20],{"class":328},[213,415,331],{"class":219},[213,417,419],{"class":215,"line":418},20,[213,420,338],{"emptyLinePlaceholder":337},[213,422,424,427,429,432,435,438,441,444,447,449,452,455,458,461,464,466,469,471,474,476,479,482],{"class":215,"line":423},21,[213,425,426],{"class":223},"  body",[213,428,325],{"class":219},[213,430,431],{"class":227},"font",[213,433,434],{"class":219},": ",[213,436,437],{"class":227},"400",[213,439,440],{"class":227}," 16",[213,442,443],{"class":356},"px",[213,445,446],{"class":219},"\u002F",[213,448,116],{"class":227},[213,450,451],{"class":227}," system-ui",[213,453,454],{"class":219},", ",[213,456,457],{"class":227},"sans-serif",[213,459,460],{"class":219},"; ",[213,462,463],{"class":227},"margin",[213,465,434],{"class":219},[213,467,468],{"class":227},"0",[213,470,460],{"class":219},[213,472,473],{"class":227},"padding",[213,475,434],{"class":219},[213,477,478],{"class":227},"2",[213,480,481],{"class":356},"rem",[213,483,484],{"class":219},"; }\n",[213,486,488],{"class":215,"line":487},22,[213,489,338],{"emptyLinePlaceholder":337},[213,491,493,496],{"class":215,"line":492},23,[213,494,495],{"class":227},"  .panel",[213,497,498],{"class":219}," {\n",[213,500,502,505,507,510,512],{"class":215,"line":501},24,[213,503,504],{"class":227},"    max-inline-size",[213,506,434],{"class":219},[213,508,509],{"class":227},"32",[213,511,481],{"class":356},[213,513,514],{"class":219},";\n",[213,516,518,521,523,526,528],{"class":215,"line":517},25,[213,519,520],{"class":227},"    padding",[213,522,434],{"class":219},[213,524,525],{"class":227},"1.25",[213,527,481],{"class":356},[213,529,514],{"class":219},[213,531,533,536,538,541,543,546,549],{"class":215,"line":532},26,[213,534,535],{"class":227},"    border",[213,537,434],{"class":219},[213,539,540],{"class":227},"1",[213,542,443],{"class":356},[213,544,545],{"class":227}," solid",[213,547,548],{"class":227}," #d0d5dd",[213,550,514],{"class":219},[213,552,554,557,559,562,564],{"class":215,"line":553},27,[213,555,556],{"class":227},"    border-radius",[213,558,434],{"class":219},[213,560,561],{"class":227},"12",[213,563,443],{"class":356},[213,565,514],{"class":219},[213,567,569,572,574,577],{"class":215,"line":568},28,[213,570,571],{"class":227},"    background",[213,573,434],{"class":219},[213,575,576],{"class":227},"#ffffff",[213,578,514],{"class":219},[213,580,582,585,587,590],{"class":215,"line":581},29,[213,583,584],{"class":227},"    color",[213,586,434],{"class":219},[213,588,589],{"class":227},"#101828",[213,591,514],{"class":219},[213,593,595],{"class":215,"line":594},30,[213,596,379],{"class":219},[213,598,600,603,605,607,609,611,614,617,619,621,623,625,628,631,633,635,638,640,642,644],{"class":215,"line":599},31,[213,601,602],{"class":227},"  .panel__title",[213,604,411],{"class":219},[213,606,463],{"class":227},[213,608,434],{"class":219},[213,610,468],{"class":227},[213,612,613],{"class":227}," 0",[213,615,616],{"class":227}," .4",[213,618,481],{"class":356},[213,620,460],{"class":219},[213,622,431],{"class":227},[213,624,434],{"class":219},[213,626,627],{"class":227},"600",[213,629,630],{"class":227}," 1.05",[213,632,481],{"class":356},[213,634,446],{"class":219},[213,636,637],{"class":227},"1.3",[213,639,451],{"class":227},[213,641,454],{"class":219},[213,643,457],{"class":227},[213,645,484],{"class":219},[213,647,649,652,655,657,659,661,663,666,668,670,673,675,678],{"class":215,"line":648},32,[213,650,651],{"class":227},"  .panel__body",[213,653,654],{"class":219},"   { ",[213,656,463],{"class":227},[213,658,434],{"class":219},[213,660,468],{"class":227},[213,662,613],{"class":227},[213,664,665],{"class":227}," 1",[213,667,481],{"class":356},[213,669,460],{"class":219},[213,671,672],{"class":227},"color",[213,674,434],{"class":219},[213,676,677],{"class":227},"#667085",[213,679,484],{"class":219},[213,681,683,686],{"class":215,"line":682},33,[213,684,685],{"class":227},"  .panel__action",[213,687,498],{"class":219},[213,689,691,693,695,698,700,702,704],{"class":215,"line":690},34,[213,692,520],{"class":227},[213,694,434],{"class":219},[213,696,697],{"class":227},".5",[213,699,481],{"class":356},[213,701,665],{"class":227},[213,703,481],{"class":356},[213,705,514],{"class":219},[213,707,709,711,713,715,717,719,721],{"class":215,"line":708},35,[213,710,535],{"class":227},[213,712,434],{"class":219},[213,714,540],{"class":227},[213,716,443],{"class":356},[213,718,545],{"class":227},[213,720,548],{"class":227},[213,722,514],{"class":219},[213,724,726,728,730,733,735],{"class":215,"line":725},36,[213,727,556],{"class":227},[213,729,434],{"class":219},[213,731,732],{"class":227},"8",[213,734,443],{"class":356},[213,736,514],{"class":219},[213,738,740,742,744,747],{"class":215,"line":739},37,[213,741,571],{"class":227},[213,743,434],{"class":219},[213,745,746],{"class":227},"#f9fafb",[213,748,514],{"class":219},[213,750,752,754,756,758],{"class":215,"line":751},38,[213,753,584],{"class":227},[213,755,434],{"class":219},[213,757,589],{"class":227},[213,759,514],{"class":219},[213,761,763,766,768,770,773,775,777,779,781,783,785],{"class":215,"line":762},39,[213,764,765],{"class":227},"    font",[213,767,434],{"class":219},[213,769,627],{"class":227},[213,771,772],{"class":227}," .875",[213,774,481],{"class":356},[213,776,446],{"class":219},[213,778,540],{"class":227},[213,780,451],{"class":227},[213,782,454],{"class":219},[213,784,457],{"class":227},[213,786,514],{"class":219},[213,788,790,793,795,798],{"class":215,"line":789},40,[213,791,792],{"class":227},"    cursor",[213,794,434],{"class":219},[213,796,797],{"class":227},"pointer",[213,799,514],{"class":219},[213,801,803],{"class":215,"line":802},41,[213,804,379],{"class":219},[213,806,808,811,813,816,818,820,822,824,827,829,832,834,836,838],{"class":215,"line":807},42,[213,809,810],{"class":227},"  .panel__action:focus-visible",[213,812,325],{"class":219},[213,814,815],{"class":227},"outline",[213,817,434],{"class":219},[213,819,478],{"class":227},[213,821,443],{"class":356},[213,823,545],{"class":227},[213,825,826],{"class":227}," #7aa2ff",[213,828,460],{"class":219},[213,830,831],{"class":227},"outline-offset",[213,833,434],{"class":219},[213,835,478],{"class":227},[213,837,443],{"class":356},[213,839,484],{"class":219},[213,841,843],{"class":215,"line":842},43,[213,844,338],{"emptyLinePlaceholder":337},[213,846,848],{"class":215,"line":847},44,[213,849,850],{"class":309},"  \u002F* The theme block. Note the selectors: identical to the base rules above, not\n",[213,852,854],{"class":215,"line":853},45,[213,855,856],{"class":309},"     prefixed with any theme selector. Same specificity, later source order. *\u002F\n",[213,858,860,863],{"class":215,"line":859},46,[213,861,862],{"class":356},"  @container",[213,864,865],{"class":219}," style(--theme: dusk) {\n",[213,867,869,872,875,878,880,883,885,888,890,893,895,897,899,902],{"class":215,"line":868},47,[213,870,871],{"class":227},"    .panel",[213,873,874],{"class":219},"         { ",[213,876,877],{"class":227},"background",[213,879,434],{"class":219},[213,881,882],{"class":227},"#1c2333",[213,884,460],{"class":219},[213,886,887],{"class":227},"border-color",[213,889,434],{"class":219},[213,891,892],{"class":227},"#33405c",[213,894,460],{"class":219},[213,896,672],{"class":227},[213,898,434],{"class":219},[213,900,901],{"class":227},"#e8ecf7",[213,903,484],{"class":219},[213,905,907,910,912,914,916,919],{"class":215,"line":906},48,[213,908,909],{"class":227},"    .panel__body",[213,911,654],{"class":219},[213,913,672],{"class":227},[213,915,434],{"class":219},[213,917,918],{"class":227},"#a9b4cc",[213,920,484],{"class":219},[213,922,924,927,929,931,933,936,938,940,942,945,947,949,951,953],{"class":215,"line":923},49,[213,925,926],{"class":227},"    .panel__action",[213,928,325],{"class":219},[213,930,877],{"class":227},[213,932,434],{"class":219},[213,934,935],{"class":227},"#26304a",[213,937,460],{"class":219},[213,939,887],{"class":227},[213,941,434],{"class":219},[213,943,944],{"class":227},"#3c4a69",[213,946,460],{"class":219},[213,948,672],{"class":227},[213,950,434],{"class":219},[213,952,901],{"class":227},[213,954,484],{"class":219},[213,956,958,961,963,966,968,971],{"class":215,"line":957},50,[213,959,960],{"class":227},"    .panel__action:focus-visible",[213,962,325],{"class":219},[213,964,965],{"class":227},"outline-color",[213,967,434],{"class":219},[213,969,970],{"class":227},"#9dbaff",[213,972,484],{"class":219},[213,974,976],{"class":215,"line":975},51,[213,977,379],{"class":219},[213,979,981,984,986],{"class":215,"line":980},52,[213,982,983],{"class":219},"\u003C\u002F",[213,985,301],{"class":223},[213,987,231],{"class":219},[213,989,991,993,995],{"class":215,"line":990},53,[213,992,983],{"class":219},[213,994,259],{"class":223},[213,996,231],{"class":219},[213,998,1000,1002,1005],{"class":215,"line":999},54,[213,1001,237],{"class":219},[213,1003,1004],{"class":223},"body",[213,1006,231],{"class":219},[213,1008,1010,1013,1016,1019,1021,1024],{"class":215,"line":1009},55,[213,1011,1012],{"class":219},"  \u003C",[213,1014,1015],{"class":223},"div",[213,1017,1018],{"class":227}," class",[213,1020,245],{"class":219},[213,1022,1023],{"class":248},"\"region region--dusk\"",[213,1025,231],{"class":219},[213,1027,1029,1032,1035,1037,1039,1042],{"class":215,"line":1028},56,[213,1030,1031],{"class":219},"    \u003C",[213,1033,1034],{"class":223},"section",[213,1036,1018],{"class":227},[213,1038,245],{"class":219},[213,1040,1041],{"class":248},"\"panel\"",[213,1043,231],{"class":219},[213,1045,1047,1050,1052,1054,1056,1059,1062,1064],{"class":215,"line":1046},57,[213,1048,1049],{"class":219},"      \u003C",[213,1051,42],{"class":223},[213,1053,1018],{"class":227},[213,1055,245],{"class":219},[213,1057,1058],{"class":248},"\"panel__title\"",[213,1060,1061],{"class":219},">Deployment window\u003C\u002F",[213,1063,42],{"class":223},[213,1065,231],{"class":219},[213,1067,1069,1071,1073,1075,1077,1080,1083,1085],{"class":215,"line":1068},58,[213,1070,1049],{"class":219},[213,1072,14],{"class":223},[213,1074,1018],{"class":227},[213,1076,245],{"class":219},[213,1078,1079],{"class":248},"\"panel__body\"",[213,1081,1082],{"class":219},">Changes are applied during the next maintenance window.\u003C\u002F",[213,1084,14],{"class":223},[213,1086,231],{"class":219},[213,1088,1090,1092,1095,1097,1099,1102,1105,1107,1110,1113,1115],{"class":215,"line":1089},59,[213,1091,1049],{"class":219},[213,1093,1094],{"class":223},"button",[213,1096,1018],{"class":227},[213,1098,245],{"class":219},[213,1100,1101],{"class":248},"\"panel__action\"",[213,1103,1104],{"class":227}," type",[213,1106,245],{"class":219},[213,1108,1109],{"class":248},"\"button\"",[213,1111,1112],{"class":219},">Review changes\u003C\u002F",[213,1114,1094],{"class":223},[213,1116,231],{"class":219},[213,1118,1120,1123,1125],{"class":215,"line":1119},60,[213,1121,1122],{"class":219},"    \u003C\u002F",[213,1124,1034],{"class":223},[213,1126,231],{"class":219},[213,1128,1130,1133,1135],{"class":215,"line":1129},61,[213,1131,1132],{"class":219},"  \u003C\u002F",[213,1134,1015],{"class":223},[213,1136,231],{"class":219},[213,1138,1140],{"class":215,"line":1139},62,[213,1141,338],{"emptyLinePlaceholder":337},[213,1143,1145,1147,1149,1151,1153,1156],{"class":215,"line":1144},63,[213,1146,1012],{"class":219},[213,1148,1015],{"class":223},[213,1150,1018],{"class":227},[213,1152,245],{"class":219},[213,1154,1155],{"class":248},"\"region region--day\"",[213,1157,231],{"class":219},[213,1159,1161,1163,1165,1167,1169,1171],{"class":215,"line":1160},64,[213,1162,1031],{"class":219},[213,1164,1034],{"class":223},[213,1166,1018],{"class":227},[213,1168,245],{"class":219},[213,1170,1041],{"class":248},[213,1172,231],{"class":219},[213,1174,1176,1178,1180,1182,1184,1186,1189,1191],{"class":215,"line":1175},65,[213,1177,1049],{"class":219},[213,1179,42],{"class":223},[213,1181,1018],{"class":227},[213,1183,245],{"class":219},[213,1185,1058],{"class":248},[213,1187,1188],{"class":219},">Audit log\u003C\u002F",[213,1190,42],{"class":223},[213,1192,231],{"class":219},[213,1194,1196,1198,1200,1202,1204,1206,1209,1211],{"class":215,"line":1195},66,[213,1197,1049],{"class":219},[213,1199,14],{"class":223},[213,1201,1018],{"class":227},[213,1203,245],{"class":219},[213,1205,1079],{"class":248},[213,1207,1208],{"class":219},">Retained for ninety days, then archived.\u003C\u002F",[213,1210,14],{"class":223},[213,1212,231],{"class":219},[213,1214,1216,1218,1220,1222,1224,1226,1228,1230,1232,1235,1237],{"class":215,"line":1215},67,[213,1217,1049],{"class":219},[213,1219,1094],{"class":223},[213,1221,1018],{"class":227},[213,1223,245],{"class":219},[213,1225,1101],{"class":248},[213,1227,1104],{"class":227},[213,1229,245],{"class":219},[213,1231,1109],{"class":248},[213,1233,1234],{"class":219},">Open log\u003C\u002F",[213,1236,1094],{"class":223},[213,1238,231],{"class":219},[213,1240,1242,1244,1246],{"class":215,"line":1241},68,[213,1243,1122],{"class":219},[213,1245,1034],{"class":223},[213,1247,231],{"class":219},[213,1249,1251,1253,1255],{"class":215,"line":1250},69,[213,1252,1132],{"class":219},[213,1254,1015],{"class":223},[213,1256,231],{"class":219},[213,1258,1260,1262,1264],{"class":215,"line":1259},70,[213,1261,983],{"class":219},[213,1263,1004],{"class":223},[213,1265,231],{"class":219},[213,1267,1269,1271,1273],{"class":215,"line":1268},71,[213,1270,983],{"class":219},[213,1272,208],{"class":223},[213,1274,231],{"class":219},[14,1276,1277],{},"Both panels use byte-identical markup. The only difference is which token value they inherit, and both regions sit on the same page — which no single global theme class can express without a second class vocabulary for exceptions.",[39,1279],{},[42,1281,1283],{"id":1282},"key-technique-same-selector-later-source-order","Key technique: same selector, later source order",[14,1285,1286,1287,1290,1291,1294,1295,1298,1299,1302],{},"This is the property that makes token theming maintainable, and it is worth stating precisely. The ",[18,1288,1289],{},"@container"," at-rule contributes nothing to specificity. A rule written as ",[18,1292,1293],{},".panel__action { … }"," inside a style query has specificity ",[18,1296,1297],{},"0,1,0"," — exactly what it would have outside. When it competes with the base ",[18,1300,1301],{},".panel__action"," rule, the winner is whichever appears later in the stylesheet.",[14,1304,1305],{},"That has two practical implications.",[14,1307,1308,1312,1313,37],{},[1309,1310,1311],"strong",{},"Theme blocks must come after base rules."," There is no specificity cushion protecting them. Put the base component styles first and every theme block after, or place them in explicit cascade layers so order is declared rather than inferred — the tradeoff between layers and specificity tricks is set out in ",[23,1314,1316],{"href":1315},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-vs-specificity-hacks\u002F","cascade layers vs specificity hacks",[14,1318,1319,1322,1323,1326,1327,1330,1331,1333],{},[1309,1320,1321],{},"An unrelated compound selector still beats a theme block."," If some legacy rule says ",[18,1324,1325],{},".sidebar .panel__action { background: #fff }"," at ",[18,1328,1329],{},"0,2,0",", your theme block at ",[18,1332,1297],{}," loses no matter where it sits. This is the failure mode teams hit when introducing token theming into an existing sheet, and the fix is to reduce the offending selector, not to escalate the theme block. Escalating puts you straight back into the specificity race the token was meant to end.",[14,1335,1336,1337,1339,1340,1343],{},"The absence of a specificity bump is also what makes nesting free. Redeclare ",[18,1338,20],{}," on an inner region and its subtree re-themes, because the query resolves against the nearest ancestor holding the token. No ",[18,1341,1342],{},":not()"," exclusions, no theme-reset class, no ordering puzzle.",[39,1345],{},[42,1347,1349],{"id":1348},"variation-a-second-axis-without-multiplying-rules","Variation: a second axis without multiplying rules",[14,1351,1352,1353,1356],{},"Add emphasis as an independent token and the two axes compose instead of multiplying. With classes you would need ",[18,1354,1355],{},".panel--dusk.panel--loud","; here each block is written once and both apply when both tokens match.",[204,1358,1362],{"className":1359,"code":1360,"language":1361,"meta":209,"style":209},"language-css shiki shiki-themes github-light-high-contrast github-dark-high-contrast","\u002F* Axis 2, declared alongside the theme on any ancestor. *\u002F\n.region--loud { --emphasis: loud; }\n\n@container style(--emphasis: loud) {\n  .panel { border-width: 2px; }\n  .panel__title { font-size: 1.25rem; }\n}\n\n\u002F* Only where the two genuinely interact do you write a combined query — and this\n   is the exception, not the rule, so there is one of these rather than N × M. *\u002F\n@container style(--theme: dusk) and style(--emphasis: loud) {\n  .panel { box-shadow: 0 0 0 1px #7aa2ff inset; }\n}\n","css",[18,1363,1364,1369,1382,1386,1393,1410,1427,1432,1436,1441,1446,1453,1481],{"__ignoreMap":209},[213,1365,1366],{"class":215,"line":216},[213,1367,1368],{"class":309},"\u002F* Axis 2, declared alongside the theme on any ancestor. *\u002F\n",[213,1370,1371,1374,1376,1379],{"class":215,"line":234},[213,1372,1373],{"class":227},".region--loud",[213,1375,325],{"class":219},[213,1377,1378],{"class":328},"--emphasis",[213,1380,1381],{"class":219},": loud; }\n",[213,1383,1384],{"class":215,"line":254},[213,1385,338],{"emptyLinePlaceholder":337},[213,1387,1388,1390],{"class":215,"line":264},[213,1389,1289],{"class":356},[213,1391,1392],{"class":219}," style(--emphasis: loud) {\n",[213,1394,1395,1397,1399,1402,1404,1406,1408],{"class":215,"line":282},[213,1396,495],{"class":227},[213,1398,325],{"class":219},[213,1400,1401],{"class":227},"border-width",[213,1403,434],{"class":219},[213,1405,478],{"class":227},[213,1407,443],{"class":356},[213,1409,484],{"class":219},[213,1411,1412,1414,1416,1419,1421,1423,1425],{"class":215,"line":296},[213,1413,602],{"class":227},[213,1415,325],{"class":219},[213,1417,1418],{"class":227},"font-size",[213,1420,434],{"class":219},[213,1422,525],{"class":227},[213,1424,481],{"class":356},[213,1426,484],{"class":219},[213,1428,1429],{"class":215,"line":306},[213,1430,1431],{"class":219},"}\n",[213,1433,1434],{"class":215,"line":313},[213,1435,338],{"emptyLinePlaceholder":337},[213,1437,1438],{"class":215,"line":319},[213,1439,1440],{"class":309},"\u002F* Only where the two genuinely interact do you write a combined query — and this\n",[213,1442,1443],{"class":215,"line":334},[213,1444,1445],{"class":309},"   is the exception, not the rule, so there is one of these rather than N × M. *\u002F\n",[213,1447,1448,1450],{"class":215,"line":341},[213,1449,1289],{"class":356},[213,1451,1452],{"class":219}," style(--theme: dusk) and style(--emphasis: loud) {\n",[213,1454,1455,1457,1459,1462,1464,1466,1468,1470,1472,1474,1476,1479],{"class":215,"line":347},[213,1456,495],{"class":227},[213,1458,325],{"class":219},[213,1460,1461],{"class":227},"box-shadow",[213,1463,434],{"class":219},[213,1465,468],{"class":227},[213,1467,613],{"class":227},[213,1469,613],{"class":227},[213,1471,665],{"class":227},[213,1473,443],{"class":356},[213,1475,826],{"class":227},[213,1477,1478],{"class":227}," inset",[213,1480,484],{"class":219},[213,1482,1483],{"class":215,"line":353},[213,1484,1431],{"class":219},[14,1486,1487],{},"For right-to-left interfaces nothing changes, because the theme axis is colour and the component already uses logical properties for spacing. That independence is the point: a token axis should describe one concern, and axes that describe different concerns should never appear together in a selector.",[39,1489],{},[42,1491,1493],{"id":1492},"browser-support","Browser support",[14,1495,1496,1497,1500,1501,37],{},"Style query theming works in Chrome and Edge 111+, Firefox 151+, and Safari 18+, so every current engine themes from the token. Older versions of any of those engines drop the theme block, and the design survives that cleanly because the block only ever overrides colours the base rules already set — which is why the base rules above are a complete, legible light theme rather than a partial starting point. Where a dark result is genuinely required on the oldest engines you support, keep a ",[18,1498,1499],{},"prefers-color-scheme"," block as the baseline and use the token only for per-region overrides that no media query can express; the layering pattern for that is in ",[23,1502,1504],{"href":1503},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fstyle-query-fallbacks-and-support\u002F","style query fallbacks and support",[39,1506],{},[42,1508,1510],{"id":1509},"faq","FAQ",[14,1512,1513,1519],{},[1309,1514,1515,1516,1518],{},"Why not just use a theme class on the ",[18,1517,1004],{}," element?","\nA body class forces every themed rule to be written as a descendant selector, which raises specificity and couples the component to a global class name. A token inherits without appearing in any selector.",[14,1521,1522,1525],{},[1309,1523,1524],{},"Does a style query add specificity to the rules inside it?","\nNo. At-rules contribute nothing to specificity, so a rule inside a style query has exactly the specificity of its own selector. Two competing theme blocks are resolved by source order unless their selectors differ.",[14,1527,1528,1531],{},[1309,1529,1530],{},"Can I nest one theme inside another?","\nYes. Because the token inherits and the query resolves against the nearest ancestor, redeclaring the token on an inner region themes that subtree only, with no selector changes anywhere.",[14,1533,1534,1540],{},[1309,1535,1536,1537,1539],{},"How does this interact with ",[18,1538,1499],{},"?","\nSet the token from the media query rather than restyling components inside it. One rule maps the user preference onto the token, and every existing style query continues to work unchanged.",[39,1542],{},[42,1544,1546],{"id":1545},"related","Related",[1548,1549,1550,1561,1567,1573,1580],"ul",{},[1551,1552,1553,1556,1557,1560],"li",{},[23,1554,1555],{"href":25},"Style queries and container state"," — the parent guide for the ",[18,1558,1559],{},"style()"," model.",[1551,1562,1563,1566],{},[23,1564,1565],{"href":35},"Style queries with custom properties"," — the matching and inheritance rules this page relies on.",[1551,1568,1569,1572],{},[23,1570,1571],{"href":1503},"Style query fallbacks and support"," — keeping the theme correct on browser versions that predate the feature.",[1551,1574,1575,1579],{},[23,1576,1578],{"href":1577},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fbuilding-responsive-cards-with-container-queries\u002F","Building responsive cards with container queries"," — the size-driven counterpart to this token-driven card work.",[1551,1581,1582,1586],{},[23,1583,1585],{"href":1584},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Fanimating-custom-properties-with-at-property\u002F","Animating custom properties with @property"," — making token changes transition rather than snap.",[301,1588,1589],{},"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 .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 .sHUrx, html code.shiki .sHUrx{--shiki-default:#A0111F;--shiki-dark:#FF9492}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":209,"searchDepth":234,"depth":234,"links":1591},[1592,1593,1594,1595,1596,1597,1598],{"id":44,"depth":234,"text":45},{"id":198,"depth":234,"text":199},{"id":1282,"depth":234,"text":1283},{"id":1348,"depth":234,"text":1349},{"id":1492,"depth":234,"text":1493},{"id":1509,"depth":234,"text":1510},{"id":1545,"depth":234,"text":1546},"Theme components with @container style(--theme): one inherited token restyles a panel, compared with theme classes and data attributes on specificity and scale.","md",{"pageTitle":1602,"datePublished":1603,"dateModified":1603,"faq":1604},"Container Style Query Theming","2026-07-20",[1605,1608,1610,1612],{"q":1606,"a":1607},"Why not just use a theme class on the body element?","A body class forces every themed rule to be written as a descendant selector, which raises specificity and couples the component to a global class name. A token inherits without appearing in any selector.",{"q":1524,"a":1609},"No. At-rules contribute nothing to specificity, so a rule inside a style query has exactly the specificity of its own selector. Two competing theme blocks are resolved by source order unless their selectors differ.",{"q":1530,"a":1611},"Yes. Because the token inherits and the query resolves against the nearest ancestor, redeclaring the token on an inner region themes that subtree only, with no selector changes anywhere.",{"q":1613,"a":1614},"How does this interact with prefers-color-scheme?","Set the token from the media query rather than restyling components inside it. One rule maps the user preference onto the token, and every existing style query continues to work unchanged.","\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fcontainer-style-query-theming",{"title":5,"description":1599},"mastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fcontainer-style-query-theming\u002Findex","GgvLRgauyTKq-OSNdWd7Ihz3mEkdVc3BP--RnFe5nnE",[1620,1623,1626,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,1760,1763,1766,1769,1772,1775,1778,1781,1784,1787,1790,1793,1796,1799,1802,1805,1808,1811,1814,1817,1820,1823,1826,1829,1831,1834,1837,1840,1843,1846,1849,1852,1855,1858,1861,1864,1867,1870,1871,1874,1877],{"path":1621,"title":1622},"\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":1624,"title":1625},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations","Accessibility in CSS Animations: Patterns, Specs & Best Practices",{"path":1627,"title":1628},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fprefers-reduced-motion-recipes","prefers-reduced-motion Recipes: A Reduction for Every Common Effect",{"path":1630,"title":1631},"\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":1633,"title":1634},"\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":1636,"title":1637},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fvestibular-safe-animation-patterns","Vestibular-Safe Animation Patterns: Why Some Motion Makes People Sick",{"path":1639,"title":1640},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fwcag-motion-success-criteria","WCAG Motion Success Criteria: What Each One Actually Requires",{"path":1642,"title":1643},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fcontainer-query-hover-affordances","Container Query Hover Affordances: When Narrow Means Persistent, Not Hidden",{"path":1645,"title":1646},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion","Container-Aware Motion: Animation Sized by the Space a Component Actually Has",{"path":1648,"title":1649},"\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":1651,"title":1652},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fsuppressing-motion-in-small-containers","Suppressing Motion in Small Containers: Deliberately Animating Nothing",{"path":1654,"title":1655},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api","CSS Animation vs the Web Animations API: A Decision Guide",{"path":1657,"title":1658},"\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":1660,"title":1661},"\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":1663,"title":1664},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Ffluid-spacing-tokens-driving-transition-durations","Fluid Spacing Tokens That Drive Transition Durations",{"path":1666,"title":1667},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture","CSS Custom Properties Architecture: Scalable Design Systems & Dynamic UI",{"path":1669,"title":1670},"\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":1672,"title":1673},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fcss-transition-timing-functions","CSS Transition Timing Functions: ease, cubic-bezier(), steps() and linear()",{"path":1675,"title":1676},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals","CSS Transition Fundamentals: Architecture, Performance & Patterns",{"path":1678,"title":1679},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fstarting-style-entry-animations","@starting-style: Animating an Element's Very First Style Change",{"path":1681,"title":1682},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransitioning-display-with-allow-discrete","Transitioning display with transition-behavior: allow-discrete and @starting-style",{"path":1684,"title":1685},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Faccessible-css-only-tooltips","Accessible CSS-Only Tooltips and Hover Cards With  and ",{"path":1687,"title":1688},"\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":1690,"title":1691},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Ffocus-within-form-patterns"," Form Patterns: Styling a Group From the Field Inside It",{"path":1693,"title":1694},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design","Hover & Focus State Design: Spec-Compliant Patterns for Modern UIs",{"path":1696,"title":1697},"\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":1699,"title":1700},"\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":1702,"title":1703},"\u002Fcss-only-micro-interactions-animations","CSS-Only Micro-Interactions & Animations: Architecture, Performance & Implementation",{"path":1705,"title":1706},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcontainer-query-triggered-keyframe-animations","Container-Query-Triggered Keyframe Animations: Animate Differently per Available Space",{"path":1708,"title":1709},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcss-only-accordions-and-disclosure","CSS-Only Accordions and Disclosure Widgets with details and summary",{"path":1711,"title":1712},"\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":1714,"title":1715},"\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":1717,"title":1718},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns","Keyframe Animation Patterns: Spec-Compliant Architectures for Modern UIs",{"path":1720,"title":1721},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fstaggered-list-animations-with-custom-properties","Staggered List Animations Using --i Index Custom Properties",{"path":1723,"title":1724},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration","Performance & GPU Acceleration in CSS: A Developer’s Blueprint",{"path":1726,"title":1727},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Foptimizing-css-animations-for-60fps","Optimizing CSS Animations for 60fps: Budgeting the Frame",{"path":1729,"title":1730},"\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":1732,"title":1733},"\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":1735,"title":1736},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations","Scroll-Driven Animations: Binding Motion to Scroll Position in Pure CSS",{"path":1738,"title":1739},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-driven-animation-fallbacks","Shipping Scroll-Driven Animations Without Breaking Anything",{"path":1741,"title":1742},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-progress-bar-without-javascript","A Reading Progress Bar Driven by scroll(root)",{"path":1744,"title":1745},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-triggered-reveal-animations","Reveal-on-Scroll with view() and animation-range",{"path":1747,"title":1748},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers","View Transitions for CSS Developers: the Pseudo-Element Tree, Snapshots, and Named Elements",{"path":1750,"title":1751},"\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":1753,"title":1754},"\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":1756,"title":1757},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transitions-with-reduced-motion","Honouring prefers-reduced-motion in View Transitions",{"path":446,"title":1759},"Modern CSS Layouts & Micro-Interactions",{"path":1761,"title":1762},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-positioned-tooltips","Anchor-Positioned Tooltips: Tethering, Flipping, and Getting the Semantics Right",{"path":1764,"title":1765},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-positioning-fallbacks","Anchor Positioning Fallbacks: A Graceful Floor for Older Browser Versions",{"path":1767,"title":1768},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays","CSS Anchor Positioning and Overlays: Tethering Elements Without JavaScript",{"path":1770,"title":1771},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fpopover-attribute-and-css-styling","The popover Attribute: Top-Layer Overlays With No JavaScript",{"path":1773,"title":1774},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Ffeature-detection-with-supports","Feature Detection with @supports: Syntax, Semantics, and the Traps",{"path":1776,"title":1777},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fhandling-container-query-fallbacks-for-older-browsers","Handling Container Query Fallbacks for Older Browsers",{"path":1779,"title":1780},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks","Container Query Fallbacks: Spec-Compliant CSS Strategies for Legacy Browsers",{"path":1782,"title":1783},"\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":1785,"title":1786},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-type-size-vs-inline-size","Choosing container-type: inline-size, size, or normal",{"path":1788,"title":1789},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-vs-media-queries-comparison","Container vs Media Queries: Choosing the Right Reference Box",{"path":1791,"title":1792},"\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":1794,"title":1795},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics","Container Query Syntax Basics",{"path":1797,"title":1798},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fnesting-and-naming-container-queries","Nesting and Naming Container Queries: Targeting the Right Ancestor",{"path":1800,"title":1801},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fauto-fit-minmax-responsive-grids","Responsive Grids with repeat(auto-fit, minmax())",{"path":1803,"title":1804},"\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":1806,"title":1807},"\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":1809,"title":1810},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts","CSS Grid and Subgrid Layouts for Responsive Interfaces",{"path":1812,"title":1813},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fsubgrid-vs-nested-grid","Subgrid vs an Independently Nested Grid",{"path":1815,"title":1816},"\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":1818,"title":1819},"\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":1821,"title":1822},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-type-accessibility-and-zoom","Fluid Type, Accessibility and Zoom: The vw-Only Trap",{"path":1824,"title":1825},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-typography-without-javascript","Fluid Typography Without JavaScript: A Precision CSS Reference",{"path":1827,"title":1828},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp","Fluid Typography with clamp(): A Practical Guide for Modern CSS",{"path":1830,"title":31},"\u002Fmastering-container-queries-responsive-layouts",{"path":1832,"title":1833},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Faspect-ratio-for-responsive-media","Using aspect-ratio for Responsive Media and Preventing Layout Shift",{"path":1835,"title":1836},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques","Intrinsic Sizing Techniques: Modern CSS Layouts for Responsive UI",{"path":1838,"title":1839},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fmin-max-fit-content-explained","min-content, max-content, and fit-content() Explained",{"path":1841,"title":1842},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fpreventing-flex-and-grid-overflow","The min-width: auto Trap in Flex and Grid Layouts",{"path":1844,"title":1845},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-for-reset-and-tokens","Cascade Layers for Reset and Design Tokens",{"path":1847,"title":1848},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-vs-specificity-hacks","Cascade Layers vs Specificity Hacks: Ordering Instead of Escalating",{"path":1850,"title":1851},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies","Modern CSS Reset Strategies: A Spec-Compliant Foundation",{"path":1853,"title":1854},"\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":1856,"title":1857},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fcontainer-query-data-tables","Container Query Data Tables: Reflowing Tables to Cards",{"path":1859,"title":1860},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fcontainer-query-sidebar-layouts","Container Query Sidebar Layouts That Travel Between Contexts",{"path":1862,"title":1863},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns","Responsive Component Patterns: Architecture & Implementation",{"path":1865,"title":1866},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-forms-with-container-queries","Responsive Forms with Container Queries: Reflow Without Losing the Wiring",{"path":1868,"title":1869},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-navigation-without-media-queries","Responsive Navigation Without Media Queries Using Container Queries",{"path":1615,"title":5},{"path":1872,"title":1873},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state","Style Queries and Container State: Token-Driven Component Variants",{"path":1875,"title":1876},"\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":1878,"title":1879},"\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]