[{"data":1,"prerenderedAt":1965},["ShallowReactive",2],{"page-\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Finterrupted-and-reversing-transitions":3,"content-all-pages":1400,"live-demo:transition-interrupt":1959},{"id":4,"title":5,"body":6,"description":1382,"extension":1383,"meta":1384,"navigation":459,"path":1396,"seo":1397,"stem":1398,"__hash__":1399},"content\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Finterrupted-and-reversing-transitions\u002Findex.md","Interrupted and Reversing Transitions: What Happens Mid-Flight",{"type":7,"value":8,"toc":1371},"minimark",[9,13,28,33,36,48,139,143,146,150,956,968,972,980,1041,1048,1051,1055,1067,1087,1091,1094,1112,1140,1146,1163,1173,1177,1180,1275,1291,1295,1308,1312,1318,1324,1330,1336,1340,1368],[10,11,5],"h1",{"id":12},"interrupted-and-reversing-transitions-what-happens-mid-flight",[14,15,16,17,22,23,27],"p",{},"Users do not wait for animations to finish. They sweep the pointer across a row of cards, tap a toggle twice in quick succession, press Escape half a second after opening a menu. Every one of those actions interrupts a transition that is still running, and how the browser handles the interruption determines whether the interface feels responsive or glitchy. CSS transitions handle interruption remarkably well by default — they reverse from wherever they are, and they even shorten the reverse to match how far they got — but only if you understand and preserve the conditions that make that work. This page explains the rules and the common ways they are accidentally broken. It belongs to ",[18,19,21],"a",{"href":20},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002F","CSS Transition Fundamentals"," in the ",[18,24,26],{"href":25},"\u002Fcss-only-micro-interactions-animations\u002F","CSS-Only Micro-Interactions & Animations"," guide.",[29,30,32],"h2",{"id":31},"why-interruption-matters","Why interruption matters",[14,34,35],{},"A transition that runs for 300 milliseconds is interrupted whenever the user's next action comes within those 300 milliseconds — which, for hover effects on dense interfaces, is most of the time. If interruption produced a jump or a restart, hover effects on a list would flicker constantly as the pointer moved across items. The quality of interrupted motion is therefore not an edge case; it is the ordinary case for many micro-interactions.",[14,37,38,39,43,44,47],{},"Two things can go right or wrong. The ",[40,41,42],"strong",{},"starting point"," of the new motion should be the element's current visual state, not either endpoint. And the ",[40,45,46],{},"duration"," of the new motion should match the distance left to travel, not the full original duration.",[49,50,56,57,56,61,56,65,56,73,56,82,56,85,56,91,56,96,56,100,56,107,56,110,56,115,56,120,56,127,56,133],"svg",{"viewBox":51,"role":52,"ariaLabel":53,"xmlns":54,"style":55},"0 0 720 300","img","Position over time for a hover transition interrupted at 25 percent: a correct reverse from the current value, versus a jump back and a restart","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;height:auto;max-width:720px;margin:2rem 0","\n  ",[58,59,60],"title",{},"Three ways an interruption could behave",[62,63,64],"desc",{},"A 400 millisecond transition is interrupted after 100 milliseconds at about a quarter of its travel. CSS transitions reverse from that point back to the start in about 100 milliseconds. A naive implementation would jump to the end first, or restart from zero with the full duration.",[66,67,72],"text",{"textAnchor":68,"x":69,"y":70,"style":71},"middle","360","26","text-anchor:middle;fill:currentColor;font:700 17px sans-serif","Interrupted at 100ms of a 400ms hover",[74,75],"line",{"x1":76,"y1":77,"x2":78,"y2":77,"stroke":79,"strokeWidth":80,"opacity":81},"80","240","660","currentColor","1.5","0.6",[74,83],{"x1":76,"y1":84,"x2":76,"y2":77,"stroke":79,"strokeWidth":80,"opacity":81},"60",[66,86,90],{"textAnchor":87,"x":78,"y":88,"style":89},"end","262","text-anchor:end;fill:currentColor;font:12px sans-serif","time",[66,92,95],{"textAnchor":87,"x":93,"y":93,"style":94},"72","text-anchor:end;fill:currentColor;font:11px sans-serif","hovered",[66,97,99],{"textAnchor":87,"x":93,"y":98,"style":94},"244","rest",[101,102],"path",{"d":103,"fill":104,"stroke":105,"strokeWidth":106},"M80 240 C110 200 130 185 160 180","none","#7aa2ff","4",[101,108],{"d":109,"fill":104,"stroke":105,"strokeWidth":106},"M160 180 C190 200 210 230 240 240",[74,111],{"x1":112,"y1":84,"x2":112,"y2":77,"stroke":79,"strokeDashArray":113,"opacity":81},"160",[114,114],"3",[66,116,119],{"textAnchor":68,"x":112,"y":117,"style":118},"54","text-anchor:middle;fill:currentColor;font:11px sans-serif","pointer leaves",[66,121,126],{"textAnchor":122,"x":123,"y":124,"style":125},"start","250","226","text-anchor:start;fill:currentColor;font:600 12px sans-serif","CSS: reverse from here, ~100ms",[101,128],{"d":129,"fill":104,"stroke":79,"strokeWidth":130,"strokeDashArray":131,"opacity":81},"M160 180 L160 72 C300 100 400 220 480 240","2",[132,106],"6",[66,134,138],{"textAnchor":122,"x":135,"y":136,"style":137},"420","150","text-anchor:start;fill:currentColor;font:12px sans-serif","jump, then full reverse",[29,140,142],{"id":141},"the-complete-implementation","The complete implementation",[14,144,145],{},"The demo compares a transition-based hover with a keyframe-based one. Sweep the pointer quickly across both rows and back.",[147,148],"live-demo",{"name":149},"transition-interrupt",[151,152,157],"pre",{"className":153,"code":154,"language":155,"meta":156,"style":156},"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>Interrupted transitions\u003C\u002Ftitle>\n\u003Cstyle>\n  body { font: 15px\u002F1.5 system-ui, sans-serif; margin: 1.5rem; display: grid; gap: 1.5rem; }\n  .row { display: flex; gap: 0.5rem; }\n  .chip {\n    padding: 0.8rem 1rem;\n    border-radius: 8px;\n    background: #e0e7ff;\n    color: #1e1b4b;\n  }\n\n  \u002F* TRANSITION: interrupting reverses smoothly from the current value,\n     and a reverse after a short hover is correspondingly short. *\u002F\n  .row--transition .chip {\n    transition: translate 400ms cubic-bezier(0.22, 1, 0.36, 1),\n                background-color 400ms ease;\n  }\n  .row--transition .chip:hover {\n    translate: 0 -10px;\n    background-color: #a5b4fc;\n  }\n\n  \u002F* KEYFRAMES: when :hover stops matching, the animation is removed and\n     the chip snaps back instantly, wherever it was. *\u002F\n  .row--keyframes .chip:hover {\n    animation: lift 400ms cubic-bezier(0.22, 1, 0.36, 1) forwards;\n  }\n  @keyframes lift {\n    to { translate: 0 -10px; background-color: #a5b4fc; }\n  }\n\n  @media (prefers-reduced-motion: reduce) {\n    .row--transition .chip { transition-duration: 1ms; }\n    .row--keyframes .chip:hover { animation: none; background-color: #a5b4fc; }\n  }\n\u003C\u002Fstyle>\n\u003C\u002Fhead>\n\u003Cbody>\n  \u003Cdiv class=\"row row--transition\">\u003Cspan class=\"chip\">Transition\u003C\u002Fspan>\u003Cspan class=\"chip\">Transition\u003C\u002Fspan>\u003Cspan class=\"chip\">Transition\u003C\u002Fspan>\u003C\u002Fdiv>\n  \u003Cdiv class=\"row row--keyframes\">\u003Cspan class=\"chip\">Keyframes\u003C\u002Fspan>\u003Cspan class=\"chip\">Keyframes\u003C\u002Fspan>\u003Cspan class=\"chip\">Keyframes\u003C\u002Fspan>\u003C\u002Fdiv>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>\n","html","",[158,159,160,179,199,209,227,252,266,276,349,377,386,407,422,435,448,454,461,468,474,485,526,541,546,556,574,587,592,597,603,609,619,658,663,675,705,710,715,724,745,772,777,787,796,806,875,938,947],"code",{"__ignoreMap":156},[161,162,164,168,172,176],"span",{"class":74,"line":163},1,[161,165,167],{"class":166},"suds8","\u003C!",[161,169,171],{"class":170},"sne4z","doctype",[161,173,175],{"class":174},"s-5SL"," html",[161,177,178],{"class":166},">\n",[161,180,182,185,187,190,193,197],{"class":74,"line":181},2,[161,183,184],{"class":166},"\u003C",[161,186,155],{"class":170},[161,188,189],{"class":174}," lang",[161,191,192],{"class":166},"=",[161,194,196],{"class":195},"sT6z2","\"en\"",[161,198,178],{"class":166},[161,200,202,204,207],{"class":74,"line":201},3,[161,203,184],{"class":166},[161,205,206],{"class":170},"head",[161,208,178],{"class":166},[161,210,212,214,217,220,222,225],{"class":74,"line":211},4,[161,213,184],{"class":166},[161,215,216],{"class":170},"meta",[161,218,219],{"class":174}," charset",[161,221,192],{"class":166},[161,223,224],{"class":195},"\"utf-8\"",[161,226,178],{"class":166},[161,228,230,232,234,237,239,242,245,247,250],{"class":74,"line":229},5,[161,231,184],{"class":166},[161,233,216],{"class":170},[161,235,236],{"class":174}," name",[161,238,192],{"class":166},[161,240,241],{"class":195},"\"viewport\"",[161,243,244],{"class":174}," content",[161,246,192],{"class":166},[161,248,249],{"class":195},"\"width=device-width, initial-scale=1\"",[161,251,178],{"class":166},[161,253,255,257,259,262,264],{"class":74,"line":254},6,[161,256,184],{"class":166},[161,258,58],{"class":170},[161,260,261],{"class":166},">Interrupted transitions\u003C\u002F",[161,263,58],{"class":170},[161,265,178],{"class":166},[161,267,269,271,274],{"class":74,"line":268},7,[161,270,184],{"class":166},[161,272,273],{"class":170},"style",[161,275,178],{"class":166},[161,277,279,282,285,288,291,294,298,301,303,306,309,312,315,318,320,322,325,327,330,332,335,337,340,342,344,346],{"class":74,"line":278},8,[161,280,281],{"class":170},"  body",[161,283,284],{"class":166}," { ",[161,286,287],{"class":174},"font",[161,289,290],{"class":166},": ",[161,292,293],{"class":174},"15",[161,295,297],{"class":296},"sHUrx","px",[161,299,300],{"class":166},"\u002F",[161,302,80],{"class":174},[161,304,305],{"class":174}," system-ui",[161,307,308],{"class":166},", ",[161,310,311],{"class":174},"sans-serif",[161,313,314],{"class":166},"; ",[161,316,317],{"class":174},"margin",[161,319,290],{"class":166},[161,321,80],{"class":174},[161,323,324],{"class":296},"rem",[161,326,314],{"class":166},[161,328,329],{"class":174},"display",[161,331,290],{"class":166},[161,333,334],{"class":174},"grid",[161,336,314],{"class":166},[161,338,339],{"class":174},"gap",[161,341,290],{"class":166},[161,343,80],{"class":174},[161,345,324],{"class":296},[161,347,348],{"class":166},"; }\n",[161,350,352,355,357,359,361,364,366,368,370,373,375],{"class":74,"line":351},9,[161,353,354],{"class":174},"  .row",[161,356,284],{"class":166},[161,358,329],{"class":174},[161,360,290],{"class":166},[161,362,363],{"class":174},"flex",[161,365,314],{"class":166},[161,367,339],{"class":174},[161,369,290],{"class":166},[161,371,372],{"class":174},"0.5",[161,374,324],{"class":296},[161,376,348],{"class":166},[161,378,380,383],{"class":74,"line":379},10,[161,381,382],{"class":174},"  .chip",[161,384,385],{"class":166}," {\n",[161,387,389,392,394,397,399,402,404],{"class":74,"line":388},11,[161,390,391],{"class":174},"    padding",[161,393,290],{"class":166},[161,395,396],{"class":174},"0.8",[161,398,324],{"class":296},[161,400,401],{"class":174}," 1",[161,403,324],{"class":296},[161,405,406],{"class":166},";\n",[161,408,410,413,415,418,420],{"class":74,"line":409},12,[161,411,412],{"class":174},"    border-radius",[161,414,290],{"class":166},[161,416,417],{"class":174},"8",[161,419,297],{"class":296},[161,421,406],{"class":166},[161,423,425,428,430,433],{"class":74,"line":424},13,[161,426,427],{"class":174},"    background",[161,429,290],{"class":166},[161,431,432],{"class":174},"#e0e7ff",[161,434,406],{"class":166},[161,436,438,441,443,446],{"class":74,"line":437},14,[161,439,440],{"class":174},"    color",[161,442,290],{"class":166},[161,444,445],{"class":174},"#1e1b4b",[161,447,406],{"class":166},[161,449,451],{"class":74,"line":450},15,[161,452,453],{"class":166},"  }\n",[161,455,457],{"class":74,"line":456},16,[161,458,460],{"emptyLinePlaceholder":459},true,"\n",[161,462,464],{"class":74,"line":463},17,[161,465,467],{"class":466},"sLBg1","  \u002F* TRANSITION: interrupting reverses smoothly from the current value,\n",[161,469,471],{"class":74,"line":470},18,[161,472,473],{"class":466},"     and a reverse after a short hover is correspondingly short. *\u002F\n",[161,475,477,480,483],{"class":74,"line":476},19,[161,478,479],{"class":174},"  .row--transition",[161,481,482],{"class":174}," .chip",[161,484,385],{"class":166},[161,486,488,491,494,497,500,503,506,509,511,514,516,519,521,523],{"class":74,"line":487},20,[161,489,490],{"class":174},"    transition",[161,492,493],{"class":166},": translate ",[161,495,496],{"class":174},"400",[161,498,499],{"class":296},"ms",[161,501,502],{"class":174}," cubic-bezier",[161,504,505],{"class":166},"(",[161,507,508],{"class":174},"0.22",[161,510,308],{"class":166},[161,512,513],{"class":174},"1",[161,515,308],{"class":166},[161,517,518],{"class":174},"0.36",[161,520,308],{"class":166},[161,522,513],{"class":174},[161,524,525],{"class":166},"),\n",[161,527,529,532,534,536,539],{"class":74,"line":528},21,[161,530,531],{"class":166},"                background-color ",[161,533,496],{"class":174},[161,535,499],{"class":296},[161,537,538],{"class":174}," ease",[161,540,406],{"class":166},[161,542,544],{"class":74,"line":543},22,[161,545,453],{"class":166},[161,547,549,551,554],{"class":74,"line":548},23,[161,550,479],{"class":174},[161,552,553],{"class":174}," .chip:hover",[161,555,385],{"class":166},[161,557,559,562,564,567,570,572],{"class":74,"line":558},24,[161,560,561],{"class":174},"    translate",[161,563,290],{"class":166},[161,565,566],{"class":174},"0",[161,568,569],{"class":174}," -10",[161,571,297],{"class":296},[161,573,406],{"class":166},[161,575,577,580,582,585],{"class":74,"line":576},25,[161,578,579],{"class":174},"    background-color",[161,581,290],{"class":166},[161,583,584],{"class":174},"#a5b4fc",[161,586,406],{"class":166},[161,588,590],{"class":74,"line":589},26,[161,591,453],{"class":166},[161,593,595],{"class":74,"line":594},27,[161,596,460],{"emptyLinePlaceholder":459},[161,598,600],{"class":74,"line":599},28,[161,601,602],{"class":466},"  \u002F* KEYFRAMES: when :hover stops matching, the animation is removed and\n",[161,604,606],{"class":74,"line":605},29,[161,607,608],{"class":466},"     the chip snaps back instantly, wherever it was. *\u002F\n",[161,610,612,615,617],{"class":74,"line":611},30,[161,613,614],{"class":174},"  .row--keyframes",[161,616,553],{"class":174},[161,618,385],{"class":166},[161,620,622,625,628,630,632,634,636,638,640,642,644,646,648,650,653,656],{"class":74,"line":621},31,[161,623,624],{"class":174},"    animation",[161,626,627],{"class":166},": lift ",[161,629,496],{"class":174},[161,631,499],{"class":296},[161,633,502],{"class":174},[161,635,505],{"class":166},[161,637,508],{"class":174},[161,639,308],{"class":166},[161,641,513],{"class":174},[161,643,308],{"class":166},[161,645,518],{"class":174},[161,647,308],{"class":166},[161,649,513],{"class":174},[161,651,652],{"class":166},") ",[161,654,655],{"class":174},"forwards",[161,657,406],{"class":166},[161,659,661],{"class":74,"line":660},32,[161,662,453],{"class":166},[161,664,666,669,673],{"class":74,"line":665},33,[161,667,668],{"class":296},"  @keyframes",[161,670,672],{"class":671},"soyes"," lift",[161,674,385],{"class":166},[161,676,678,681,683,686,688,690,692,694,696,699,701,703],{"class":74,"line":677},34,[161,679,680],{"class":174},"    to",[161,682,284],{"class":166},[161,684,685],{"class":174},"translate",[161,687,290],{"class":166},[161,689,566],{"class":174},[161,691,569],{"class":174},[161,693,297],{"class":296},[161,695,314],{"class":166},[161,697,698],{"class":174},"background-color",[161,700,290],{"class":166},[161,702,584],{"class":174},[161,704,348],{"class":166},[161,706,708],{"class":74,"line":707},35,[161,709,453],{"class":166},[161,711,713],{"class":74,"line":712},36,[161,714,460],{"emptyLinePlaceholder":459},[161,716,718,721],{"class":74,"line":717},37,[161,719,720],{"class":296},"  @media",[161,722,723],{"class":166}," (prefers-reduced-motion: reduce) {\n",[161,725,727,730,732,734,737,739,741,743],{"class":74,"line":726},38,[161,728,729],{"class":174},"    .row--transition",[161,731,482],{"class":174},[161,733,284],{"class":166},[161,735,736],{"class":174},"transition-duration",[161,738,290],{"class":166},[161,740,513],{"class":174},[161,742,499],{"class":296},[161,744,348],{"class":166},[161,746,748,751,753,755,758,760,762,764,766,768,770],{"class":74,"line":747},39,[161,749,750],{"class":174},"    .row--keyframes",[161,752,553],{"class":174},[161,754,284],{"class":166},[161,756,757],{"class":174},"animation",[161,759,290],{"class":166},[161,761,104],{"class":174},[161,763,314],{"class":166},[161,765,698],{"class":174},[161,767,290],{"class":166},[161,769,584],{"class":174},[161,771,348],{"class":166},[161,773,775],{"class":74,"line":774},40,[161,776,453],{"class":166},[161,778,780,783,785],{"class":74,"line":779},41,[161,781,782],{"class":166},"\u003C\u002F",[161,784,273],{"class":170},[161,786,178],{"class":166},[161,788,790,792,794],{"class":74,"line":789},42,[161,791,782],{"class":166},[161,793,206],{"class":170},[161,795,178],{"class":166},[161,797,799,801,804],{"class":74,"line":798},43,[161,800,184],{"class":166},[161,802,803],{"class":170},"body",[161,805,178],{"class":166},[161,807,809,812,815,818,820,823,826,828,830,832,835,838,840,842,844,846,848,850,852,854,856,858,860,862,864,866,868,871,873],{"class":74,"line":808},44,[161,810,811],{"class":166},"  \u003C",[161,813,814],{"class":170},"div",[161,816,817],{"class":174}," class",[161,819,192],{"class":166},[161,821,822],{"class":195},"\"row row--transition\"",[161,824,825],{"class":166},">\u003C",[161,827,161],{"class":170},[161,829,817],{"class":174},[161,831,192],{"class":166},[161,833,834],{"class":195},"\"chip\"",[161,836,837],{"class":166},">Transition\u003C\u002F",[161,839,161],{"class":170},[161,841,825],{"class":166},[161,843,161],{"class":170},[161,845,817],{"class":174},[161,847,192],{"class":166},[161,849,834],{"class":195},[161,851,837],{"class":166},[161,853,161],{"class":170},[161,855,825],{"class":166},[161,857,161],{"class":170},[161,859,817],{"class":174},[161,861,192],{"class":166},[161,863,834],{"class":195},[161,865,837],{"class":166},[161,867,161],{"class":170},[161,869,870],{"class":166},">\u003C\u002F",[161,872,814],{"class":170},[161,874,178],{"class":166},[161,876,878,880,882,884,886,889,891,893,895,897,899,902,904,906,908,910,912,914,916,918,920,922,924,926,928,930,932,934,936],{"class":74,"line":877},45,[161,879,811],{"class":166},[161,881,814],{"class":170},[161,883,817],{"class":174},[161,885,192],{"class":166},[161,887,888],{"class":195},"\"row row--keyframes\"",[161,890,825],{"class":166},[161,892,161],{"class":170},[161,894,817],{"class":174},[161,896,192],{"class":166},[161,898,834],{"class":195},[161,900,901],{"class":166},">Keyframes\u003C\u002F",[161,903,161],{"class":170},[161,905,825],{"class":166},[161,907,161],{"class":170},[161,909,817],{"class":174},[161,911,192],{"class":166},[161,913,834],{"class":195},[161,915,901],{"class":166},[161,917,161],{"class":170},[161,919,825],{"class":166},[161,921,161],{"class":170},[161,923,817],{"class":174},[161,925,192],{"class":166},[161,927,834],{"class":195},[161,929,901],{"class":166},[161,931,161],{"class":170},[161,933,870],{"class":166},[161,935,814],{"class":170},[161,937,178],{"class":166},[161,939,941,943,945],{"class":74,"line":940},46,[161,942,782],{"class":166},[161,944,803],{"class":170},[161,946,178],{"class":166},[161,948,950,952,954],{"class":74,"line":949},47,[161,951,782],{"class":166},[161,953,155],{"class":170},[161,955,178],{"class":166},[14,957,958,959,962,963,967],{},"The transition row feels fluid under fast pointer movement: each chip rises only as far as it got while hovered and sinks back from that point. The keyframe row stutters: every chip that the pointer leaves mid-lift snaps to the floor, because removing ",[158,960,961],{},":hover"," removes the animation entirely. That single difference is why transitions are the right tool for reversible state changes, and keyframes for one-way or looping effects, a distinction developed further in ",[18,964,966],{"href":965},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002F","Keyframe Animation Patterns",".",[29,969,971],{"id":970},"the-key-technique-reversal-shortening","The key technique: reversal shortening",[14,973,974,975,979],{},"Starting from the current value solves the jump. It does not, on its own, solve the timing: a 400-millisecond reverse from a point only 10% along the path would crawl back over 400 milliseconds, feeling sluggish. The transition model handles this with ",[976,977,978],"em",{},"reversal shortening",". When a new transition returns a property to the value it was transitioning from — a reversal — the browser scales the new duration by how far the interrupted transition had progressed.",[49,981,56,984,56,987,56,990,56,993,56,999,56,1006,56,1011,56,1015,56,1018,56,1023,56,1027,56,1031,56,1036],{"viewBox":982,"role":52,"ariaLabel":983,"xmlns":54,"style":55},"0 0 720 280","Bars showing reverse durations for interruptions at 25, 50 and 90 percent progress of a 400 millisecond transition",[58,985,986],{},"Reverse duration follows progress",[62,988,989],{},"An interruption at 25 percent progress reverses in about 100 milliseconds, at 50 percent in about 200 milliseconds, and at 90 percent in about 360 milliseconds. The reverse always takes roughly as long as the forward motion had run.",[66,991,992],{"textAnchor":68,"x":69,"y":70,"style":71},"400ms transition, reversed at different points",[66,994,998],{"textAnchor":122,"x":995,"y":996,"style":997},"40","84","text-anchor:start;fill:currentColor;font:12px ui-monospace,monospace","at 25%",[1000,1001],"rect",{"x":1002,"y":1003,"width":1004,"height":1005,"rx":106,"fill":105,"opacity":372},"140","66","120","28",[66,1007,1010],{"textAnchor":122,"x":1008,"y":1009,"style":137},"270","85","reverse ≈ 100ms",[66,1012,1014],{"textAnchor":122,"x":995,"y":1013,"style":997},"144","at 50%",[1000,1016],{"x":1002,"y":1017,"width":77,"height":1005,"rx":106,"fill":105,"opacity":372},"126",[66,1019,1022],{"textAnchor":122,"x":1020,"y":1021,"style":137},"390","145","reverse ≈ 200ms",[66,1024,1026],{"textAnchor":122,"x":995,"y":1025,"style":997},"204","at 90%",[1000,1028],{"x":1002,"y":1029,"width":1030,"height":1005,"rx":106,"fill":105,"opacity":372},"186","432",[66,1032,1035],{"textAnchor":122,"x":1033,"y":1034,"style":137},"582","205","≈ 360ms",[66,1037,1040],{"textAnchor":68,"x":69,"y":1038,"style":1039},"258","text-anchor:middle;fill:currentColor;font:12px sans-serif","A brief hover produces a brief return, never a slow crawl back.",[14,1042,1043,1044,1047],{},"The shortening is proportional to ",[976,1045,1046],{},"output progress",", which accounts for easing: with a strong ease-out, 100 milliseconds may already be 40% of the visible travel, and the reverse is scaled accordingly. The practical upshot is that you can choose a comfortable forward duration without worrying that quick interactions will feel slow on the way back.",[14,1049,1050],{},"Shortening only applies to a true reversal — returning to the previous start value. If a third state intervenes (a hover, then a click that sets a different value), the new transition runs for its full declared duration from the current value to the new target, which is also correct: it is a new journey, not a return.",[29,1052,1054],{"id":1053},"how-interruption-interacts-with-per-state-timing","How interruption interacts with per-state timing",[14,1056,1057,1058,1061,1062,1066],{},"Because the transition values of the ",[976,1059,1060],{},"entered"," state apply, an interruption can switch curves mid-flight. A hover with a slow, bouncy entry and a quick, plain exit — the asymmetry recommended in ",[18,1063,1065],{"href":1064},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fentry-vs-exit-easing\u002F","Entry vs Exit Easing"," — reverses with the exit curve from the current point when interrupted. That is usually exactly what you want. Two edge cases deserve awareness:",[1068,1069,1070,1077],"ul",{},[1071,1072,1073,1076],"li",{},[40,1074,1075],{},"Overshooting curves."," If the entry curve overshoots and the pointer leaves at the peak, the reverse starts from beyond the resting position. That looks natural for springs and odd for large overshoots.",[1071,1078,1079,1082,1083,1086],{},[40,1080,1081],{},"Delays."," A ",[158,1084,1085],{},"transition-delay"," on the entered state applies to the interruption too. A hover-intent delay on the open state means a quick re-entry waits again before resuming — correct for menus, surprising for simple hover lifts.",[29,1088,1090],{"id":1089},"things-that-break-interruption","Things that break interruption",[14,1092,1093],{},"Transitions interrupt cleanly only while the browser can see a continuous change in one property's computed value. Several common patterns quietly break that.",[14,1095,1096,1103,1104,1107,1108,1111],{},[40,1097,1098,1099,1102],{},"Changing ",[158,1100,1101],{},"transition"," on the fly with a class that also removes the property."," If a script swaps a class that sets both the target value and ",[158,1105,1106],{},"transition: none"," — often done to \"reset\" an element before animating it — the interruption becomes a jump. Separate the reset from the state change, or use ",[158,1109,1110],{},"@starting-style"," for first-frame values.",[14,1113,1114,1117,1118,1121,1122,1125,1126,1129,1130,308,1132,1135,1136,1139],{},[40,1115,1116],{},"Animating between different value types."," A transition from ",[158,1119,1120],{},"height: 0"," to ",[158,1123,1124],{},"height: auto"," has no interpolable path without ",[158,1127,1128],{},"interpolate-size",", so an interruption jumps. The same applies to ",[158,1131,329],{},[158,1133,1134],{},"background-image"," and other discrete properties unless ",[158,1137,1138],{},"allow-discrete"," or a registered custom property provides a path.",[14,1141,1142,1145],{},[40,1143,1144],{},"Replacing the element."," Frameworks that re-render a list by replacing DOM nodes destroy the old element mid-transition and insert a new one at its resting state. Keying list items stably so the same node persists is what lets its transition continue.",[14,1147,1148,1151,1152,1155,1156,1158,1159,1162],{},[40,1149,1150],{},"Mixing transitions and animations on one property."," A running keyframe animation overrides the transitioned value for as long as it runs. If both target ",[158,1153,1154],{},"transform",", the transition's interruption behaviour is invisible while the animation plays and snaps when it ends. Give each mechanism its own property — ",[158,1157,685],{}," for the transition, ",[158,1160,1161],{},"rotate"," for the animation — so they compose instead of competing.",[14,1164,1165,1168,1169,967],{},[40,1166,1167],{},"Very long durations."," Interruption and shortening work at any duration, but a 1.5-second transition interrupted frequently still feels laggy, because every short hover produces motion that outlasts the user's attention. Micro-interactions should stay under about 300 milliseconds, as argued in ",[18,1170,1172],{"href":1171},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fchoosing-animation-durations\u002F","Choosing Animation Durations",[29,1174,1176],{"id":1175},"variation-making-a-keyframe-animation-interruptible","Variation: making a keyframe animation interruptible",[14,1178,1179],{},"Sometimes a keyframe animation genuinely is the right tool — for a multi-step effect that a transition cannot express — but it must still reverse gracefully. One approach keeps the animation applied and pauses or reverses it rather than removing it.",[151,1181,1185],{"className":1182,"code":1183,"language":1184,"meta":156,"style":156},"language-css shiki shiki-themes github-light-high-contrast github-dark-high-contrast",".badge {\n  animation: pop 500ms cubic-bezier(0.34, 1.56, 0.64, 1) both paused;\n}\n\n\u002F* Run forward while hovered; hold wherever it is when not. *\u002F\n.badge:hover {\n  animation-play-state: running;\n}\n","css",[158,1186,1187,1194,1238,1243,1247,1252,1259,1271],{"__ignoreMap":156},[161,1188,1189,1192],{"class":74,"line":163},[161,1190,1191],{"class":174},".badge",[161,1193,385],{"class":166},[161,1195,1196,1199,1202,1205,1207,1209,1211,1214,1216,1219,1221,1224,1226,1228,1230,1233,1236],{"class":74,"line":181},[161,1197,1198],{"class":174},"  animation",[161,1200,1201],{"class":166},": pop ",[161,1203,1204],{"class":174},"500",[161,1206,499],{"class":296},[161,1208,502],{"class":174},[161,1210,505],{"class":166},[161,1212,1213],{"class":174},"0.34",[161,1215,308],{"class":166},[161,1217,1218],{"class":174},"1.56",[161,1220,308],{"class":166},[161,1222,1223],{"class":174},"0.64",[161,1225,308],{"class":166},[161,1227,513],{"class":174},[161,1229,652],{"class":166},[161,1231,1232],{"class":174},"both",[161,1234,1235],{"class":174}," paused",[161,1237,406],{"class":166},[161,1239,1240],{"class":74,"line":201},[161,1241,1242],{"class":166},"}\n",[161,1244,1245],{"class":74,"line":211},[161,1246,460],{"emptyLinePlaceholder":459},[161,1248,1249],{"class":74,"line":229},[161,1250,1251],{"class":466},"\u002F* Run forward while hovered; hold wherever it is when not. *\u002F\n",[161,1253,1254,1257],{"class":74,"line":254},[161,1255,1256],{"class":174},".badge:hover",[161,1258,385],{"class":166},[161,1260,1261,1264,1266,1269],{"class":74,"line":268},[161,1262,1263],{"class":174},"  animation-play-state",[161,1265,290],{"class":166},[161,1267,1268],{"class":174},"running",[161,1270,406],{"class":166},[161,1272,1273],{"class":74,"line":278},[161,1274,1242],{"class":166},[14,1276,1277,1278,1281,1282,1285,1286,1290],{},"This holds the effect in place instead of snapping when the pointer leaves, but it cannot run ",[976,1279,1280],{},"backwards"," on un-hover. For true reversal of a keyframe effect, the Web Animations API's ",[158,1283,1284],{},"animation.reverse()"," is needed, one of the cases covered in ",[18,1287,1289],{"href":1288},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api\u002Fwhen-to-use-javascript-animation\u002F","When to Use JavaScript Animation",". For most micro-interactions, rewriting the effect as a transition — possibly on several properties with different delays — is simpler and interrupts correctly for free.",[29,1292,1294],{"id":1293},"browser-support","Browser support",[14,1296,1297,1298,1300,1301,1303,1304,1307],{},"CSS transitions, including starting from the current value on interruption and reversal shortening, behave consistently in all current browsers; the ",[158,1299,1101],{}," shorthand dates from Chrome 26, Edge 12, Firefox 16 and Safari 9. The standalone ",[158,1302,685],{}," property is supported in Chrome and Edge 104+, Firefox 72+ and Safari 14.1+. ",[158,1305,1306],{},"animation-play-state"," is supported in Chrome 43+, Edge 12+, Firefox 16+ and Safari 9+.",[29,1309,1311],{"id":1310},"faq","FAQ",[14,1313,1314,1317],{},[40,1315,1316],{},"What happens if the user un-hovers halfway through a hover transition?","\nThe browser starts a new transition from the element's current, partly transitioned value back toward the original value. It does not jump to the end or restart from the beginning, so the element reverses smoothly from where it was.",[14,1319,1320,1323],{},[40,1321,1322],{},"What is reversal shortening?","\nWhen a transition is reversed before it finishes, the browser shortens the reverse transition in proportion to how far the original had progressed. A 400ms transition interrupted after 100ms reverses in about 100ms rather than a full 400ms, so quick hovers produce quick returns.",[14,1325,1326,1329],{},[40,1327,1328],{},"Why do my keyframe animations jump when interrupted?","\nRemoving the class or state that applies an animation removes the animation entirely, so the element snaps to its unanimated style. Keyframe animations have no built-in reverse from the current point. Use transitions for state changes that can be interrupted.",[14,1331,1332,1335],{},[40,1333,1334],{},"Can different curves apply to each direction of an interrupted transition?","\nYes. The transition values of the state being entered apply. If the base state and the hover state declare different curves and durations, an interruption switches to the curve of whichever state is now being entered, starting from the current value.",[29,1337,1339],{"id":1338},"related","Related",[1068,1341,1342,1347,1354,1361],{},[1071,1343,1344,1346],{},[18,1345,21],{"href":20}," — the parent guide.",[1071,1348,1349,1353],{},[18,1350,1352],{"href":1351},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fcss-transition-timing-functions\u002F","CSS Transition Timing Functions"," — the curves being reversed.",[1071,1355,1356,1360],{},[18,1357,1359],{"href":1358},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransition-shorthand-and-multiple-properties\u002F","Transition Shorthand and Multiple Properties"," — declaring per-property timing.",[1071,1362,1363,1367],{},[18,1364,1366],{"href":1365},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fcontainer-query-hover-affordances\u002F","Container Query Hover Affordances"," — hover effects that must interrupt cleanly.",[273,1369,1370],{},"html pre.shiki code .suds8, html code.shiki .suds8{--shiki-default:#0E1116;--shiki-dark:#F0F3F6}html pre.shiki code .sne4z, html code.shiki .sne4z{--shiki-default:#024C1A;--shiki-dark:#72F088}html pre.shiki code .s-5SL, html code.shiki .s-5SL{--shiki-default:#023B95;--shiki-dark:#91CBFF}html pre.shiki code .sT6z2, html code.shiki .sT6z2{--shiki-default:#032563;--shiki-dark:#ADDCFF}html pre.shiki code .sHUrx, html code.shiki .sHUrx{--shiki-default:#A0111F;--shiki-dark:#FF9492}html pre.shiki code .sLBg1, html code.shiki .sLBg1{--shiki-default:#66707B;--shiki-dark:#BDC4CC}html pre.shiki code .soyes, html code.shiki .soyes{--shiki-default:#702C00;--shiki-dark:#FFB757}html .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":156,"searchDepth":181,"depth":181,"links":1372},[1373,1374,1375,1376,1377,1378,1379,1380,1381],{"id":31,"depth":181,"text":32},{"id":141,"depth":181,"text":142},{"id":970,"depth":181,"text":971},{"id":1053,"depth":181,"text":1054},{"id":1089,"depth":181,"text":1090},{"id":1175,"depth":181,"text":1176},{"id":1293,"depth":181,"text":1294},{"id":1310,"depth":181,"text":1311},{"id":1338,"depth":181,"text":1339},"What happens when a transition is interrupted mid-flight: reversing from the current value, reversal shortening, asymmetric timing, and why keyframes cannot.","md",{"pageTitle":1385,"datePublished":1386,"dateModified":1386,"faq":1387},"Interrupted and Reversing CSS Transitions","2026-09-18",[1388,1390,1392,1394],{"q":1316,"a":1389},"The browser starts a new transition from the element's current, partly transitioned value back toward the original value. It does not jump to the end or restart from the beginning, so the element reverses smoothly from where it was.",{"q":1322,"a":1391},"When a transition is reversed before it finishes, the browser shortens the reverse transition in proportion to how far the original had progressed. A 400ms transition interrupted after 100ms reverses in about 100ms rather than a full 400ms, so quick hovers produce quick returns.",{"q":1328,"a":1393},"Removing the class or state that applies an animation removes the animation entirely, so the element snaps to its unanimated style. Keyframe animations have no built-in reverse from the current point. Use transitions for state changes that can be interrupted.",{"q":1334,"a":1395},"Yes. The transition values of the state being entered apply. If the base state and the hover state declare different curves and durations, an interruption switches to the curve of whichever state is now being entered, starting from the current value.","\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Finterrupted-and-reversing-transitions",{"title":5,"description":1382},"css-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Finterrupted-and-reversing-transitions\u002Findex","lO4GoMoonR5AAai4N2QfDrpmVP0yWRkqywotxuM8ph0",[1401,1404,1407,1410,1413,1416,1419,1422,1425,1428,1431,1434,1437,1440,1443,1446,1449,1452,1455,1458,1461,1464,1467,1470,1473,1476,1479,1482,1485,1488,1491,1494,1497,1500,1503,1506,1509,1512,1515,1516,1519,1522,1525,1528,1531,1534,1537,1540,1543,1546,1549,1552,1555,1558,1561,1564,1567,1570,1573,1576,1579,1582,1585,1588,1591,1594,1597,1600,1603,1606,1609,1612,1615,1618,1621,1624,1627,1630,1633,1636,1639,1642,1645,1648,1651,1654,1657,1660,1663,1666,1669,1672,1675,1678,1680,1683,1686,1689,1692,1695,1698,1701,1704,1707,1710,1713,1716,1719,1722,1725,1728,1731,1734,1737,1740,1743,1746,1749,1752,1755,1758,1761,1764,1767,1770,1773,1776,1779,1782,1785,1788,1791,1794,1797,1800,1803,1806,1809,1812,1815,1818,1821,1824,1827,1830,1833,1836,1839,1842,1845,1848,1851,1854,1857,1860,1863,1866,1869,1872,1875,1878,1881,1884,1887,1890,1893,1896,1899,1902,1905,1908,1911,1914,1917,1920,1923,1926,1929,1932,1935,1938,1941,1944,1947,1950,1953,1956],{"path":1402,"title":1403},"\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":1405,"title":1406},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fflashing-content-and-seizure-thresholds","Flashing Content and Seizure Thresholds",{"path":1408,"title":1409},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fforced-colors-mode-and-animations","Forced Colors Mode and Animations",{"path":1411,"title":1412},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations","Accessibility in CSS Animations: Patterns, Specs & Best Practices",{"path":1414,"title":1415},"\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":1417,"title":1418},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fprefers-reduced-motion-recipes","prefers-reduced-motion Recipes: A Reduction for Every Common Effect",{"path":1420,"title":1421},"\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":1423,"title":1424},"\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":1426,"title":1427},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fvestibular-safe-animation-patterns","Vestibular-Safe Animation Patterns: Why Some Motion Makes People Sick",{"path":1429,"title":1430},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fwcag-motion-success-criteria","WCAG Motion Success Criteria: What Each One Actually Requires",{"path":1432,"title":1433},"\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":1435,"title":1436},"\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":1438,"title":1439},"\u002Fcss-only-micro-interactions-animations\u002Fclip-path-and-mask-animations","Clip-Path & Mask Animations: Animating Visibility Instead of Position",{"path":1441,"title":1442},"\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":1444,"title":1445},"\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":1447,"title":1448},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions\u002Fanimating-gradients","Animating CSS Gradients: Smooth Colour Motion Without Jumps",{"path":1450,"title":1451},"\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":1453,"title":1454},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions","Color & Theme Transitions: Colour as Part of the Motion System",{"path":1456,"title":1457},"\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":1459,"title":1460},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions\u002Fsmooth-theme-switching-transitions","Smooth Theme Switching: Crossfades, Circular Reveals and No Flash",{"path":1462,"title":1463},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fcontainer-query-hover-affordances","Container Query Hover Affordances: When Narrow Means Persistent, Not Hidden",{"path":1465,"title":1466},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion","Container-Aware Motion: Animation Sized by the Space a Component Actually Has",{"path":1468,"title":1469},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Flayout-change-animations-at-container-breakpoints","Animating Changes at Container Breakpoints",{"path":1471,"title":1472},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fmotion-driven-by-container-style-queries","Motion Driven by Container Style Queries",{"path":1474,"title":1475},"\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":1477,"title":1478},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fsuppressing-motion-in-small-containers","Suppressing Motion in Small Containers: Deliberately Animating Nothing",{"path":1480,"title":1481},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api\u002Fcontrolling-css-animations-from-javascript","Controlling CSS Animations From JavaScript",{"path":1483,"title":1484},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api","CSS Animation vs the Web Animations API: A Decision Guide",{"path":1486,"title":1487},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api\u002Fwaapi-vs-css-for-interruptible-ui","Interruptible UI: CSS Transitions vs WAAPI",{"path":1489,"title":1490},"\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":1492,"title":1493},"\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":1495,"title":1496},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Fcustom-property-fallbacks-and-invalid-values","Custom Property Fallbacks and Invalid Values",{"path":1498,"title":1499},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Ffluid-spacing-tokens-driving-transition-durations","Fluid Spacing Tokens That Drive Transition Durations",{"path":1501,"title":1502},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture","CSS Custom Properties Architecture: Scalable Design Systems & Dynamic UI",{"path":1504,"title":1505},"\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":1507,"title":1508},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Fscoping-custom-properties-to-components","Scoping Custom Properties to Components",{"path":1510,"title":1511},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fcss-transition-timing-functions","CSS Transition Timing Functions: ease, cubic-bezier(), steps() and linear()",{"path":1513,"title":1514},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals","CSS Transition Fundamentals: Architecture, Performance & Patterns",{"path":1396,"title":5},{"path":1517,"title":1518},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fstarting-style-entry-animations","@starting-style: Animating an Element's Very First Style Change",{"path":1520,"title":1521},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransition-delay-choreography","Choreographing Motion With transition-delay",{"path":1523,"title":1524},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransition-shorthand-and-multiple-properties","The transition Shorthand and Multiple Properties",{"path":1526,"title":1527},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransitioning-display-with-allow-discrete","Transitioning display with transition-behavior: allow-discrete and @starting-style",{"path":1529,"title":1530},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Fanimating-dialog-open-and-close","Animating \u003Cdialog> Open and Close: Both Directions, No Library",{"path":1532,"title":1533},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Fbackdrop-animations","Animating ::backdrop: Fades and Blurs Behind Dialogs and Popovers",{"path":1535,"title":1536},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations","Dialog & Popover Animations: Motion for the Top Layer",{"path":1538,"title":1539},"\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":1541,"title":1542},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Fpopover-entry-and-exit-transitions","Popover Menus That Animate From Their Anchor",{"path":1544,"title":1545},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fchoosing-animation-durations","Choosing Animation Durations: How Long Motion Should Last",{"path":1547,"title":1548},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fcubic-bezier-overshoot-and-anticipation","Overshoot and Anticipation With cubic-bezier(): Motion With Character",{"path":1550,"title":1551},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fentry-vs-exit-easing","Entry vs Exit Easing: Different Curves for Arriving and Leaving",{"path":1553,"title":1554},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design","Easing & Motion Design: Making CSS Motion Feel Intentional",{"path":1556,"title":1557},"\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":1559,"title":1560},"\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":1562,"title":1563},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Faccessible-css-only-tooltips","Accessible CSS-Only Tooltips and Hover Cards With  and ",{"path":1565,"title":1566},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Fbutton-press-and-active-states","Button Press and  States",{"path":1568,"title":1569},"\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":1571,"title":1572},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Ffocus-within-form-patterns"," Form Patterns: Styling a Group From the Field Inside It",{"path":1574,"title":1575},"\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":1577,"title":1578},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design","Hover & Focus State Design: Spec-Compliant Patterns for Modern UIs",{"path":1580,"title":1581},"\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":1583,"title":1584},"\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":1586,"title":1587},"\u002Fcss-only-micro-interactions-animations","CSS-Only Micro-Interactions & Animations: Architecture, Performance & Implementation",{"path":1589,"title":1590},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fanimation-composition-and-stacking","Stacking Animations With animation-composition",{"path":1592,"title":1593},"\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":1595,"title":1596},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcontainer-query-triggered-keyframe-animations","Container-Query-Triggered Keyframe Animations: Animate Differently per Available Space",{"path":1598,"title":1599},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcss-only-accordions-and-disclosure","CSS-Only Accordions and Disclosure Widgets with details and summary",{"path":1601,"title":1602},"\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":1604,"title":1605},"\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":1607,"title":1608},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns","Keyframe Animation Patterns: Spec-Compliant Architectures for Modern UIs",{"path":1610,"title":1611},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fmulti-step-keyframes-and-per-keyframe-easing","Multi-Step Keyframes and Per-Keyframe Easing",{"path":1613,"title":1614},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fstaggered-list-animations-with-custom-properties","Staggered List Animations Using --i Index Custom Properties",{"path":1616,"title":1617},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fanimating-box-shadow-and-filters-cheaply","Animating box-shadow and Filters Cheaply",{"path":1619,"title":1620},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fcontain-property-for-animation-performance","The contain Property for Animation Performance",{"path":1622,"title":1623},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fcss-triggers-layout-paint-composite","Layout, Paint and Composite: What Triggers What",{"path":1625,"title":1626},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration","Performance & GPU Acceleration in CSS: A Developer’s Blueprint",{"path":1628,"title":1629},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Foptimizing-css-animations-for-60fps","Optimizing CSS Animations for 60fps: Budgeting the Frame",{"path":1631,"title":1632},"\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":1634,"title":1635},"\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":1637,"title":1638},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations","Scroll-Driven Animations: Binding Motion to Scroll Position in Pure CSS",{"path":1640,"title":1641},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-driven-animation-fallbacks","Shipping Scroll-Driven Animations Without Breaking Anything",{"path":1643,"title":1644},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-driven-parallax-effects","Scroll-Driven Parallax Effects in CSS",{"path":1646,"title":1647},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-progress-bar-without-javascript","A Reading Progress Bar Driven by scroll(root)",{"path":1649,"title":1650},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-triggered-reveal-animations","Reveal-on-Scroll with view() and animation-range",{"path":1652,"title":1653},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Ftimeline-scope-for-cross-element-animations","timeline-scope for Cross-Element Animations",{"path":1655,"title":1656},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fview-timeline-and-animation-range","View Timelines and animation-range",{"path":1658,"title":1659},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fcross-document-view-transitions","Cross-Document View Transitions",{"path":1661,"title":1662},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers","View Transitions for CSS Developers: the Pseudo-Element Tree, Snapshots, and Named Elements",{"path":1664,"title":1665},"\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":1667,"title":1668},"\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":1670,"title":1671},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transition-types-and-classes","View Transition Types and Classes",{"path":1673,"title":1674},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transitions-for-list-reordering","View Transitions for List Reordering",{"path":1676,"title":1677},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transitions-with-reduced-motion","Honouring prefers-reduced-motion in View Transitions",{"path":300,"title":1679},"Modern CSS Layouts & Micro-Interactions",{"path":1681,"title":1682},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-positioned-tooltips","Anchor-Positioned Tooltips: Tethering, Flipping, and Getting the Semantics Right",{"path":1684,"title":1685},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-positioning-fallbacks","Anchor Positioning Fallbacks: A Graceful Floor for Older Browser Versions",{"path":1687,"title":1688},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-size-for-matching-widths","anchor-size(): Overlays That Match Their Trigger's Size",{"path":1690,"title":1691},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays","CSS Anchor Positioning and Overlays: Tethering Elements Without JavaScript",{"path":1693,"title":1694},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fpopover-attribute-and-css-styling","The popover Attribute: Top-Layer Overlays With No JavaScript",{"path":1696,"title":1697},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fpopover-light-dismiss-and-stacking","Popover Light Dismiss, Nesting and Stacking",{"path":1699,"title":1700},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fposition-area-grid-explained","position-area: The Anchor Placement Grid",{"path":1702,"title":1703},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fcontainer-query-polyfill-tradeoffs","Container Query Polyfills: What They Cost and When to Skip Them",{"path":1705,"title":1706},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Ffeature-detection-with-supports","Feature Detection with @supports: Syntax, Semantics, and the Traps",{"path":1708,"title":1709},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fhandling-container-query-fallbacks-for-older-browsers","Handling Container Query Fallbacks for Older Browsers",{"path":1711,"title":1712},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks","Container Query Fallbacks: Spec-Compliant CSS Strategies for Legacy Browsers",{"path":1714,"title":1715},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fintrinsic-layout-fallbacks-without-queries","Intrinsic Layout Fallbacks: Baselines That Adapt Without Any Query",{"path":1717,"title":1718},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Ftesting-fallbacks-without-old-browsers","Testing CSS Fallbacks Without an Old Browser",{"path":1720,"title":1721},"\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":1723,"title":1724},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-query-range-and-logic-operators","Container Query Range Syntax and Logic Operators",{"path":1726,"title":1727},"\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":1729,"title":1730},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-type-size-vs-inline-size","Choosing container-type: inline-size, size, or normal",{"path":1732,"title":1733},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-vs-media-queries-comparison","Container vs Media Queries: Choosing the Right Reference Box",{"path":1735,"title":1736},"\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":1738,"title":1739},"\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":1741,"title":1742},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics","Container Query Syntax Basics",{"path":1744,"title":1745},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fnesting-and-naming-container-queries","Nesting and Naming Container Queries: Targeting the Right Ancestor",{"path":1747,"title":1748},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fauto-fit-minmax-responsive-grids","Responsive Grids with repeat(auto-fit, minmax())",{"path":1750,"title":1751},"\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":1753,"title":1754},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fgrid-auto-flow-dense-packing","grid-auto-flow: dense for Packed Layouts",{"path":1756,"title":1757},"\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":1759,"title":1760},"\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":1762,"title":1763},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts","CSS Grid and Subgrid Layouts for Responsive Interfaces",{"path":1765,"title":1766},"\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":1768,"title":1769},"\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":1771,"title":1772},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fsubgrid-vs-nested-grid","Subgrid vs an Independently Nested Grid",{"path":1774,"title":1775},"\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":1777,"title":1778},"\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":1780,"title":1781},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflex-grow-and-flex-shrink-explained","flex-grow and flex-shrink Explained",{"path":1783,"title":1784},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflex-wrap-intrinsic-responsive-rows","Breakpoint-Free Responsive Rows With flex-wrap and flex-basis",{"path":1786,"title":1787},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflexbox-gap-and-spacing","Flexbox gap vs Margins: Spacing Items Without Edge Hacks",{"path":1789,"title":1790},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns","Flexbox Layout Patterns: One-Dimensional Layout for Real Components",{"path":1792,"title":1793},"\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":1795,"title":1796},"\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":1798,"title":1799},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Fdebugging-clamp-values","Debugging clamp(): Values That Are Ignored, Stuck or Never Fluid",{"path":1801,"title":1802},"\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":1804,"title":1805},"\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":1807,"title":1808},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-type-accessibility-and-zoom","Fluid Type, Accessibility and Zoom: The vw-Only Trap",{"path":1810,"title":1811},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-typography-without-javascript","Fluid Typography Without JavaScript: A Precision CSS Reference",{"path":1813,"title":1814},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp","Fluid Typography with clamp(): A Practical Guide for Modern CSS",{"path":1816,"title":1817},"\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":1819,"title":1820},"\u002Fmastering-container-queries-responsive-layouts","Mastering Container Queries & Responsive Layouts",{"path":1822,"title":1823},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Faspect-ratio-for-responsive-media","Using aspect-ratio for Responsive Media and Preventing Layout Shift",{"path":1825,"title":1826},"\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":1828,"title":1829},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques","Intrinsic Sizing Techniques: Modern CSS Layouts for Responsive UI",{"path":1831,"title":1832},"\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":1834,"title":1835},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fmin-max-fit-content-explained","min-content, max-content, and fit-content() Explained",{"path":1837,"title":1838},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fobject-fit-and-object-position","object-fit and object-position: Images That Fit Any Box",{"path":1840,"title":1841},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fpreventing-flex-and-grid-overflow","The min-width: auto Trap in Flex and Grid Layouts",{"path":1843,"title":1844},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-for-reset-and-tokens","Cascade Layers for Reset and Design Tokens",{"path":1846,"title":1847},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-vs-specificity-hacks","Cascade Layers vs Specificity Hacks: Ordering Instead of Escalating",{"path":1849,"title":1850},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcss-scope-for-component-styles","@scope for Component Styles: Short Selectors That Cannot Leak",{"path":1852,"title":1853},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies","Modern CSS Reset Strategies: A Spec-Compliant Foundation",{"path":1855,"title":1856},"\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":1858,"title":1859},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fwriting-a-minimal-modern-reset","Writing a Minimal Modern CSS Reset: Every Line Justified",{"path":1861,"title":1862},"\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":1864,"title":1865},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has\u002Fempty-and-loading-states-with-has","Empty and Loading States With ()",{"path":1867,"title":1868},"\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":1870,"title":1871},"\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":1873,"title":1874},"\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":1876,"title":1877},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has","Parent-Aware Layouts With :has(): Letting Containers React to Their Contents",{"path":1879,"title":1880},"\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":1882,"title":1883},"\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":1885,"title":1886},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fcontainer-query-data-tables","Container Query Data Tables: Reflowing Tables to Cards",{"path":1888,"title":1889},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fcontainer-query-sidebar-layouts","Container Query Sidebar Layouts That Travel Between Contexts",{"path":1891,"title":1892},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns","Responsive Component Patterns: Architecture & Implementation",{"path":1894,"title":1895},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-forms-with-container-queries","Responsive Forms with Container Queries: Reflow Without Losing the Wiring",{"path":1897,"title":1898},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-hero-sections-with-container-queries","Responsive Hero Sections With Container Queries",{"path":1900,"title":1901},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-navigation-without-media-queries","Responsive Navigation Without Media Queries Using Container Queries",{"path":1903,"title":1904},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-pricing-tables","Responsive Pricing Tables: Aligned Features, a Clear Recommendation, Any Width",{"path":1906,"title":1907},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Ftabs-that-become-accordions","Tabs That Become an Accordion: One Component, Two Layouts",{"path":1909,"title":1910},"\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts\u002Fcss-only-carousel-with-scroll-snap","A CSS-Only Carousel With Scroll Snap",{"path":1912,"title":1913},"\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":1915,"title":1916},"\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts","Scroll Snap & Overflow Layouts: Designing Components That Scroll on Purpose",{"path":1918,"title":1919},"\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":1921,"title":1922},"\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":1924,"title":1925},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fcombining-size-and-style-queries","Combining Size and Style Container Queries",{"path":1927,"title":1928},"\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":1930,"title":1931},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state","Style Queries and Container State: Token-Driven Component Variants",{"path":1933,"title":1934},"\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":1936,"title":1937},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fstyle-query-component-variants","Component Variants With Style Queries: One Token, Many Looks",{"path":1939,"title":1940},"\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":1942,"title":1943},"\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":1945,"title":1946},"\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":1948,"title":1949},"\u002Fmastering-container-queries-responsive-layouts\u002Fviewport-units-and-mobile-layout","Viewport Units & Mobile Layout: Designing for the Screen You Actually Get",{"path":1951,"title":1952},"\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":1954,"title":1955},"\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":1957,"title":1958},"\u002Fmastering-container-queries-responsive-layouts\u002Fviewport-units-and-mobile-layout\u002Fvirtual-keyboard-and-interactive-widget","Layouts That Survive the Virtual Keyboard",{"title":1960,"caption":1961,"height":1962,"html":1963,"css":1964},"Transition versus keyframes when a hover is interrupted","Sweep the pointer quickly across both rows: the transition chips sink back from wherever they reached; the keyframe chips snap to the floor.",200,"\n\u003Cdiv class=\"row row--transition\">\u003Cspan class=\"chip\">Transition\u003C\u002Fspan>\u003Cspan class=\"chip\">Transition\u003C\u002Fspan>\u003Cspan class=\"chip\">Transition\u003C\u002Fspan>\u003C\u002Fdiv>\n\u003Cdiv class=\"row row--keyframes\">\u003Cspan class=\"chip\">Keyframes\u003C\u002Fspan>\u003Cspan class=\"chip\">Keyframes\u003C\u002Fspan>\u003Cspan class=\"chip\">Keyframes\u003C\u002Fspan>\u003C\u002Fdiv>","\nbody { display: grid; gap: 1.5rem; place-content: center; }\n.row { display: flex; gap: 0.5rem; }\n.chip { padding: 0.8rem 1rem; border-radius: 8px; background: #e0e7ff; color: #1e1b4b; }\n.row--transition .chip { transition: translate 400ms cubic-bezier(0.22, 1, 0.36, 1), background-color 400ms ease; }\n.row--transition .chip:hover { translate: 0 -10px; background-color: #a5b4fc; }\n.row--keyframes .chip:hover { animation: lift 400ms cubic-bezier(0.22, 1, 0.36, 1) forwards; }\n@keyframes lift { to { translate: 0 -10px; background-color: #a5b4fc; } }\n@media (prefers-reduced-motion: reduce) {\n  .row--transition .chip { transition-duration: 1ms; }\n  .row--keyframes .chip:hover { animation: none; background-color: #a5b4fc; }\n}",1789717748181]