[{"data":1,"prerenderedAt":2327},["ShallowReactive",2],{"page-\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fchoosing-animation-durations\u002F":3,"content-all-pages":1762,"live-demo:easing-duration-tokens":2321},{"id":4,"title":5,"body":6,"description":1744,"extension":1745,"meta":1746,"navigation":459,"path":1758,"seo":1759,"stem":1760,"__hash__":1761},"content\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fchoosing-animation-durations\u002Findex.md","Choosing Animation Durations: How Long Motion Should Last",{"type":7,"value":8,"toc":1733},"minimark",[9,13,41,46,49,52,56,198,201,224,228,231,235,1317,1333,1337,1340,1396,1560,1585,1589,1592,1595,1599,1625,1628,1631,1635,1662,1666,1672,1678,1684,1690,1694,1730],[10,11,5],"h1",{"id":12},"choosing-animation-durations-how-long-motion-should-last",[14,15,16,17,21,22,25,26,29,30,35,36,40],"p",{},"Easing curves get most of the attention in motion design, but duration does as much to shape how an interface feels. The same curve at 120 milliseconds reads as crisp; at 600 milliseconds, as sluggish; at 60, as a flicker. Most codebases end up with durations chosen one at a time — ",[18,19,20],"code",{},".3s"," here, ",[18,23,24],{},"250ms"," there, ",[18,27,28],{},"0.4s"," on the modal because it \"felt right\" — and the result is an interface with no consistent rhythm. This page gives a principled way to choose durations from what the animation does, turns the choices into tokens, and shows how to scale durations with component size and remove them for reduced motion. It belongs to ",[31,32,34],"a",{"href":33},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002F","Easing & Motion Design"," in the ",[31,37,39],{"href":38},"\u002Fcss-only-micro-interactions-animations\u002F","CSS-Only Micro-Interactions & Animations"," guide.",[42,43,45],"h2",{"id":44},"why-duration-is-a-design-decision","Why duration is a design decision",[14,47,48],{},"Human perception sets the outer bounds. Changes faster than roughly 100 milliseconds are perceived as instantaneous — useful when you want feedback without the sense of motion. Motion slower than roughly half a second begins to feel like waiting, and users of productivity software notice it quickly because they trigger the same transitions hundreds of times a day. Between those limits is where UI motion lives, and within that range the right value depends on what is moving and how far.",[14,50,51],{},"Duration also carries meaning. Fast motion reads as lightweight and responsive; slower motion reads as significant. A toast that slides in over 350 milliseconds says \"this is worth noticing\"; a dropdown that opens over 350 milliseconds says \"you have to wait for this\". Matching duration to importance is how motion stays informative instead of decorative.",[42,53,55],{"id":54},"duration-by-kind-of-change","Duration by kind of change",[57,58,64,65,64,69,64,73,64,81,64,90,64,95,64,99,64,103,64,107,64,111,64,115,64,118,64,127,64,133,64,138,64,141,64,145,64,148,64,152,64,156,64,160,64,163,64,166,64,171,64,175,64,178,64,181,64,186,64,190,64,193],"svg",{"viewBox":59,"role":60,"ariaLabel":61,"xmlns":62,"style":63},"0 0 720 320","img","Horizontal timeline from 0 to 600 milliseconds with bands for instant feedback, small state changes, component movement, and large transitions","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;height:auto;max-width:720px;margin:2rem 0","\n  ",[66,67,68],"title",{},"Where common UI changes sit on the duration scale",[70,71,72],"desc",{},"Under 100 milliseconds reads as instant. 100 to 200 suits hover, focus and toggles. 200 to 350 suits menus, tooltips and cards moving. 350 to 500 suits dialogs, drawers and page-level transitions. Beyond 500 feels slow for routine UI.",[74,75,80],"text",{"textAnchor":76,"x":77,"y":78,"style":79},"middle","360","26","text-anchor:middle;fill:currentColor;font:700 17px sans-serif","Match the duration to the size of the change",[82,83],"line",{"x1":84,"y1":85,"x2":86,"y2":85,"stroke":87,"strokeWidth":88,"opacity":89},"50","220","680","currentColor","1.5","0.6",[74,91,94],{"textAnchor":76,"x":84,"y":92,"style":93},"244","text-anchor:middle;fill:currentColor;font:11px ui-monospace,monospace","0",[74,96,98],{"textAnchor":76,"x":97,"y":92,"style":93},"155","100",[74,100,102],{"textAnchor":76,"x":101,"y":92,"style":93},"260","200",[74,104,106],{"textAnchor":76,"x":105,"y":92,"style":93},"365","300",[74,108,110],{"textAnchor":76,"x":109,"y":92,"style":93},"470","400",[74,112,114],{"textAnchor":76,"x":113,"y":92,"style":93},"575","500",[74,116,117],{"textAnchor":76,"x":86,"y":92,"style":93},"600ms",[119,120],"rect",{"x":84,"y":121,"width":122,"height":123,"rx":124,"fill":125,"opacity":126},"60","105","140","6","#7aa2ff","0.1",[74,128,132],{"textAnchor":76,"x":129,"y":130,"style":131},"102","86","text-anchor:middle;fill:currentColor;font:600 12px sans-serif","instant",[74,134,137],{"textAnchor":76,"x":129,"y":135,"style":136},"108","text-anchor:middle;fill:currentColor;font:11px sans-serif","press states",[119,139],{"x":97,"y":121,"width":122,"height":123,"rx":124,"fill":125,"opacity":140},"0.22",[74,142,144],{"textAnchor":76,"x":143,"y":130,"style":131},"207","small",[74,146,147],{"textAnchor":76,"x":143,"y":135,"style":136},"hover, focus",[74,149,151],{"textAnchor":76,"x":143,"y":150,"style":136},"126","toggles",[119,153],{"x":101,"y":121,"width":154,"height":123,"rx":124,"fill":125,"opacity":155},"158","0.34",[74,157,159],{"textAnchor":76,"x":158,"y":130,"style":131},"339","component",[74,161,162],{"textAnchor":76,"x":158,"y":135,"style":136},"menus, tooltips",[74,164,165],{"textAnchor":76,"x":158,"y":150,"style":136},"accordions",[119,167],{"x":168,"y":121,"width":169,"height":123,"rx":124,"fill":125,"opacity":170},"418","157","0.46",[74,172,174],{"textAnchor":76,"x":173,"y":130,"style":131},"496","large",[74,176,177],{"textAnchor":76,"x":173,"y":135,"style":136},"dialogs, drawers",[74,179,180],{"textAnchor":76,"x":173,"y":150,"style":136},"page transitions",[119,182],{"x":113,"y":121,"width":122,"height":123,"rx":124,"fill":183,"stroke":87,"strokeDashArray":184,"opacity":89},"none",[185,185],"4",[74,187,189],{"textAnchor":76,"x":188,"y":130,"style":131},"627","slow",[74,191,192],{"textAnchor":76,"x":188,"y":135,"style":136},"rare, special",[74,194,197],{"textAnchor":76,"x":77,"y":195,"style":196},"290","text-anchor:middle;fill:currentColor;font:12px sans-serif;opacity:0.8","Ranges are starting points; tune by eye at real size and speed.",[14,199,200],{},"Three factors push a duration up or down within its band:",[202,203,204,212,218],"ol",{},[205,206,207,211],"li",{},[208,209,210],"strong",{},"Distance travelled."," An element moving 8 pixels needs less time than one moving 400. Duration should grow with distance, but sub-linearly — a doubled distance needs perhaps a third more time, not twice as much, or long movements drag.",[205,213,214,217],{},[208,215,216],{},"Area changing."," A large surface fading or scaling draws more attention than a small one and benefits from a slightly longer duration so the change is not jarring.",[205,219,220,223],{},[208,221,222],{},"Frequency of use."," The more often a transition runs, the shorter it should be. A hover state seen hundreds of times deserves the low end of its band; a celebratory confirmation seen once deserves the high end.",[42,225,227],{"id":226},"the-complete-implementation-duration-tokens","The complete implementation: duration tokens",[14,229,230],{},"Durations belong in tokens for the same reason colours do: consistency and a single place to adjust. The system below defines a small scale, maps component types onto it, and handles reduced motion at the token level.",[232,233],"live-demo",{"name":234},"easing-duration-tokens",[236,237,242],"pre",{"className":238,"code":239,"language":240,"meta":241,"style":241},"language-html shiki shiki-themes github-light-high-contrast github-dark-high-contrast","\u003C!doctype html>\n\u003Chtml lang=\"en\">\n\u003Chead>\n\u003Cmeta charset=\"utf-8\">\n\u003Cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\u003Ctitle>Duration tokens\u003C\u002Ftitle>\n\u003Cstyle>\n  :root {\n    \u002F* The scale: a handful of steps, roughly 1.5x apart. *\u002F\n    --duration-instant: 70ms;\n    --duration-fast: 140ms;\n    --duration-base: 220ms;\n    --duration-moderate: 320ms;\n    --duration-slow: 450ms;\n\n    \u002F* Semantic tokens: what components actually reference. *\u002F\n    --motion-press: var(--duration-instant);\n    --motion-hover: var(--duration-fast);\n    --motion-reveal: var(--duration-base);\n    --motion-panel: var(--duration-moderate);\n    --motion-page: var(--duration-slow);\n  }\n\n  \u002F* One place turns movement off for users who asked for less. Colour and\n     opacity changes keep a short duration because they carry state. *\u002F\n  @media (prefers-reduced-motion: reduce) {\n    :root {\n      --motion-reveal: 1ms;\n      --motion-panel: 1ms;\n      --motion-page: 1ms;\n    }\n  }\n\n  body { font: 15px\u002F1.5 system-ui, sans-serif; margin: 1.5rem; display: grid; gap: 1rem; }\n\n  .button {\n    justify-self: start;\n    padding: 0.5rem 1rem;\n    border: 0;\n    border-radius: 8px;\n    background: #4f46e5;\n    color: #ffffff;\n    font: inherit;\n    transition:\n      background-color var(--motion-hover) ease,\n      scale var(--motion-press) ease;\n  }\n  .button:hover { background-color: #4338ca; }\n  .button:active { scale: 0.97; }\n  .button:focus-visible { outline: 2px solid #1e1b4b; outline-offset: 2px; }\n\n  .panel {\n    padding: 1rem;\n    border-radius: 12px;\n    background: #eef2ff;\n    translate: 0 0.5rem;\n    opacity: 0;\n    transition:\n      translate var(--motion-panel) cubic-bezier(0.22, 1, 0.36, 1),\n      opacity var(--motion-panel) ease;\n  }\n  .toggle:checked ~ .panel { translate: 0 0; opacity: 1; }\n\u003C\u002Fstyle>\n\u003C\u002Fhead>\n\u003Cbody>\n  \u003Cbutton class=\"button\" type=\"button\">Save\u003C\u002Fbutton>\n  \u003Cinput class=\"toggle\" type=\"checkbox\" id=\"show\" aria-controls=\"p\">\n  \u003Clabel for=\"show\">Show details\u003C\u002Flabel>\n  \u003Cdiv class=\"panel\" id=\"p\">Details slide up over the panel duration.\u003C\u002Fdiv>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>\n","html","",[18,243,244,263,283,293,311,336,350,360,369,376,396,410,424,439,454,461,467,487,504,521,538,555,561,566,572,578,587,595,610,624,638,644,649,654,725,730,738,751,771,783,798,811,824,837,846,868,887,892,910,928,965,970,978,991,1005,1017,1034,1046,1053,1091,1109,1114,1149,1159,1168,1178,1209,1249,1271,1299,1308],{"__ignoreMap":241},[245,246,248,252,256,260],"span",{"class":82,"line":247},1,[245,249,251],{"class":250},"suds8","\u003C!",[245,253,255],{"class":254},"sne4z","doctype",[245,257,259],{"class":258},"s-5SL"," html",[245,261,262],{"class":250},">\n",[245,264,266,269,271,274,277,281],{"class":82,"line":265},2,[245,267,268],{"class":250},"\u003C",[245,270,240],{"class":254},[245,272,273],{"class":258}," lang",[245,275,276],{"class":250},"=",[245,278,280],{"class":279},"sT6z2","\"en\"",[245,282,262],{"class":250},[245,284,286,288,291],{"class":82,"line":285},3,[245,287,268],{"class":250},[245,289,290],{"class":254},"head",[245,292,262],{"class":250},[245,294,296,298,301,304,306,309],{"class":82,"line":295},4,[245,297,268],{"class":250},[245,299,300],{"class":254},"meta",[245,302,303],{"class":258}," charset",[245,305,276],{"class":250},[245,307,308],{"class":279},"\"utf-8\"",[245,310,262],{"class":250},[245,312,314,316,318,321,323,326,329,331,334],{"class":82,"line":313},5,[245,315,268],{"class":250},[245,317,300],{"class":254},[245,319,320],{"class":258}," name",[245,322,276],{"class":250},[245,324,325],{"class":279},"\"viewport\"",[245,327,328],{"class":258}," content",[245,330,276],{"class":250},[245,332,333],{"class":279},"\"width=device-width, initial-scale=1\"",[245,335,262],{"class":250},[245,337,339,341,343,346,348],{"class":82,"line":338},6,[245,340,268],{"class":250},[245,342,66],{"class":254},[245,344,345],{"class":250},">Duration tokens\u003C\u002F",[245,347,66],{"class":254},[245,349,262],{"class":250},[245,351,353,355,358],{"class":82,"line":352},7,[245,354,268],{"class":250},[245,356,357],{"class":254},"style",[245,359,262],{"class":250},[245,361,363,366],{"class":82,"line":362},8,[245,364,365],{"class":258},"  :root",[245,367,368],{"class":250}," {\n",[245,370,372],{"class":82,"line":371},9,[245,373,375],{"class":374},"sLBg1","    \u002F* The scale: a handful of steps, roughly 1.5x apart. *\u002F\n",[245,377,379,383,386,389,393],{"class":82,"line":378},10,[245,380,382],{"class":381},"soyes","    --duration-instant",[245,384,385],{"class":250},": ",[245,387,388],{"class":258},"70",[245,390,392],{"class":391},"sHUrx","ms",[245,394,395],{"class":250},";\n",[245,397,399,402,404,406,408],{"class":82,"line":398},11,[245,400,401],{"class":381},"    --duration-fast",[245,403,385],{"class":250},[245,405,123],{"class":258},[245,407,392],{"class":391},[245,409,395],{"class":250},[245,411,413,416,418,420,422],{"class":82,"line":412},12,[245,414,415],{"class":381},"    --duration-base",[245,417,385],{"class":250},[245,419,85],{"class":258},[245,421,392],{"class":391},[245,423,395],{"class":250},[245,425,427,430,432,435,437],{"class":82,"line":426},13,[245,428,429],{"class":381},"    --duration-moderate",[245,431,385],{"class":250},[245,433,434],{"class":258},"320",[245,436,392],{"class":391},[245,438,395],{"class":250},[245,440,442,445,447,450,452],{"class":82,"line":441},14,[245,443,444],{"class":381},"    --duration-slow",[245,446,385],{"class":250},[245,448,449],{"class":258},"450",[245,451,392],{"class":391},[245,453,395],{"class":250},[245,455,457],{"class":82,"line":456},15,[245,458,460],{"emptyLinePlaceholder":459},true,"\n",[245,462,464],{"class":82,"line":463},16,[245,465,466],{"class":374},"    \u002F* Semantic tokens: what components actually reference. *\u002F\n",[245,468,470,473,475,478,481,484],{"class":82,"line":469},17,[245,471,472],{"class":381},"    --motion-press",[245,474,385],{"class":250},[245,476,477],{"class":258},"var",[245,479,480],{"class":250},"(",[245,482,483],{"class":381},"--duration-instant",[245,485,486],{"class":250},");\n",[245,488,490,493,495,497,499,502],{"class":82,"line":489},18,[245,491,492],{"class":381},"    --motion-hover",[245,494,385],{"class":250},[245,496,477],{"class":258},[245,498,480],{"class":250},[245,500,501],{"class":381},"--duration-fast",[245,503,486],{"class":250},[245,505,507,510,512,514,516,519],{"class":82,"line":506},19,[245,508,509],{"class":381},"    --motion-reveal",[245,511,385],{"class":250},[245,513,477],{"class":258},[245,515,480],{"class":250},[245,517,518],{"class":381},"--duration-base",[245,520,486],{"class":250},[245,522,524,527,529,531,533,536],{"class":82,"line":523},20,[245,525,526],{"class":381},"    --motion-panel",[245,528,385],{"class":250},[245,530,477],{"class":258},[245,532,480],{"class":250},[245,534,535],{"class":381},"--duration-moderate",[245,537,486],{"class":250},[245,539,541,544,546,548,550,553],{"class":82,"line":540},21,[245,542,543],{"class":381},"    --motion-page",[245,545,385],{"class":250},[245,547,477],{"class":258},[245,549,480],{"class":250},[245,551,552],{"class":381},"--duration-slow",[245,554,486],{"class":250},[245,556,558],{"class":82,"line":557},22,[245,559,560],{"class":250},"  }\n",[245,562,564],{"class":82,"line":563},23,[245,565,460],{"emptyLinePlaceholder":459},[245,567,569],{"class":82,"line":568},24,[245,570,571],{"class":374},"  \u002F* One place turns movement off for users who asked for less. Colour and\n",[245,573,575],{"class":82,"line":574},25,[245,576,577],{"class":374},"     opacity changes keep a short duration because they carry state. *\u002F\n",[245,579,581,584],{"class":82,"line":580},26,[245,582,583],{"class":391},"  @media",[245,585,586],{"class":250}," (prefers-reduced-motion: reduce) {\n",[245,588,590,593],{"class":82,"line":589},27,[245,591,592],{"class":258},"    :root",[245,594,368],{"class":250},[245,596,598,601,603,606,608],{"class":82,"line":597},28,[245,599,600],{"class":381},"      --motion-reveal",[245,602,385],{"class":250},[245,604,605],{"class":258},"1",[245,607,392],{"class":391},[245,609,395],{"class":250},[245,611,613,616,618,620,622],{"class":82,"line":612},29,[245,614,615],{"class":381},"      --motion-panel",[245,617,385],{"class":250},[245,619,605],{"class":258},[245,621,392],{"class":391},[245,623,395],{"class":250},[245,625,627,630,632,634,636],{"class":82,"line":626},30,[245,628,629],{"class":381},"      --motion-page",[245,631,385],{"class":250},[245,633,605],{"class":258},[245,635,392],{"class":391},[245,637,395],{"class":250},[245,639,641],{"class":82,"line":640},31,[245,642,643],{"class":250},"    }\n",[245,645,647],{"class":82,"line":646},32,[245,648,560],{"class":250},[245,650,652],{"class":82,"line":651},33,[245,653,460],{"emptyLinePlaceholder":459},[245,655,657,660,663,666,668,671,674,677,679,682,685,688,691,694,696,698,701,703,706,708,711,713,716,718,720,722],{"class":82,"line":656},34,[245,658,659],{"class":254},"  body",[245,661,662],{"class":250}," { ",[245,664,665],{"class":258},"font",[245,667,385],{"class":250},[245,669,670],{"class":258},"15",[245,672,673],{"class":391},"px",[245,675,676],{"class":250},"\u002F",[245,678,88],{"class":258},[245,680,681],{"class":258}," system-ui",[245,683,684],{"class":250},", ",[245,686,687],{"class":258},"sans-serif",[245,689,690],{"class":250},"; ",[245,692,693],{"class":258},"margin",[245,695,385],{"class":250},[245,697,88],{"class":258},[245,699,700],{"class":391},"rem",[245,702,690],{"class":250},[245,704,705],{"class":258},"display",[245,707,385],{"class":250},[245,709,710],{"class":258},"grid",[245,712,690],{"class":250},[245,714,715],{"class":258},"gap",[245,717,385],{"class":250},[245,719,605],{"class":258},[245,721,700],{"class":391},[245,723,724],{"class":250},"; }\n",[245,726,728],{"class":82,"line":727},35,[245,729,460],{"emptyLinePlaceholder":459},[245,731,733,736],{"class":82,"line":732},36,[245,734,735],{"class":258},"  .button",[245,737,368],{"class":250},[245,739,741,744,746,749],{"class":82,"line":740},37,[245,742,743],{"class":258},"    justify-self",[245,745,385],{"class":250},[245,747,748],{"class":258},"start",[245,750,395],{"class":250},[245,752,754,757,759,762,764,767,769],{"class":82,"line":753},38,[245,755,756],{"class":258},"    padding",[245,758,385],{"class":250},[245,760,761],{"class":258},"0.5",[245,763,700],{"class":391},[245,765,766],{"class":258}," 1",[245,768,700],{"class":391},[245,770,395],{"class":250},[245,772,774,777,779,781],{"class":82,"line":773},39,[245,775,776],{"class":258},"    border",[245,778,385],{"class":250},[245,780,94],{"class":258},[245,782,395],{"class":250},[245,784,786,789,791,794,796],{"class":82,"line":785},40,[245,787,788],{"class":258},"    border-radius",[245,790,385],{"class":250},[245,792,793],{"class":258},"8",[245,795,673],{"class":391},[245,797,395],{"class":250},[245,799,801,804,806,809],{"class":82,"line":800},41,[245,802,803],{"class":258},"    background",[245,805,385],{"class":250},[245,807,808],{"class":258},"#4f46e5",[245,810,395],{"class":250},[245,812,814,817,819,822],{"class":82,"line":813},42,[245,815,816],{"class":258},"    color",[245,818,385],{"class":250},[245,820,821],{"class":258},"#ffffff",[245,823,395],{"class":250},[245,825,827,830,832,835],{"class":82,"line":826},43,[245,828,829],{"class":258},"    font",[245,831,385],{"class":250},[245,833,834],{"class":258},"inherit",[245,836,395],{"class":250},[245,838,840,843],{"class":82,"line":839},44,[245,841,842],{"class":258},"    transition",[245,844,845],{"class":250},":\n",[245,847,849,852,854,856,859,862,865],{"class":82,"line":848},45,[245,850,851],{"class":250},"      background-color ",[245,853,477],{"class":258},[245,855,480],{"class":250},[245,857,858],{"class":381},"--motion-hover",[245,860,861],{"class":250},") ",[245,863,864],{"class":258},"ease",[245,866,867],{"class":250},",\n",[245,869,871,874,876,878,881,883,885],{"class":82,"line":870},46,[245,872,873],{"class":250},"      scale ",[245,875,477],{"class":258},[245,877,480],{"class":250},[245,879,880],{"class":381},"--motion-press",[245,882,861],{"class":250},[245,884,864],{"class":258},[245,886,395],{"class":250},[245,888,890],{"class":82,"line":889},47,[245,891,560],{"class":250},[245,893,895,898,900,903,905,908],{"class":82,"line":894},48,[245,896,897],{"class":258},"  .button:hover",[245,899,662],{"class":250},[245,901,902],{"class":258},"background-color",[245,904,385],{"class":250},[245,906,907],{"class":258},"#4338ca",[245,909,724],{"class":250},[245,911,913,916,918,921,923,926],{"class":82,"line":912},49,[245,914,915],{"class":258},"  .button:active",[245,917,662],{"class":250},[245,919,920],{"class":258},"scale",[245,922,385],{"class":250},[245,924,925],{"class":258},"0.97",[245,927,724],{"class":250},[245,929,931,934,936,939,941,944,946,949,952,954,957,959,961,963],{"class":82,"line":930},50,[245,932,933],{"class":258},"  .button:focus-visible",[245,935,662],{"class":250},[245,937,938],{"class":258},"outline",[245,940,385],{"class":250},[245,942,943],{"class":258},"2",[245,945,673],{"class":391},[245,947,948],{"class":258}," solid",[245,950,951],{"class":258}," #1e1b4b",[245,953,690],{"class":250},[245,955,956],{"class":258},"outline-offset",[245,958,385],{"class":250},[245,960,943],{"class":258},[245,962,673],{"class":391},[245,964,724],{"class":250},[245,966,968],{"class":82,"line":967},51,[245,969,460],{"emptyLinePlaceholder":459},[245,971,973,976],{"class":82,"line":972},52,[245,974,975],{"class":258},"  .panel",[245,977,368],{"class":250},[245,979,981,983,985,987,989],{"class":82,"line":980},53,[245,982,756],{"class":258},[245,984,385],{"class":250},[245,986,605],{"class":258},[245,988,700],{"class":391},[245,990,395],{"class":250},[245,992,994,996,998,1001,1003],{"class":82,"line":993},54,[245,995,788],{"class":258},[245,997,385],{"class":250},[245,999,1000],{"class":258},"12",[245,1002,673],{"class":391},[245,1004,395],{"class":250},[245,1006,1008,1010,1012,1015],{"class":82,"line":1007},55,[245,1009,803],{"class":258},[245,1011,385],{"class":250},[245,1013,1014],{"class":258},"#eef2ff",[245,1016,395],{"class":250},[245,1018,1020,1023,1025,1027,1030,1032],{"class":82,"line":1019},56,[245,1021,1022],{"class":258},"    translate",[245,1024,385],{"class":250},[245,1026,94],{"class":258},[245,1028,1029],{"class":258}," 0.5",[245,1031,700],{"class":391},[245,1033,395],{"class":250},[245,1035,1037,1040,1042,1044],{"class":82,"line":1036},57,[245,1038,1039],{"class":258},"    opacity",[245,1041,385],{"class":250},[245,1043,94],{"class":258},[245,1045,395],{"class":250},[245,1047,1049,1051],{"class":82,"line":1048},58,[245,1050,842],{"class":258},[245,1052,845],{"class":250},[245,1054,1056,1059,1061,1063,1066,1068,1071,1073,1075,1077,1079,1081,1084,1086,1088],{"class":82,"line":1055},59,[245,1057,1058],{"class":250},"      translate ",[245,1060,477],{"class":258},[245,1062,480],{"class":250},[245,1064,1065],{"class":381},"--motion-panel",[245,1067,861],{"class":250},[245,1069,1070],{"class":258},"cubic-bezier",[245,1072,480],{"class":250},[245,1074,140],{"class":258},[245,1076,684],{"class":250},[245,1078,605],{"class":258},[245,1080,684],{"class":250},[245,1082,1083],{"class":258},"0.36",[245,1085,684],{"class":250},[245,1087,605],{"class":258},[245,1089,1090],{"class":250},"),\n",[245,1092,1094,1097,1099,1101,1103,1105,1107],{"class":82,"line":1093},60,[245,1095,1096],{"class":250},"      opacity ",[245,1098,477],{"class":258},[245,1100,480],{"class":250},[245,1102,1065],{"class":381},[245,1104,861],{"class":250},[245,1106,864],{"class":258},[245,1108,395],{"class":250},[245,1110,1112],{"class":82,"line":1111},61,[245,1113,560],{"class":250},[245,1115,1117,1120,1123,1126,1128,1131,1133,1135,1138,1140,1143,1145,1147],{"class":82,"line":1116},62,[245,1118,1119],{"class":258},"  .toggle:checked",[245,1121,1122],{"class":391}," ~",[245,1124,1125],{"class":258}," .panel",[245,1127,662],{"class":250},[245,1129,1130],{"class":258},"translate",[245,1132,385],{"class":250},[245,1134,94],{"class":258},[245,1136,1137],{"class":258}," 0",[245,1139,690],{"class":250},[245,1141,1142],{"class":258},"opacity",[245,1144,385],{"class":250},[245,1146,605],{"class":258},[245,1148,724],{"class":250},[245,1150,1152,1155,1157],{"class":82,"line":1151},63,[245,1153,1154],{"class":250},"\u003C\u002F",[245,1156,357],{"class":254},[245,1158,262],{"class":250},[245,1160,1162,1164,1166],{"class":82,"line":1161},64,[245,1163,1154],{"class":250},[245,1165,290],{"class":254},[245,1167,262],{"class":250},[245,1169,1171,1173,1176],{"class":82,"line":1170},65,[245,1172,268],{"class":250},[245,1174,1175],{"class":254},"body",[245,1177,262],{"class":250},[245,1179,1181,1184,1187,1190,1192,1195,1198,1200,1202,1205,1207],{"class":82,"line":1180},66,[245,1182,1183],{"class":250},"  \u003C",[245,1185,1186],{"class":254},"button",[245,1188,1189],{"class":258}," class",[245,1191,276],{"class":250},[245,1193,1194],{"class":279},"\"button\"",[245,1196,1197],{"class":258}," type",[245,1199,276],{"class":250},[245,1201,1194],{"class":279},[245,1203,1204],{"class":250},">Save\u003C\u002F",[245,1206,1186],{"class":254},[245,1208,262],{"class":250},[245,1210,1212,1214,1217,1219,1221,1224,1226,1228,1231,1234,1236,1239,1242,1244,1247],{"class":82,"line":1211},67,[245,1213,1183],{"class":250},[245,1215,1216],{"class":254},"input",[245,1218,1189],{"class":258},[245,1220,276],{"class":250},[245,1222,1223],{"class":279},"\"toggle\"",[245,1225,1197],{"class":258},[245,1227,276],{"class":250},[245,1229,1230],{"class":279},"\"checkbox\"",[245,1232,1233],{"class":258}," id",[245,1235,276],{"class":250},[245,1237,1238],{"class":279},"\"show\"",[245,1240,1241],{"class":258}," aria-controls",[245,1243,276],{"class":250},[245,1245,1246],{"class":279},"\"p\"",[245,1248,262],{"class":250},[245,1250,1252,1254,1257,1260,1262,1264,1267,1269],{"class":82,"line":1251},68,[245,1253,1183],{"class":250},[245,1255,1256],{"class":254},"label",[245,1258,1259],{"class":258}," for",[245,1261,276],{"class":250},[245,1263,1238],{"class":279},[245,1265,1266],{"class":250},">Show details\u003C\u002F",[245,1268,1256],{"class":254},[245,1270,262],{"class":250},[245,1272,1274,1276,1279,1281,1283,1286,1288,1290,1292,1295,1297],{"class":82,"line":1273},69,[245,1275,1183],{"class":250},[245,1277,1278],{"class":254},"div",[245,1280,1189],{"class":258},[245,1282,276],{"class":250},[245,1284,1285],{"class":279},"\"panel\"",[245,1287,1233],{"class":258},[245,1289,276],{"class":250},[245,1291,1246],{"class":279},[245,1293,1294],{"class":250},">Details slide up over the panel duration.\u003C\u002F",[245,1296,1278],{"class":254},[245,1298,262],{"class":250},[245,1300,1302,1304,1306],{"class":82,"line":1301},70,[245,1303,1154],{"class":250},[245,1305,1175],{"class":254},[245,1307,262],{"class":250},[245,1309,1311,1313,1315],{"class":82,"line":1310},71,[245,1312,1154],{"class":250},[245,1314,240],{"class":254},[245,1316,262],{"class":250},[14,1318,1319,1320,1322,1323,684,1325,1327,1328,1332],{},"Two layers of tokens are deliberate. The raw scale (",[18,1321,501],{}," and so on) gives designers a small vocabulary to choose from. The semantic tokens (",[18,1324,858],{},[18,1326,1065],{},") are what components use, so changing \"how fast do panels open across the product\" is one edit, and the reduced-motion override can target ",[1329,1330,1331],"em",{},"movement"," categories while leaving colour-change durations alone.",[42,1334,1336],{"id":1335},"the-key-technique-scaling-duration-with-distance","The key technique: scaling duration with distance",[14,1338,1339],{},"When the same component appears at very different sizes, a single duration is wrong at one extreme or the other. A drawer that slides 280 pixels on a phone and 640 pixels on a desktop moves more than twice as fast on desktop if the duration is fixed, which feels abrupt. Container query units make it possible to scale duration with the component's size, bounded on both ends.",[57,1341,64,1344,64,1347,64,1350,64,1353,64,1358,64,1360,64,1366,64,1370,64,1374,64,1379,64,1381,64,1387,64,1391],{"viewBox":1342,"role":60,"ariaLabel":1343,"xmlns":62,"style":63},"0 0 720 280","Graph of duration against travel distance: a fixed duration line, a proportional line that grows too slow, and a clamped sub-linear curve between them",[66,1345,1346],{},"Duration versus distance",[70,1348,1349],{},"A flat line shows a fixed duration that is too fast for long travel. A steep straight line shows proportional scaling that becomes too slow. A curve that rises quickly then flattens, clamped between a minimum and maximum, shows the recommended scaling.",[74,1351,1352],{"textAnchor":76,"x":77,"y":78,"style":79},"Grow duration with distance, then cap it",[82,1354],{"x1":1355,"y1":1356,"x2":1357,"y2":1356,"stroke":87,"strokeWidth":88,"opacity":89},"80","230","660",[82,1359],{"x1":1355,"y1":84,"x2":1355,"y2":1356,"stroke":87,"strokeWidth":88,"opacity":89},[74,1361,1365],{"textAnchor":1362,"x":1357,"y":1363,"style":1364},"end","254","text-anchor:end;fill:currentColor;font:12px sans-serif","travel distance",[74,1367,1369],{"textAnchor":1362,"x":1368,"y":121,"style":1364},"72","time",[82,1371],{"x1":1355,"y1":1372,"x2":1357,"y2":1372,"stroke":87,"strokeWidth":943,"strokeDashArray":1373,"opacity":89},"170",[124,185],[74,1375,1378],{"textAnchor":1362,"x":1376,"y":1377,"style":1364},"650","162","fixed: too fast when far",[82,1380],{"x1":1355,"y1":85,"x2":110,"y2":84,"stroke":87,"strokeWidth":943,"opacity":761},[74,1382,1386],{"textAnchor":748,"x":1383,"y":1384,"style":1385},"410","56","text-anchor:start;fill:currentColor;font:12px sans-serif","proportional: too slow",[1388,1389],"path",{"d":1390,"fill":183,"stroke":125,"strokeWidth":185},"M80 200 C200 130 320 110 480 100 L660 100",[74,1392,1395],{"textAnchor":76,"x":1393,"y":1394,"style":131},"560","92","clamped, sub-linear",[236,1397,1401],{"className":1398,"code":1399,"language":1400,"meta":241,"style":241},"language-css shiki shiki-themes github-light-high-contrast github-dark-high-contrast",".drawer-host { container-type: inline-size; }\n\n.drawer {\n  \u002F* tan(atan2()) turns a length ratio into a plain number. Here the\n     container width in units of 400px: 0.7 on a 280px phone, 1.6 on a\n     640px panel. The duration grows with it, clamped to a sane range. *\u002F\n  --room: tan(atan2(100cqi, 400px));\n  transition: translate clamp(220ms, calc(180ms + 90ms * var(--room)), 380ms)\n              cubic-bezier(0.22, 1, 0.36, 1);\n}\n","css",[18,1402,1403,1416,1420,1427,1432,1437,1442,1473,1532,1555],{"__ignoreMap":241},[245,1404,1405,1408,1410,1413],{"class":82,"line":247},[245,1406,1407],{"class":258},".drawer-host",[245,1409,662],{"class":250},[245,1411,1412],{"class":258},"container-type",[245,1414,1415],{"class":250},": inline-size; }\n",[245,1417,1418],{"class":82,"line":265},[245,1419,460],{"emptyLinePlaceholder":459},[245,1421,1422,1425],{"class":82,"line":285},[245,1423,1424],{"class":258},".drawer",[245,1426,368],{"class":250},[245,1428,1429],{"class":82,"line":295},[245,1430,1431],{"class":374},"  \u002F* tan(atan2()) turns a length ratio into a plain number. Here the\n",[245,1433,1434],{"class":82,"line":313},[245,1435,1436],{"class":374},"     container width in units of 400px: 0.7 on a 280px phone, 1.6 on a\n",[245,1438,1439],{"class":82,"line":338},[245,1440,1441],{"class":374},"     640px panel. The duration grows with it, clamped to a sane range. *\u002F\n",[245,1443,1444,1447,1449,1452,1454,1457,1459,1461,1464,1466,1468,1470],{"class":82,"line":352},[245,1445,1446],{"class":381},"  --room",[245,1448,385],{"class":250},[245,1450,1451],{"class":258},"tan",[245,1453,480],{"class":250},[245,1455,1456],{"class":258},"atan2",[245,1458,480],{"class":250},[245,1460,98],{"class":258},[245,1462,1463],{"class":391},"cqi",[245,1465,684],{"class":250},[245,1467,110],{"class":258},[245,1469,673],{"class":391},[245,1471,1472],{"class":250},"));\n",[245,1474,1475,1478,1481,1484,1486,1488,1490,1492,1495,1497,1500,1502,1505,1508,1510,1513,1516,1518,1521,1524,1527,1529],{"class":82,"line":362},[245,1476,1477],{"class":258},"  transition",[245,1479,1480],{"class":250},": translate ",[245,1482,1483],{"class":258},"clamp",[245,1485,480],{"class":250},[245,1487,85],{"class":258},[245,1489,392],{"class":391},[245,1491,684],{"class":250},[245,1493,1494],{"class":258},"calc",[245,1496,480],{"class":250},[245,1498,1499],{"class":258},"180",[245,1501,392],{"class":391},[245,1503,1504],{"class":391}," +",[245,1506,1507],{"class":258}," 90",[245,1509,392],{"class":391},[245,1511,1512],{"class":391}," *",[245,1514,1515],{"class":258}," var",[245,1517,480],{"class":250},[245,1519,1520],{"class":381},"--room",[245,1522,1523],{"class":250},")), ",[245,1525,1526],{"class":258},"380",[245,1528,392],{"class":391},[245,1530,1531],{"class":250},")\n",[245,1533,1534,1537,1539,1541,1543,1545,1547,1549,1551,1553],{"class":82,"line":371},[245,1535,1536],{"class":258},"              cubic-bezier",[245,1538,480],{"class":250},[245,1540,140],{"class":258},[245,1542,684],{"class":250},[245,1544,605],{"class":258},[245,1546,684],{"class":250},[245,1548,1083],{"class":258},[245,1550,684],{"class":250},[245,1552,605],{"class":258},[245,1554,486],{"class":250},[245,1556,1557],{"class":82,"line":378},[245,1558,1559],{"class":250},"}\n",[14,1561,1562,1563,1566,1567,1570,1571,1574,1575,1579,1580,1584],{},"The linear formula inside ",[18,1564,1565],{},"clamp()"," gives the \"rises, then flattens\" behaviour in practice: the constant term dominates for small containers, and the maximum caps large ones. The ",[18,1568,1569],{},"tan(atan2())"," idiom is the standard way to divide one length by another in CSS, since ",[18,1572,1573],{},"calc()"," cannot divide lengths directly; its derivation and pitfalls are covered in ",[31,1576,1578],{"href":1577},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fmotion-that-scales-with-container-size\u002F","Motion That Scales With Container Size",". For spacing-driven timing, ",[31,1581,1583],{"href":1582},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Ffluid-spacing-tokens-driving-transition-durations\u002F","Fluid Spacing Tokens Driving Transition Durations"," takes the same idea further.",[42,1586,1588],{"id":1587},"duration-for-sequences-and-loops","Duration for sequences and loops",[14,1590,1591],{},"Staggered sequences need their own arithmetic. If eight list items each fade in over 220 milliseconds with a 60-millisecond stagger, the sequence takes 220 + 7 × 60 = 640 milliseconds — already past the \"feels slow\" line. Keep total sequence time under about half a second by shortening the stagger as the count grows, or by staggering only the first few items and revealing the rest together.",[14,1593,1594],{},"Loops are the opposite case: a spinner or pulsing indicator should be slow enough to be calm. A rotation of 0.8 to 1.2 seconds per revolution reads as working; faster spinning reads as anxious. And any loop that runs longer than five seconds needs a way to pause under WCAG 2.2.2, or should stop on its own.",[42,1596,1598],{"id":1597},"auditing-durations-in-an-existing-codebase","Auditing durations in an existing codebase",[14,1600,1601,1602,1605,1606,1609,1610,684,1613,684,1616,684,1619,684,1621,1624],{},"Introducing tokens into a mature stylesheet starts with finding out what is already there. A quick inventory is revealing: search the CSS for ",[18,1603,1604],{},"transition"," and ",[18,1607,1608],{},"animation"," declarations and extract every time value. Most codebases turn up fifteen to thirty distinct durations, many within a few milliseconds of each other — ",[18,1611,1612],{},"0.2s",[18,1614,1615],{},"200ms",[18,1617,1618],{},".25s",[18,1620,24],{},[18,1622,1623],{},"0.3s"," — which is exactly the inconsistency users perceive as an interface lacking rhythm.",[14,1626,1627],{},"Group the values by what they animate rather than by number. Hover and focus colour changes form one group, menu and tooltip reveals another, dialogs and drawers a third. Each group maps onto one semantic token, and outliers either join the nearest group or earn a documented exception. The exercise usually shrinks the palette to five or six durations without anyone noticing a change — except that the interface suddenly feels more coherent.",[14,1629,1630],{},"Two findings deserve special attention. First, any duration above 500 milliseconds on a routine interaction is a candidate for shortening; those are the transitions users describe as \"laggy\" without knowing why. Second, any animated movement with no reduced-motion handling needs it, and routing every duration through tokens makes the fix a single media query rather than dozens of overrides. Browser DevTools help here too: the Animations panel in Chromium and Firefox records every animation and transition on the page with its duration and delay, which is a faster inventory for a live page than reading source.",[42,1632,1634],{"id":1633},"browser-support","Browser support",[14,1636,1637,1638,1605,1640,1643,1644,1605,1646,1648,1649,1652,1653,1655,1656,1658,1659,1661],{},"Durations in ",[18,1639,392],{},[18,1641,1642],{},"s",", custom properties inside ",[18,1645,1604],{},[18,1647,1608],{},", and ",[18,1650,1651],{},"prefers-reduced-motion"," are supported across all current engines; ",[18,1654,1651],{}," dates from Chrome 74, Edge 79, Firefox 63 and Safari 10.1. The container-scaled variant needs container query units (Chrome and Edge 105+, Firefox 110+, Safari 16+) and the trigonometric functions for ",[18,1657,1569],{},", which are supported in current versions of all three engines. Declare a fixed-duration ",[18,1660,1604],{}," first as a fallback.",[42,1663,1665],{"id":1664},"faq","FAQ",[14,1667,1668,1671],{},[208,1669,1670],{},"What is a good default duration for UI transitions?","\nAround 150 to 250 milliseconds for small state changes such as hover, focus and toggles, and 250 to 400 milliseconds for larger movements such as panels and dialogs. Anything under about 100 milliseconds is perceived as instant, and anything over about 500 milliseconds starts to feel slow for routine interactions.",[14,1673,1674,1677],{},[208,1675,1676],{},"Should larger elements animate for longer?","\nGenerally yes. A larger element or a longer travel distance needs more time for the eye to follow, so duration should grow with distance, but less than proportionally. Doubling the distance calls for roughly a 20 to 40 percent longer duration, not double.",[14,1679,1680,1683],{},[208,1681,1682],{},"Should exit animations be shorter than entrances?","\nUsually. Users have already decided to dismiss something, so the exit should get out of the way. Exits commonly run at 60 to 80 percent of the matching entrance duration.",[14,1685,1686,1689],{},[208,1687,1688],{},"What duration should reduced-motion users get?","\nFor movement, none or nearly none. Keep short opacity or colour changes if they help communicate state, since those are not the motion that affects vestibular disorders, but remove travel, scaling, parallax and bounces.",[42,1691,1693],{"id":1692},"related","Related",[1695,1696,1697,1702,1709,1716,1723],"ul",{},[205,1698,1699,1701],{},[31,1700,34],{"href":33}," — the parent guide.",[205,1703,1704,1708],{},[31,1705,1707],{"href":1706},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fentry-vs-exit-easing\u002F","Entry vs Exit Easing"," — asymmetric curves and durations.",[205,1710,1711,1715],{},[31,1712,1714],{"href":1713},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002F","CSS Custom Properties Architecture"," — where motion tokens live.",[205,1717,1718,1722],{},[31,1719,1721],{"href":1720},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fstaggered-list-animations-with-custom-properties\u002F","Staggered List Animations With Custom Properties"," — sequence timing in practice.",[205,1724,1725,1729],{},[31,1726,1728],{"href":1727},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-space-scale-with-clamp\u002F","Fluid Space Scale With clamp()"," — the spacing scale durations can follow.",[357,1731,1732],{},"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":241,"searchDepth":265,"depth":265,"links":1734},[1735,1736,1737,1738,1739,1740,1741,1742,1743],{"id":44,"depth":265,"text":45},{"id":54,"depth":265,"text":55},{"id":226,"depth":265,"text":227},{"id":1335,"depth":265,"text":1336},{"id":1587,"depth":265,"text":1588},{"id":1597,"depth":265,"text":1598},{"id":1633,"depth":265,"text":1634},{"id":1664,"depth":265,"text":1665},{"id":1692,"depth":265,"text":1693},"How long UI motion should last: duration ranges by element size and travel distance, duration tokens, scaling with container size, and reduced-motion timing.","md",{"pageTitle":1747,"datePublished":1748,"dateModified":1748,"faq":1749},"Choosing CSS Animation Durations","2026-09-18",[1750,1752,1754,1756],{"q":1670,"a":1751},"Around 150 to 250 milliseconds for small state changes such as hover, focus and toggles, and 250 to 400 milliseconds for larger movements such as panels and dialogs. Anything under about 100 milliseconds is perceived as instant, and anything over about 500 milliseconds starts to feel slow for routine interactions.",{"q":1676,"a":1753},"Generally yes. A larger element or a longer travel distance needs more time for the eye to follow, so duration should grow with distance, but less than proportionally. Doubling the distance calls for roughly a 20 to 40 percent longer duration, not double.",{"q":1682,"a":1755},"Usually. Users have already decided to dismiss something, so the exit should get out of the way. Exits commonly run at 60 to 80 percent of the matching entrance duration.",{"q":1688,"a":1757},"For movement, none or nearly none. Keep short opacity or colour changes if they help communicate state, since those are not the motion that affects vestibular disorders, but remove travel, scaling, parallax and bounces.","\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fchoosing-animation-durations",{"title":5,"description":1744},"css-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fchoosing-animation-durations\u002Findex","XL5dFgII_WoYF_6QgaCk62IbD15BrqCqfBsE-XsR9mk",[1763,1766,1769,1772,1775,1778,1781,1784,1787,1790,1793,1796,1799,1802,1805,1808,1811,1814,1817,1820,1823,1826,1829,1832,1835,1838,1841,1844,1847,1850,1853,1856,1859,1862,1865,1868,1871,1874,1877,1880,1883,1886,1889,1892,1895,1898,1901,1904,1907,1908,1911,1914,1917,1920,1923,1926,1929,1932,1935,1938,1941,1944,1947,1950,1953,1956,1959,1962,1965,1968,1971,1974,1977,1980,1983,1986,1989,1992,1995,1998,2001,2004,2007,2010,2013,2016,2019,2022,2025,2028,2031,2034,2037,2040,2042,2045,2048,2051,2054,2057,2060,2063,2066,2069,2072,2075,2078,2081,2084,2087,2090,2093,2096,2099,2102,2105,2108,2111,2114,2117,2120,2123,2126,2129,2132,2135,2138,2141,2144,2147,2150,2153,2156,2159,2162,2165,2168,2171,2174,2177,2180,2183,2186,2189,2192,2195,2198,2201,2204,2207,2210,2213,2216,2219,2222,2225,2228,2231,2234,2237,2240,2243,2246,2249,2252,2255,2258,2261,2264,2267,2270,2273,2276,2279,2282,2285,2288,2291,2294,2297,2300,2303,2306,2309,2312,2315,2318],{"path":1764,"title":1765},"\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":1767,"title":1768},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fflashing-content-and-seizure-thresholds","Flashing Content and Seizure Thresholds",{"path":1770,"title":1771},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fforced-colors-mode-and-animations","Forced Colors Mode and Animations",{"path":1773,"title":1774},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations","Accessibility in CSS Animations: Patterns, Specs & Best Practices",{"path":1776,"title":1777},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fpause-controls-for-looping-animations","Pause Controls for Looping CSS Animations: Meeting WCAG 2.2.2",{"path":1779,"title":1780},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fprefers-reduced-motion-recipes","prefers-reduced-motion Recipes: A Reduction for Every Common Effect",{"path":1782,"title":1783},"\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":1785,"title":1786},"\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":1788,"title":1789},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fvestibular-safe-animation-patterns","Vestibular-Safe Animation Patterns: Why Some Motion Makes People Sick",{"path":1791,"title":1792},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fwcag-motion-success-criteria","WCAG Motion Success Criteria: What Each One Actually Requires",{"path":1794,"title":1795},"\u002Fcss-only-micro-interactions-animations\u002Fclip-path-and-mask-animations\u002Fanimated-gradient-borders-with-property","Animated Gradient Borders With @property: A Spinning Highlight Without Extra Elements",{"path":1797,"title":1798},"\u002Fcss-only-micro-interactions-animations\u002Fclip-path-and-mask-animations\u002Fclip-path-reveal-animations","Clip-Path Reveal Animations: Wipes, Irises and Corners Without Extra Markup",{"path":1800,"title":1801},"\u002Fcss-only-micro-interactions-animations\u002Fclip-path-and-mask-animations","Clip-Path & Mask Animations: Animating Visibility Instead of Position",{"path":1803,"title":1804},"\u002Fcss-only-micro-interactions-animations\u002Fclip-path-and-mask-animations\u002Fmask-image-fade-edges","Fading Edges With mask-image: Soft Boundaries That Work on Any Background",{"path":1806,"title":1807},"\u002Fcss-only-micro-interactions-animations\u002Fclip-path-and-mask-animations\u002Fmorphing-shapes-with-clip-path-polygon","Morphing Shapes With clip-path: polygon(): Point-Matched Transitions",{"path":1809,"title":1810},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions\u002Fanimating-gradients","Animating CSS Gradients: Smooth Colour Motion Without Jumps",{"path":1812,"title":1813},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions\u002Fcolor-mix-hover-states","Hover and Active States With color-mix(): One Token, Every Shade",{"path":1815,"title":1816},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions","Color & Theme Transitions: Colour as Part of the Motion System",{"path":1818,"title":1819},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions\u002Flight-dark-function-for-themes","Light and Dark Themes With light-dark(): One Declaration per Colour",{"path":1821,"title":1822},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions\u002Fsmooth-theme-switching-transitions","Smooth Theme Switching: Crossfades, Circular Reveals and No Flash",{"path":1824,"title":1825},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fcontainer-query-hover-affordances","Container Query Hover Affordances: When Narrow Means Persistent, Not Hidden",{"path":1827,"title":1828},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion","Container-Aware Motion: Animation Sized by the Space a Component Actually Has",{"path":1830,"title":1831},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Flayout-change-animations-at-container-breakpoints","Animating Changes at Container Breakpoints",{"path":1833,"title":1834},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fmotion-driven-by-container-style-queries","Motion Driven by Container Style Queries",{"path":1836,"title":1837},"\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":1839,"title":1840},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fsuppressing-motion-in-small-containers","Suppressing Motion in Small Containers: Deliberately Animating Nothing",{"path":1842,"title":1843},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api\u002Fcontrolling-css-animations-from-javascript","Controlling CSS Animations From JavaScript",{"path":1845,"title":1846},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api","CSS Animation vs the Web Animations API: A Decision Guide",{"path":1848,"title":1849},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api\u002Fwaapi-vs-css-for-interruptible-ui","Interruptible UI: CSS Transitions vs WAAPI",{"path":1851,"title":1852},"\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":1854,"title":1855},"\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":1857,"title":1858},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Fcustom-property-fallbacks-and-invalid-values","Custom Property Fallbacks and Invalid Values",{"path":1860,"title":1861},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Ffluid-spacing-tokens-driving-transition-durations","Fluid Spacing Tokens That Drive Transition Durations",{"path":1863,"title":1864},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture","CSS Custom Properties Architecture: Scalable Design Systems & Dynamic UI",{"path":1866,"title":1867},"\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":1869,"title":1870},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Fscoping-custom-properties-to-components","Scoping Custom Properties to Components",{"path":1872,"title":1873},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fcss-transition-timing-functions","CSS Transition Timing Functions: ease, cubic-bezier(), steps() and linear()",{"path":1875,"title":1876},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals","CSS Transition Fundamentals: Architecture, Performance & Patterns",{"path":1878,"title":1879},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Finterrupted-and-reversing-transitions","Interrupted and Reversing Transitions: What Happens Mid-Flight",{"path":1881,"title":1882},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fstarting-style-entry-animations","@starting-style: Animating an Element's Very First Style Change",{"path":1884,"title":1885},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransition-delay-choreography","Choreographing Motion With transition-delay",{"path":1887,"title":1888},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransition-shorthand-and-multiple-properties","The transition Shorthand and Multiple Properties",{"path":1890,"title":1891},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransitioning-display-with-allow-discrete","Transitioning display with transition-behavior: allow-discrete and @starting-style",{"path":1893,"title":1894},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Fanimating-dialog-open-and-close","Animating \u003Cdialog> Open and Close: Both Directions, No Library",{"path":1896,"title":1897},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Fbackdrop-animations","Animating ::backdrop: Fades and Blurs Behind Dialogs and Popovers",{"path":1899,"title":1900},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations","Dialog & Popover Animations: Motion for the Top Layer",{"path":1902,"title":1903},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Finterpolate-size-for-height-auto-animation","Animating to height: auto With interpolate-size and calc-size()",{"path":1905,"title":1906},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Fpopover-entry-and-exit-transitions","Popover Menus That Animate From Their Anchor",{"path":1758,"title":5},{"path":1909,"title":1910},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fcubic-bezier-overshoot-and-anticipation","Overshoot and Anticipation With cubic-bezier(): Motion With Character",{"path":1912,"title":1913},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fentry-vs-exit-easing","Entry vs Exit Easing: Different Curves for Arriving and Leaving",{"path":1915,"title":1916},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design","Easing & Motion Design: Making CSS Motion Feel Intentional",{"path":1918,"title":1919},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Flinear-easing-function-for-springs","Spring and Bounce Easing With linear(): Physical Motion Without JavaScript",{"path":1921,"title":1922},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fsteps-easing-for-sprite-animations","steps() Easing: Sprite Sheets, Typewriters and Other Frame-by-Frame Effects",{"path":1924,"title":1925},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Faccessible-css-only-tooltips","Accessible CSS-Only Tooltips and Hover Cards With  and ",{"path":1927,"title":1928},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Fbutton-press-and-active-states","Button Press and  States",{"path":1930,"title":1931},"\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":1933,"title":1934},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Ffocus-within-form-patterns"," Form Patterns: Styling a Group From the Field Inside It",{"path":1936,"title":1937},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Fhover-intent-delays-with-transition-delay","Hover Intent Delays With transition-delay: Menus That Don't Flicker",{"path":1939,"title":1940},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design","Hover & Focus State Design: Spec-Compliant Patterns for Modern UIs",{"path":1942,"title":1943},"\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":1945,"title":1946},"\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":1948,"title":1949},"\u002Fcss-only-micro-interactions-animations","CSS-Only Micro-Interactions & Animations: Architecture, Performance & Implementation",{"path":1951,"title":1952},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fanimation-composition-and-stacking","Stacking Animations With animation-composition",{"path":1954,"title":1955},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fanimation-fill-mode-explained","animation-fill-mode: What an Animation Applies Before and After It Runs",{"path":1957,"title":1958},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcontainer-query-triggered-keyframe-animations","Container-Query-Triggered Keyframe Animations: Animate Differently per Available Space",{"path":1960,"title":1961},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcss-only-accordions-and-disclosure","CSS-Only Accordions and Disclosure Widgets with details and summary",{"path":1963,"title":1964},"\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":1966,"title":1967},"\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":1969,"title":1970},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns","Keyframe Animation Patterns: Spec-Compliant Architectures for Modern UIs",{"path":1972,"title":1973},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fmulti-step-keyframes-and-per-keyframe-easing","Multi-Step Keyframes and Per-Keyframe Easing",{"path":1975,"title":1976},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fstaggered-list-animations-with-custom-properties","Staggered List Animations Using --i Index Custom Properties",{"path":1978,"title":1979},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fanimating-box-shadow-and-filters-cheaply","Animating box-shadow and Filters Cheaply",{"path":1981,"title":1982},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fcontain-property-for-animation-performance","The contain Property for Animation Performance",{"path":1984,"title":1985},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fcss-triggers-layout-paint-composite","Layout, Paint and Composite: What Triggers What",{"path":1987,"title":1988},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration","Performance & GPU Acceleration in CSS: A Developer’s Blueprint",{"path":1990,"title":1991},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Foptimizing-css-animations-for-60fps","Optimizing CSS Animations for 60fps: Budgeting the Frame",{"path":1993,"title":1994},"\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":1996,"title":1997},"\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":1999,"title":2000},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations","Scroll-Driven Animations: Binding Motion to Scroll Position in Pure CSS",{"path":2002,"title":2003},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-driven-animation-fallbacks","Shipping Scroll-Driven Animations Without Breaking Anything",{"path":2005,"title":2006},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-driven-parallax-effects","Scroll-Driven Parallax Effects in CSS",{"path":2008,"title":2009},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-progress-bar-without-javascript","A Reading Progress Bar Driven by scroll(root)",{"path":2011,"title":2012},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-triggered-reveal-animations","Reveal-on-Scroll with view() and animation-range",{"path":2014,"title":2015},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Ftimeline-scope-for-cross-element-animations","timeline-scope for Cross-Element Animations",{"path":2017,"title":2018},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fview-timeline-and-animation-range","View Timelines and animation-range",{"path":2020,"title":2021},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fcross-document-view-transitions","Cross-Document View Transitions",{"path":2023,"title":2024},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers","View Transitions for CSS Developers: the Pseudo-Element Tree, Snapshots, and Named Elements",{"path":2026,"title":2027},"\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":2029,"title":2030},"\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":2032,"title":2033},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transition-types-and-classes","View Transition Types and Classes",{"path":2035,"title":2036},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transitions-for-list-reordering","View Transitions for List Reordering",{"path":2038,"title":2039},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transitions-with-reduced-motion","Honouring prefers-reduced-motion in View Transitions",{"path":676,"title":2041},"Modern CSS Layouts & Micro-Interactions",{"path":2043,"title":2044},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-positioned-tooltips","Anchor-Positioned Tooltips: Tethering, Flipping, and Getting the Semantics Right",{"path":2046,"title":2047},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-positioning-fallbacks","Anchor Positioning Fallbacks: A Graceful Floor for Older Browser Versions",{"path":2049,"title":2050},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-size-for-matching-widths","anchor-size(): Overlays That Match Their Trigger's Size",{"path":2052,"title":2053},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays","CSS Anchor Positioning and Overlays: Tethering Elements Without JavaScript",{"path":2055,"title":2056},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fpopover-attribute-and-css-styling","The popover Attribute: Top-Layer Overlays With No JavaScript",{"path":2058,"title":2059},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fpopover-light-dismiss-and-stacking","Popover Light Dismiss, Nesting and Stacking",{"path":2061,"title":2062},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fposition-area-grid-explained","position-area: The Anchor Placement Grid",{"path":2064,"title":2065},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fcontainer-query-polyfill-tradeoffs","Container Query Polyfills: What They Cost and When to Skip Them",{"path":2067,"title":2068},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Ffeature-detection-with-supports","Feature Detection with @supports: Syntax, Semantics, and the Traps",{"path":2070,"title":2071},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fhandling-container-query-fallbacks-for-older-browsers","Handling Container Query Fallbacks for Older Browsers",{"path":2073,"title":2074},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks","Container Query Fallbacks: Spec-Compliant CSS Strategies for Legacy Browsers",{"path":2076,"title":2077},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fintrinsic-layout-fallbacks-without-queries","Intrinsic Layout Fallbacks: Baselines That Adapt Without Any Query",{"path":2079,"title":2080},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Ftesting-fallbacks-without-old-browsers","Testing CSS Fallbacks Without an Old Browser",{"path":2082,"title":2083},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-queries-inside-css-nesting","Container Queries Inside CSS Nesting: Keeping Responses Next to the Styles They Change",{"path":2085,"title":2086},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-query-range-and-logic-operators","Container Query Range Syntax and Logic Operators",{"path":2088,"title":2089},"\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":2091,"title":2092},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-type-size-vs-inline-size","Choosing container-type: inline-size, size, or normal",{"path":2094,"title":2095},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-vs-media-queries-comparison","Container vs Media Queries: Choosing the Right Reference Box",{"path":2097,"title":2098},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fdebugging-container-queries-in-devtools","Debugging Container Queries in DevTools: Why a Rule Doesn't Match",{"path":2100,"title":2101},"\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":2103,"title":2104},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics","Container Query Syntax Basics",{"path":2106,"title":2107},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fnesting-and-naming-container-queries","Nesting and Naming Container Queries: Targeting the Right Ancestor",{"path":2109,"title":2110},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fauto-fit-minmax-responsive-grids","Responsive Grids with repeat(auto-fit, minmax())",{"path":2112,"title":2113},"\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":2115,"title":2116},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fgrid-auto-flow-dense-packing","grid-auto-flow: dense for Packed Layouts",{"path":2118,"title":2119},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fgrid-template-areas-responsive-layouts","Responsive Layouts With grid-template-areas: Rearranging Regions by Name",{"path":2121,"title":2122},"\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":2124,"title":2125},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts","CSS Grid and Subgrid Layouts for Responsive Interfaces",{"path":2127,"title":2128},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fmasonry-style-layouts-with-grid","Masonry-Style Layouts With the CSS That Ships Today",{"path":2130,"title":2131},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Foverlapping-elements-with-grid-stacking","Overlapping Elements With Grid Stacking: Layers Without position: absolute",{"path":2133,"title":2134},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fsubgrid-vs-nested-grid","Subgrid vs an Independently Nested Grid",{"path":2136,"title":2137},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fcentering-in-css-every-method","Centering in CSS: Every Modern Method and When Each One Breaks",{"path":2139,"title":2140},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflex-basis-vs-width","flex-basis vs width: Which Size a Flex Item Actually Starts From",{"path":2142,"title":2143},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflex-grow-and-flex-shrink-explained","flex-grow and flex-shrink Explained",{"path":2145,"title":2146},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflex-wrap-intrinsic-responsive-rows","Breakpoint-Free Responsive Rows With flex-wrap and flex-basis",{"path":2148,"title":2149},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflexbox-gap-and-spacing","Flexbox gap vs Margins: Spacing Items Without Edge Hacks",{"path":2151,"title":2152},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns","Flexbox Layout Patterns: One-Dimensional Layout for Real Components",{"path":2154,"title":2155},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fsticky-footer-with-flexbox-and-grid","Sticky Footer With Flexbox or Grid: Pinning the Footer on Short Pages",{"path":2157,"title":2158},"\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":2160,"title":2161},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Fdebugging-clamp-values","Debugging clamp(): Values That Are Ignored, Stuck or Never Fluid",{"path":2163,"title":2164},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-line-height-and-measure","Fluid Line Height and Measure: Keeping Text Readable as It Scales",{"path":2166,"title":2167},"\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":2169,"title":2170},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-type-accessibility-and-zoom","Fluid Type, Accessibility and Zoom: The vw-Only Trap",{"path":2172,"title":2173},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-typography-without-javascript","Fluid Typography Without JavaScript: A Precision CSS Reference",{"path":2175,"title":2176},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp","Fluid Typography with clamp(): A Practical Guide for Modern CSS",{"path":2178,"title":2179},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ftext-wrap-balance-and-pretty","text-wrap: balance and pretty: Better Line Breaks Without Manual Breaks",{"path":2181,"title":2182},"\u002Fmastering-container-queries-responsive-layouts","Mastering Container Queries & Responsive Layouts",{"path":2184,"title":2185},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Faspect-ratio-for-responsive-media","Using aspect-ratio for Responsive Media and Preventing Layout Shift",{"path":2187,"title":2188},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fcontent-visibility-and-contain-intrinsic-size","content-visibility and contain-intrinsic-size: Rendering Only What Is Near the Screen",{"path":2190,"title":2191},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques","Intrinsic Sizing Techniques: Modern CSS Layouts for Responsive UI",{"path":2193,"title":2194},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Flayout-widths-with-min-max-clamp","Layout Widths With min(), max() and clamp(): Sizing Without Breakpoints",{"path":2196,"title":2197},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fmin-max-fit-content-explained","min-content, max-content, and fit-content() Explained",{"path":2199,"title":2200},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fobject-fit-and-object-position","object-fit and object-position: Images That Fit Any Box",{"path":2202,"title":2203},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fpreventing-flex-and-grid-overflow","The min-width: auto Trap in Flex and Grid Layouts",{"path":2205,"title":2206},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-for-reset-and-tokens","Cascade Layers for Reset and Design Tokens",{"path":2208,"title":2209},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-vs-specificity-hacks","Cascade Layers vs Specificity Hacks: Ordering Instead of Escalating",{"path":2211,"title":2212},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcss-scope-for-component-styles","@scope for Component Styles: Short Selectors That Cannot Leak",{"path":2214,"title":2215},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies","Modern CSS Reset Strategies: A Spec-Compliant Foundation",{"path":2217,"title":2218},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Frevert-layer-and-revert-keywords","initial, inherit, unset, revert and revert-layer: Undoing Styles Correctly",{"path":2220,"title":2221},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fwriting-a-minimal-modern-reset","Writing a Minimal Modern CSS Reset: Every Line Justified",{"path":2223,"title":2224},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has\u002Fcontent-aware-card-layouts-with-has","Content-Aware Card Layouts With :has(): One Component, Many Shapes",{"path":2226,"title":2227},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has\u002Fempty-and-loading-states-with-has","Empty and Loading States With ()",{"path":2229,"title":2230},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has\u002Fform-validation-layouts-with-has","Form Validation Layouts With :has(): Styling Groups From Field State",{"path":2232,"title":2233},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has\u002Fhas-selector-performance",":has() Selector Performance: What Is Cheap, What Is Not, and How to Measure",{"path":2235,"title":2236},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has\u002Fhas-vs-container-style-queries",":has() vs Container Style Queries: Discovered State and Published State",{"path":2238,"title":2239},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has","Parent-Aware Layouts With :has(): Letting Containers React to Their Contents",{"path":2241,"title":2242},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has\u002Fquantity-queries-with-has","Quantity Queries With :has(): Layouts That Respond to How Many Items There Are",{"path":2244,"title":2245},"\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":2247,"title":2248},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fcontainer-query-data-tables","Container Query Data Tables: Reflowing Tables to Cards",{"path":2250,"title":2251},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fcontainer-query-sidebar-layouts","Container Query Sidebar Layouts That Travel Between Contexts",{"path":2253,"title":2254},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns","Responsive Component Patterns: Architecture & Implementation",{"path":2256,"title":2257},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-forms-with-container-queries","Responsive Forms with Container Queries: Reflow Without Losing the Wiring",{"path":2259,"title":2260},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-hero-sections-with-container-queries","Responsive Hero Sections With Container Queries",{"path":2262,"title":2263},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-navigation-without-media-queries","Responsive Navigation Without Media Queries Using Container Queries",{"path":2265,"title":2266},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-pricing-tables","Responsive Pricing Tables: Aligned Features, a Clear Recommendation, Any Width",{"path":2268,"title":2269},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Ftabs-that-become-accordions","Tabs That Become an Accordion: One Component, Two Layouts",{"path":2271,"title":2272},"\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts\u002Fcss-only-carousel-with-scroll-snap","A CSS-Only Carousel With Scroll Snap",{"path":2274,"title":2275},"\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts\u002Fhorizontal-scrolling-card-rows","Horizontal Scrolling Card Rows: Swipeable Lists That Stay in Their Lane",{"path":2277,"title":2278},"\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts","Scroll Snap & Overflow Layouts: Designing Components That Scroll on Purpose",{"path":2280,"title":2281},"\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts\u002Foverscroll-behavior-for-nested-scrolling","overscroll-behavior: Taming Nested Scrolling, Pull-to-Refresh and Back-Swipe",{"path":2283,"title":2284},"\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts\u002Fscroll-margin-and-scroll-padding-for-sticky-headers","scroll-margin and scroll-padding: Keeping Targets Clear of Sticky Headers",{"path":2286,"title":2287},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fcombining-size-and-style-queries","Combining Size and Style Container Queries",{"path":2289,"title":2290},"\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":2292,"title":2293},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state","Style Queries and Container State: Token-Driven Component Variants",{"path":2295,"title":2296},"\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":2298,"title":2299},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fstyle-query-component-variants","Component Variants With Style Queries: One Token, Many Looks",{"path":2301,"title":2302},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fstyle-query-fallbacks-and-support","Style Query Fallbacks and Support: Designing for Older Browser Versions",{"path":2304,"title":2305},"\u002Fmastering-container-queries-responsive-layouts\u002Fviewport-units-and-mobile-layout\u002Fdvh-svh-lvh-mobile-viewport-units","dvh, svh and lvh: Choosing the Right Mobile Viewport Unit",{"path":2307,"title":2308},"\u002Fmastering-container-queries-responsive-layouts\u002Fviewport-units-and-mobile-layout\u002Ffull-bleed-sections-in-constrained-layouts","Full-Bleed Sections in a Constrained Layout: Breaking Out Without Breaking the Page",{"path":2310,"title":2311},"\u002Fmastering-container-queries-responsive-layouts\u002Fviewport-units-and-mobile-layout","Viewport Units & Mobile Layout: Designing for the Screen You Actually Get",{"path":2313,"title":2314},"\u002Fmastering-container-queries-responsive-layouts\u002Fviewport-units-and-mobile-layout\u002Fsafe-area-insets-for-notched-screens","Safe Area Insets: Designing Around Notches, Corners and Home Indicators",{"path":2316,"title":2317},"\u002Fmastering-container-queries-responsive-layouts\u002Fviewport-units-and-mobile-layout\u002Fviewport-units-vs-container-units","Viewport Units vs Container Units: Choosing the Right Reference Box",{"path":2319,"title":2320},"\u002Fmastering-container-queries-responsive-layouts\u002Fviewport-units-and-mobile-layout\u002Fvirtual-keyboard-and-interactive-widget","Layouts That Survive the Virtual Keyboard",{"title":2322,"caption":2323,"height":2324,"html":2325,"css":2326},"Components timed from a duration token scale","Hover and press the button (fast tokens), then tick the checkbox to slide the panel in at the panel duration.",240,"\n\u003Cbutton class=\"button\" type=\"button\">Save\u003C\u002Fbutton>\n\u003Cdiv>\u003Cinput class=\"toggle\" type=\"checkbox\" id=\"show\" aria-controls=\"p\"> \u003Clabel for=\"show\">Show details\u003C\u002Flabel>\n\u003Cdiv class=\"panel\" id=\"p\">Details slide up over the panel duration.\u003C\u002Fdiv>\u003C\u002Fdiv>","\n:root {\n  --duration-instant: 70ms;\n  --duration-fast: 140ms;\n  --duration-base: 220ms;\n  --duration-moderate: 320ms;\n  --duration-slow: 450ms;\n  --motion-press: var(--duration-instant);\n  --motion-hover: var(--duration-fast);\n  --motion-reveal: var(--duration-base);\n  --motion-panel: var(--duration-moderate);\n  --motion-page: var(--duration-slow);\n}\n@media (prefers-reduced-motion: reduce) {\n  :root { --motion-reveal: 1ms; --motion-panel: 1ms; --motion-page: 1ms; }\n}\nbody { display: grid; gap: 1rem; justify-items: start; align-content: center; }\n.button { padding: 0.5rem 1rem; border: 0; border-radius: 8px; background: #4f46e5; color: #ffffff; font: inherit; transition: background-color var(--motion-hover) ease, scale var(--motion-press) ease; }\n.button:hover { background-color: #3730a3; }\n.button:active { scale: 0.97; }\n.button:focus-visible { outline: 2px solid var(--demo-fg); outline-offset: 2px; }\n.panel { margin-top: 0.75rem; padding: 1rem; border-radius: 12px; background: var(--demo-surface); border: 1px solid var(--demo-border); translate: 0 0.5rem; opacity: 0; transition: translate var(--motion-panel) cubic-bezier(0.22, 1, 0.36, 1), opacity var(--motion-panel) ease; }\n.toggle:checked ~ .panel { translate: 0 0; opacity: 1; }",1789717746646]