[{"data":1,"prerenderedAt":3281},["ShallowReactive",2],{"page-\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design":3,"content-all-pages":2715,"live-demo:easing-segmented-control":3275},{"id":4,"title":5,"body":6,"description":2694,"extension":2695,"meta":2696,"navigation":1522,"path":2711,"seo":2712,"stem":2713,"__hash__":2714},"content\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Findex.md","Easing & Motion Design: Making CSS Motion Feel Intentional",{"type":7,"value":8,"toc":2671},"minimark",[9,13,28,34,64,67,72,95,221,249,254,328,343,347,362,379,382,384,388,531,537,539,543,547,701,705,793,797,933,937,1016,1020,1111,1114,1116,1120,1123,1127,1358,2106,2109,2111,2115,2118,2124,2134,2140,2146,2152,2156,2174,2184,2196,2206,2216,2218,2222,2250,2256,2262,2268,2274,2276,2280,2332,2334,2338,2457,2469,2471,2475,2564,2566,2570,2576,2582,2607,2616,2622,2626,2667],[10,11,5],"h1",{"id":12},"easing-motion-design-making-css-motion-feel-intentional",[14,15,16,17,21,22,27],"p",{},"The mechanics of CSS animation are straightforward: pick properties, set a duration, choose a timing function. What separates motion that feels polished from motion that merely moves is the ",[18,19,20],"em",{},"design"," of those choices — how curves and durations relate to one another, which moments deserve emphasis, and how the system behaves when a user asks for less motion. This guide, part of ",[23,24,26],"a",{"href":25},"\u002Fcss-only-micro-interactions-animations\u002F","CSS-Only Micro-Interactions & Animations",", treats easing and timing as a design system: the vocabulary of curves, how they map onto intent, how to encode them as tokens, and how to apply them consistently across components.",[14,29,30],{},[31,32,33],"strong",{},"Prerequisites — this guide assumes you can already:",[35,36,37,46,54,57],"ul",{},[38,39,40,41,45],"li",{},"Write CSS transitions and keyframe animations (see ",[23,42,44],{"href":43},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002F","CSS Transition Fundamentals",").",[38,47,48,49,53],{},"Read a ",[50,51,52],"code",{},"cubic-bezier()"," value as two control points.",[38,55,56],{},"Use custom properties for design tokens.",[38,58,59,60,63],{},"Handle ",[50,61,62],{},"prefers-reduced-motion"," in a media query.",[65,66],"hr",{},[68,69,71],"h2",{"id":70},"the-core-concept-timing-functions-map-time-to-progress","The Core Concept: Timing Functions Map Time to Progress",[14,73,74,75,78,79,82,83,86,87,90,91,94],{},"Every CSS animation computes, for each frame, how far through its duration it is — the ",[18,76,77],{},"input progress",", from 0 to 1. The timing function transforms that into ",[18,80,81],{},"output progress",", which is what actually interpolates the animated property. ",[50,84,85],{},"linear"," maps input straight to output. Every other timing function reshapes the relationship: ",[50,88,89],{},"ease-out"," makes output race ahead early and crawl at the end; ",[50,92,93],{},"steps(4)"," holds output flat and jumps; a spring pushes output past 1 and back.",[96,97,103,104,103,108,103,112,103,120,103,132,103,138,103,143,103,148,103,154,103,161,103,166,103,170,103,174,103,177,103,181,103,184,103,188,103,191,103,194,103,198,103,203,103,210,103,214,103,218],"svg",{"viewBox":98,"role":99,"ariaLabel":100,"xmlns":101,"style":102},"0 0 720 340","img","Pipeline from elapsed time to input progress, through a timing function, to output progress that interpolates the property","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;height:auto;max-width:720px;margin:2rem 0","\n  ",[105,106,107],"title",{},"Where the timing function sits",[109,110,111],"desc",{},"Elapsed time divided by duration gives input progress from 0 to 1. The timing function reshapes input into output progress, which may leave the 0 to 1 range. Output progress interpolates between the start and end values of the property, producing the value painted on that frame.",[113,114,119],"text",{"textAnchor":115,"x":116,"y":117,"style":118},"middle","360","26","text-anchor:middle;fill:currentColor;font:700 17px sans-serif","One frame of a CSS animation",[121,122],"rect",{"x":123,"y":124,"width":125,"height":126,"rx":127,"fill":128,"stroke":129,"strokeWidth":130,"opacity":131},"20","60","150","100","10","none","currentColor","1.5","0.6",[113,133,137],{"textAnchor":115,"x":134,"y":135,"style":136},"95","92","text-anchor:middle;fill:currentColor;font:700 13px sans-serif","elapsed time",[113,139,142],{"textAnchor":115,"x":134,"y":140,"style":141},"118","text-anchor:middle;fill:currentColor;font:12px ui-monospace,monospace","÷ duration",[113,144,147],{"textAnchor":115,"x":134,"y":145,"style":146},"140","text-anchor:middle;fill:currentColor;font:12px sans-serif","input 0…1",[149,150],"line",{"x1":151,"y1":152,"x2":153,"y2":152,"stroke":129,"strokeWidth":130,"opacity":131},"170","110","200",[121,155],{"x":153,"y":156,"width":157,"height":158,"rx":127,"fill":159,"opacity":160},"50","220","120","#7aa2ff","0.3",[113,162,165],{"textAnchor":115,"x":163,"y":164,"style":136},"310","80","timing function",[113,167,169],{"textAnchor":115,"x":163,"y":168,"style":141},"106","ease-out · steps()",[113,171,173],{"textAnchor":115,"x":163,"y":172,"style":141},"126","cubic-bezier() · linear()",[113,175,176],{"textAnchor":115,"x":163,"y":125,"style":146},"output may exceed 0…1",[149,178],{"x1":179,"y1":152,"x2":180,"y2":152,"stroke":129,"strokeWidth":130,"opacity":131},"420","450",[121,182],{"x":180,"y":124,"width":183,"height":126,"rx":127,"fill":128,"stroke":129,"strokeWidth":130,"opacity":131},"250",[113,185,187],{"textAnchor":115,"x":186,"y":135,"style":136},"575","interpolate property",[113,189,190],{"textAnchor":115,"x":186,"y":140,"style":141},"start + (end − start) × out",[113,192,193],{"textAnchor":115,"x":186,"y":145,"style":146},"painted value",[121,195],{"x":123,"y":153,"width":196,"height":152,"rx":127,"fill":128,"stroke":129,"strokeWidth":130,"opacity":197},"680","0.5",[113,199,202],{"textAnchor":115,"x":116,"y":200,"style":201},"228","text-anchor:middle;fill:currentColor;font:600 13px sans-serif","What each guide in this section tunes",[113,204,209],{"textAnchor":205,"x":206,"y":207,"style":208},"start","40","256","text-anchor:start;fill:currentColor;font:12px sans-serif","duration → Choosing Animation Durations",[113,211,213],{"textAnchor":205,"x":206,"y":212,"style":208},"280","curve shape → Overshoot and Anticipation, Springs",[113,215,217],{"textAnchor":205,"x":216,"y":207,"style":208},"380","discrete output → steps()",[113,219,220],{"textAnchor":205,"x":216,"y":212,"style":208},"per-direction timing → Entry vs Exit",[14,222,223,224,228,229,233,234,238,239,243,244,248],{},"Every guide in this section adjusts one part of that pipeline. ",[23,225,227],{"href":226},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fchoosing-animation-durations\u002F","Choosing Animation Durations"," sets the denominator. ",[23,230,232],{"href":231},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fcubic-bezier-overshoot-and-anticipation\u002F","Overshoot and Anticipation With cubic-bezier"," and ",[23,235,237],{"href":236},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Flinear-easing-function-for-springs\u002F","Spring and Bounce Easing With linear()"," shape the curve. ",[23,240,242],{"href":241},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fsteps-easing-for-sprite-animations\u002F","steps() Easing for Sprites and Typing"," makes the output discrete. ",[23,245,247],{"href":246},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fentry-vs-exit-easing\u002F","Entry vs Exit Easing"," chooses different curves and durations for each direction of travel.",[250,251,253],"h3",{"id":252},"the-four-families-of-curves","The four families of curves",[96,255,103,258,103,261,103,264,103,267,103,272,103,277,103,280,103,284,103,287,103,290,103,294,103,297,103,300,103,303,103,307,103,310,103,314,103,317,103,321,103,324],{"viewBox":256,"role":99,"ariaLabel":257,"xmlns":101,"style":102},"0 0 720 300","Four small plots representing the families: deceleration, acceleration, symmetric, and expressive",[105,259,260],{},"Curve families and their jobs",[109,262,263],{},"Deceleration curves suit entrances and state changes. Acceleration curves suit exits. Symmetric curves suit movement between two on-screen positions. Expressive curves with overshoot, springs or steps suit rare moments of emphasis or frame-by-frame effects.",[113,265,266],{"textAnchor":115,"x":116,"y":117,"style":118},"Four families, four jobs",[121,268],{"x":123,"y":156,"width":269,"height":270,"rx":127,"fill":159,"opacity":271},"160","190","0.14",[273,274],"path",{"d":275,"fill":128,"stroke":159,"strokeWidth":276},"M40 170 C70 80 100 70 160 70","4",[113,278,279],{"textAnchor":115,"x":126,"y":153,"style":136},"Decelerate",[113,281,283],{"textAnchor":115,"x":126,"y":282,"style":146},"222","entrances",[121,285],{"x":286,"y":156,"width":269,"height":270,"rx":127,"fill":159,"opacity":271},"196",[273,288],{"d":289,"fill":128,"stroke":159,"strokeWidth":276},"M216 170 C276 170 306 160 336 70",[113,291,293],{"textAnchor":115,"x":292,"y":153,"style":136},"276","Accelerate",[113,295,296],{"textAnchor":115,"x":292,"y":282,"style":146},"exits",[121,298],{"x":299,"y":156,"width":269,"height":270,"rx":127,"fill":159,"opacity":271},"372",[273,301],{"d":302,"fill":128,"stroke":159,"strokeWidth":276},"M392 170 C452 170 452 70 512 70",[113,304,306],{"textAnchor":115,"x":305,"y":153,"style":136},"452","Symmetric",[113,308,309],{"textAnchor":115,"x":305,"y":282,"style":146},"on-screen moves",[121,311],{"x":312,"y":156,"width":313,"height":270,"rx":127,"fill":159,"opacity":271},"548","152",[273,315],{"d":316,"fill":128,"stroke":159,"strokeWidth":276},"M568 170 C600 50 620 50 680 80",[113,318,320],{"textAnchor":115,"x":319,"y":153,"style":136},"624","Expressive",[113,322,323],{"textAnchor":115,"x":319,"y":282,"style":146},"rare emphasis",[113,325,327],{"textAnchor":115,"x":116,"y":292,"style":326},"text-anchor:middle;fill:currentColor;font:12px sans-serif;opacity:0.8","Most interfaces need one of each and use the first family for the majority of motion.",[14,329,330,331,334,335,338,339,342],{},"The practical insight is that choosing easing is not choosing a favourite curve; it is classifying each motion by its job. An element ",[18,332,333],{},"arriving"," decelerates. An element ",[18,336,337],{},"leaving"," accelerates. An element ",[18,340,341],{},"moving between two visible positions"," — a toggle knob, a tab indicator — accelerates and decelerates symmetrically, because both ends of the path are on screen. And a small number of moments that deserve attention get an expressive curve. Once motions are classified, the curve follows.",[250,344,346],{"id":345},"why-a-system-beats-one-off-choices","Why a system beats one-off choices",[14,348,349,350,353,354,357,358,361],{},"Motion choices made one component at a time drift. The dropdown gets ",[50,351,352],{},"0.3s ease",", the modal ",[50,355,356],{},"250ms ease-out",", the toast ",[50,359,360],{},".4s cubic-bezier(.17,.67,.83,.67)"," copied from a blog post, and the tooltip nothing at all. Each looked fine when it was built. Together they make an interface whose parts do not feel like they belong to the same product, and users perceive that inconsistency as a lack of polish even when they cannot name it.",[14,363,364,365,368,369,368,372,233,375,378],{},"A motion system fixes this the same way a colour system fixes ad hoc hex values. A small, named vocabulary — a handful of curves and a handful of durations — is paired into intents such as ",[18,366,367],{},"enter",", ",[18,370,371],{},"exit",[18,373,374],{},"move",[18,376,377],{},"emphasis",". Components choose an intent; the system decides the numbers. The benefits compound: consistency across components, one place to tune the feel of the whole product, and a single switch for reduced motion. It also makes design review faster, because the conversation moves from \"should this be 280 or 300 milliseconds?\" to \"is this an entrance or a move?\", which is a question with a clear answer.",[14,380,381],{},"The system does not have to be large, and it should not try to anticipate every future need. Most products need four or five intents, and new ones should be added only when a real component cannot be expressed with the existing set. What matters is that every animation in the codebase maps onto one of them, and that exceptions are rare, deliberate and documented.",[65,383],{},[68,385,387],{"id":386},"syntax-and-parameters","Syntax and Parameters",[389,390,391,407],"table",{},[392,393,394],"thead",{},[395,396,397,401,404],"tr",{},[398,399,400],"th",{},"Timing function",[398,402,403],{},"Accepted values",[398,405,406],{},"Default \u002F notes",[408,409,410,436,449,462,492,514],"tbody",{},[395,411,412,416,431],{},[413,414,415],"td",{},"Keywords",[413,417,418,368,420,368,423,368,426,368,428],{},[50,419,85],{},[50,421,422],{},"ease",[50,424,425],{},"ease-in",[50,427,89],{},[50,429,430],{},"ease-in-out",[413,432,433,435],{},[50,434,422],{}," is the initial value",[395,437,438,443,446],{},[413,439,440],{},[50,441,442],{},"cubic-bezier(x1, y1, x2, y2)",[413,444,445],{},"x in 0–1; y any number",[413,447,448],{},"y outside 0–1 gives overshoot or anticipation",[395,450,451,456,459],{},[413,452,453],{},[50,454,455],{},"linear(\u003Cpoint>#)",[413,457,458],{},"output numbers with optional input percentages",[413,460,461],{},"outputs unclamped; enables springs and bounces",[395,463,464,469,487],{},[413,465,466],{},[50,467,468],{},"steps(n, \u003Cposition>)",[413,470,471,474,475,368,478,368,481,368,484],{},[50,472,473],{},"n"," ≥ 1; ",[50,476,477],{},"jump-start",[50,479,480],{},"jump-end",[50,482,483],{},"jump-none",[50,485,486],{},"jump-both",[413,488,489,490],{},"position defaults to ",[50,491,480],{},[395,493,494,502,505],{},[413,495,496,368,499],{},[50,497,498],{},"step-start",[50,500,501],{},"step-end",[413,503,504],{},"keywords",[413,506,507,510,511],{},[50,508,509],{},"steps(1, jump-start)"," \u002F ",[50,512,513],{},"steps(1, jump-end)",[395,515,516,519,528],{},[413,517,518],{},"Applied via",[413,520,521,368,524,527],{},[50,522,523],{},"transition-timing-function",[50,525,526],{},"animation-timing-function",", per-keyframe",[413,529,530],{},"per-keyframe values apply to the segment that follows",[14,532,533,534,536],{},"The last row is an underused feature: ",[50,535,526],{}," declared inside a keyframe applies to the segment from that keyframe to the next. That allows a single animation to ease out into a midpoint and ease in out of it, which is how complex multi-stage motion is built without multiple animations.",[65,538],{},[68,540,542],{"id":541},"step-by-step-implementation-a-motion-token-system","Step-by-Step Implementation: A Motion Token System",[250,544,546],{"id":545},"step-1-define-the-curve-vocabulary","Step 1: define the curve vocabulary",[548,549,554],"pre",{"className":550,"code":551,"language":552,"meta":553,"style":553},"language-css shiki shiki-themes github-light-high-contrast github-dark-high-contrast",":root {\n  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);\n  --ease-in: cubic-bezier(0.64, 0, 0.78, 0);\n  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);\n  --ease-emphasis: cubic-bezier(0.34, 1.56, 0.64, 1);\n}\n","css","",[50,555,556,568,604,635,665,695],{"__ignoreMap":553},[557,558,560,564],"span",{"class":149,"line":559},1,[557,561,563],{"class":562},"s-5SL",":root",[557,565,567],{"class":566},"suds8"," {\n",[557,569,571,575,578,581,584,587,589,592,594,597,599,601],{"class":149,"line":570},2,[557,572,574],{"class":573},"soyes","  --ease-out",[557,576,577],{"class":566},": ",[557,579,580],{"class":562},"cubic-bezier",[557,582,583],{"class":566},"(",[557,585,586],{"class":562},"0.22",[557,588,368],{"class":566},[557,590,591],{"class":562},"1",[557,593,368],{"class":566},[557,595,596],{"class":562},"0.36",[557,598,368],{"class":566},[557,600,591],{"class":562},[557,602,603],{"class":566},");\n",[557,605,607,610,612,614,616,619,621,624,626,629,631,633],{"class":149,"line":606},3,[557,608,609],{"class":573},"  --ease-in",[557,611,577],{"class":566},[557,613,580],{"class":562},[557,615,583],{"class":566},[557,617,618],{"class":562},"0.64",[557,620,368],{"class":566},[557,622,623],{"class":562},"0",[557,625,368],{"class":566},[557,627,628],{"class":562},"0.78",[557,630,368],{"class":566},[557,632,623],{"class":562},[557,634,603],{"class":566},[557,636,638,641,643,645,647,650,652,654,656,659,661,663],{"class":149,"line":637},4,[557,639,640],{"class":573},"  --ease-in-out",[557,642,577],{"class":566},[557,644,580],{"class":562},[557,646,583],{"class":566},[557,648,649],{"class":562},"0.65",[557,651,368],{"class":566},[557,653,623],{"class":562},[557,655,368],{"class":566},[557,657,658],{"class":562},"0.35",[557,660,368],{"class":566},[557,662,591],{"class":562},[557,664,603],{"class":566},[557,666,668,671,673,675,677,680,682,685,687,689,691,693],{"class":149,"line":667},5,[557,669,670],{"class":573},"  --ease-emphasis",[557,672,577],{"class":566},[557,674,580],{"class":562},[557,676,583],{"class":566},[557,678,679],{"class":562},"0.34",[557,681,368],{"class":566},[557,683,684],{"class":562},"1.56",[557,686,368],{"class":566},[557,688,618],{"class":562},[557,690,368],{"class":566},[557,692,591],{"class":562},[557,694,603],{"class":566},[557,696,698],{"class":149,"line":697},6,[557,699,700],{"class":566},"}\n",[250,702,704],{"id":703},"step-2-define-the-duration-scale","Step 2: define the duration scale",[548,706,708],{"className":550,"code":707,"language":552,"meta":553,"style":553},":root {\n  --dur-1: 90ms;\n  --dur-2: 160ms;\n  --dur-3: 240ms;\n  --dur-4: 340ms;\n  --dur-5: 480ms;\n}\n",[50,709,710,716,733,746,760,774,788],{"__ignoreMap":553},[557,711,712,714],{"class":149,"line":559},[557,713,563],{"class":562},[557,715,567],{"class":566},[557,717,718,721,723,726,730],{"class":149,"line":570},[557,719,720],{"class":573},"  --dur-1",[557,722,577],{"class":566},[557,724,725],{"class":562},"90",[557,727,729],{"class":728},"sHUrx","ms",[557,731,732],{"class":566},";\n",[557,734,735,738,740,742,744],{"class":149,"line":606},[557,736,737],{"class":573},"  --dur-2",[557,739,577],{"class":566},[557,741,269],{"class":562},[557,743,729],{"class":728},[557,745,732],{"class":566},[557,747,748,751,753,756,758],{"class":149,"line":637},[557,749,750],{"class":573},"  --dur-3",[557,752,577],{"class":566},[557,754,755],{"class":562},"240",[557,757,729],{"class":728},[557,759,732],{"class":566},[557,761,762,765,767,770,772],{"class":149,"line":667},[557,763,764],{"class":573},"  --dur-4",[557,766,577],{"class":566},[557,768,769],{"class":562},"340",[557,771,729],{"class":728},[557,773,732],{"class":566},[557,775,776,779,781,784,786],{"class":149,"line":697},[557,777,778],{"class":573},"  --dur-5",[557,780,577],{"class":566},[557,782,783],{"class":562},"480",[557,785,729],{"class":728},[557,787,732],{"class":566},[557,789,791],{"class":149,"line":790},7,[557,792,700],{"class":566},[250,794,796],{"id":795},"step-3-map-intents-to-pairs-of-curve-and-duration","Step 3: map intents to pairs of curve and duration",[548,798,800],{"className":550,"code":799,"language":552,"meta":553,"style":553},":root {\n  --motion-enter: var(--dur-3) var(--ease-out);\n  --motion-exit: var(--dur-2) var(--ease-in);\n  --motion-move: var(--dur-3) var(--ease-in-out);\n  --motion-emphasis: var(--dur-4) var(--ease-emphasis);\n  --motion-feedback: var(--dur-1) linear;\n}\n",[50,801,802,808,835,860,884,909,929],{"__ignoreMap":553},[557,803,804,806],{"class":149,"line":559},[557,805,563],{"class":562},[557,807,567],{"class":566},[557,809,810,813,815,818,820,823,826,828,830,833],{"class":149,"line":570},[557,811,812],{"class":573},"  --motion-enter",[557,814,577],{"class":566},[557,816,817],{"class":562},"var",[557,819,583],{"class":566},[557,821,822],{"class":573},"--dur-3",[557,824,825],{"class":566},") ",[557,827,817],{"class":562},[557,829,583],{"class":566},[557,831,832],{"class":573},"--ease-out",[557,834,603],{"class":566},[557,836,837,840,842,844,846,849,851,853,855,858],{"class":149,"line":606},[557,838,839],{"class":573},"  --motion-exit",[557,841,577],{"class":566},[557,843,817],{"class":562},[557,845,583],{"class":566},[557,847,848],{"class":573},"--dur-2",[557,850,825],{"class":566},[557,852,817],{"class":562},[557,854,583],{"class":566},[557,856,857],{"class":573},"--ease-in",[557,859,603],{"class":566},[557,861,862,865,867,869,871,873,875,877,879,882],{"class":149,"line":637},[557,863,864],{"class":573},"  --motion-move",[557,866,577],{"class":566},[557,868,817],{"class":562},[557,870,583],{"class":566},[557,872,822],{"class":573},[557,874,825],{"class":566},[557,876,817],{"class":562},[557,878,583],{"class":566},[557,880,881],{"class":573},"--ease-in-out",[557,883,603],{"class":566},[557,885,886,889,891,893,895,898,900,902,904,907],{"class":149,"line":667},[557,887,888],{"class":573},"  --motion-emphasis",[557,890,577],{"class":566},[557,892,817],{"class":562},[557,894,583],{"class":566},[557,896,897],{"class":573},"--dur-4",[557,899,825],{"class":566},[557,901,817],{"class":562},[557,903,583],{"class":566},[557,905,906],{"class":573},"--ease-emphasis",[557,908,603],{"class":566},[557,910,911,914,916,918,920,923,925,927],{"class":149,"line":697},[557,912,913],{"class":573},"  --motion-feedback",[557,915,577],{"class":566},[557,917,817],{"class":562},[557,919,583],{"class":566},[557,921,922],{"class":573},"--dur-1",[557,924,825],{"class":566},[557,926,85],{"class":562},[557,928,732],{"class":566},[557,930,931],{"class":149,"line":790},[557,932,700],{"class":566},[250,934,936],{"id":935},"step-4-components-reference-intents-only","Step 4: components reference intents only",[548,938,940],{"className":550,"code":939,"language":552,"meta":553,"style":553},".tab-indicator { transition: translate var(--motion-move); }\n.toast { transition: translate var(--motion-enter), opacity var(--motion-enter); }\n.button:active { transition: scale var(--motion-feedback); }\n",[50,941,942,966,995],{"__ignoreMap":553},[557,943,944,947,950,953,956,958,960,963],{"class":149,"line":559},[557,945,946],{"class":562},".tab-indicator",[557,948,949],{"class":566}," { ",[557,951,952],{"class":562},"transition",[557,954,955],{"class":566},": translate ",[557,957,817],{"class":562},[557,959,583],{"class":566},[557,961,962],{"class":573},"--motion-move",[557,964,965],{"class":566},"); }\n",[557,967,968,971,973,975,977,979,981,984,987,989,991,993],{"class":149,"line":570},[557,969,970],{"class":562},".toast",[557,972,949],{"class":566},[557,974,952],{"class":562},[557,976,955],{"class":566},[557,978,817],{"class":562},[557,980,583],{"class":566},[557,982,983],{"class":573},"--motion-enter",[557,985,986],{"class":566},"), opacity ",[557,988,817],{"class":562},[557,990,583],{"class":566},[557,992,983],{"class":573},[557,994,965],{"class":566},[557,996,997,1000,1002,1004,1007,1009,1011,1014],{"class":149,"line":606},[557,998,999],{"class":562},".button:active",[557,1001,949],{"class":566},[557,1003,952],{"class":562},[557,1005,1006],{"class":566},": scale ",[557,1008,817],{"class":562},[557,1010,583],{"class":566},[557,1012,1013],{"class":573},"--motion-feedback",[557,1015,965],{"class":566},[250,1017,1019],{"id":1018},"step-5-one-switch-for-reduced-motion","Step 5: one switch for reduced motion",[548,1021,1023],{"className":550,"code":1022,"language":552,"meta":553,"style":553},"@media (prefers-reduced-motion: reduce) {\n  :root {\n    --motion-enter: 1ms linear;\n    --motion-exit: 1ms linear;\n    --motion-move: 1ms linear;\n    --motion-emphasis: 1ms linear;\n  }\n}\n",[50,1024,1025,1033,1040,1056,1071,1086,1101,1106],{"__ignoreMap":553},[557,1026,1027,1030],{"class":149,"line":559},[557,1028,1029],{"class":728},"@media",[557,1031,1032],{"class":566}," (prefers-reduced-motion: reduce) {\n",[557,1034,1035,1038],{"class":149,"line":570},[557,1036,1037],{"class":562},"  :root",[557,1039,567],{"class":566},[557,1041,1042,1045,1047,1049,1051,1054],{"class":149,"line":606},[557,1043,1044],{"class":573},"    --motion-enter",[557,1046,577],{"class":566},[557,1048,591],{"class":562},[557,1050,729],{"class":728},[557,1052,1053],{"class":562}," linear",[557,1055,732],{"class":566},[557,1057,1058,1061,1063,1065,1067,1069],{"class":149,"line":637},[557,1059,1060],{"class":573},"    --motion-exit",[557,1062,577],{"class":566},[557,1064,591],{"class":562},[557,1066,729],{"class":728},[557,1068,1053],{"class":562},[557,1070,732],{"class":566},[557,1072,1073,1076,1078,1080,1082,1084],{"class":149,"line":667},[557,1074,1075],{"class":573},"    --motion-move",[557,1077,577],{"class":566},[557,1079,591],{"class":562},[557,1081,729],{"class":728},[557,1083,1053],{"class":562},[557,1085,732],{"class":566},[557,1087,1088,1091,1093,1095,1097,1099],{"class":149,"line":697},[557,1089,1090],{"class":573},"    --motion-emphasis",[557,1092,577],{"class":566},[557,1094,591],{"class":562},[557,1096,729],{"class":728},[557,1098,1053],{"class":562},[557,1100,732],{"class":566},[557,1102,1103],{"class":149,"line":790},[557,1104,1105],{"class":566},"  }\n",[557,1107,1109],{"class":149,"line":1108},8,[557,1110,700],{"class":566},[14,1112,1113],{},"Because every component references an intent token, the reduced-motion variant of the entire interface is one media query. Components never need to know about the preference.",[65,1115],{},[68,1117,1119],{"id":1118},"annotated-production-example-a-segmented-control","Annotated Production Example: A Segmented Control",[14,1121,1122],{},"A segmented control — a row of mutually exclusive options with a sliding indicator — uses three of the four families at once: a symmetric move for the indicator, fast feedback for the press, and a decelerating fade for the label colour.",[1124,1125],"live-demo",{"name":1126},"easing-segmented-control",[548,1128,1132],{"className":1129,"code":1130,"language":1131,"meta":553,"style":553},"language-html shiki shiki-themes github-light-high-contrast github-dark-high-contrast","\u003Cfieldset class=\"segmented\">\n  \u003Clegend class=\"visually-hidden\">View\u003C\u002Flegend>\n  \u003Clabel>\u003Cinput type=\"radio\" name=\"view\" value=\"day\" checked>\u003Cspan>Day\u003C\u002Fspan>\u003C\u002Flabel>\n  \u003Clabel>\u003Cinput type=\"radio\" name=\"view\" value=\"week\">\u003Cspan>Week\u003C\u002Fspan>\u003C\u002Flabel>\n  \u003Clabel>\u003Cinput type=\"radio\" name=\"view\" value=\"month\">\u003Cspan>Month\u003C\u002Fspan>\u003C\u002Flabel>\n  \u003Cspan class=\"segmented__indicator\" aria-hidden=\"true\">\u003C\u002Fspan>\n\u003C\u002Ffieldset>\n","html",[50,1133,1134,1156,1178,1234,1278,1322,1349],{"__ignoreMap":553},[557,1135,1136,1139,1143,1146,1149,1153],{"class":149,"line":559},[557,1137,1138],{"class":566},"\u003C",[557,1140,1142],{"class":1141},"sne4z","fieldset",[557,1144,1145],{"class":562}," class",[557,1147,1148],{"class":566},"=",[557,1150,1152],{"class":1151},"sT6z2","\"segmented\"",[557,1154,1155],{"class":566},">\n",[557,1157,1158,1161,1164,1166,1168,1171,1174,1176],{"class":149,"line":570},[557,1159,1160],{"class":566},"  \u003C",[557,1162,1163],{"class":1141},"legend",[557,1165,1145],{"class":562},[557,1167,1148],{"class":566},[557,1169,1170],{"class":1151},"\"visually-hidden\"",[557,1172,1173],{"class":566},">View\u003C\u002F",[557,1175,1163],{"class":1141},[557,1177,1155],{"class":566},[557,1179,1180,1182,1185,1188,1191,1194,1196,1199,1202,1204,1207,1210,1212,1215,1218,1220,1222,1225,1227,1230,1232],{"class":149,"line":606},[557,1181,1160],{"class":566},[557,1183,1184],{"class":1141},"label",[557,1186,1187],{"class":566},">\u003C",[557,1189,1190],{"class":1141},"input",[557,1192,1193],{"class":562}," type",[557,1195,1148],{"class":566},[557,1197,1198],{"class":1151},"\"radio\"",[557,1200,1201],{"class":562}," name",[557,1203,1148],{"class":566},[557,1205,1206],{"class":1151},"\"view\"",[557,1208,1209],{"class":562}," value",[557,1211,1148],{"class":566},[557,1213,1214],{"class":1151},"\"day\"",[557,1216,1217],{"class":562}," checked",[557,1219,1187],{"class":566},[557,1221,557],{"class":1141},[557,1223,1224],{"class":566},">Day\u003C\u002F",[557,1226,557],{"class":1141},[557,1228,1229],{"class":566},">\u003C\u002F",[557,1231,1184],{"class":1141},[557,1233,1155],{"class":566},[557,1235,1236,1238,1240,1242,1244,1246,1248,1250,1252,1254,1256,1258,1260,1263,1265,1267,1270,1272,1274,1276],{"class":149,"line":637},[557,1237,1160],{"class":566},[557,1239,1184],{"class":1141},[557,1241,1187],{"class":566},[557,1243,1190],{"class":1141},[557,1245,1193],{"class":562},[557,1247,1148],{"class":566},[557,1249,1198],{"class":1151},[557,1251,1201],{"class":562},[557,1253,1148],{"class":566},[557,1255,1206],{"class":1151},[557,1257,1209],{"class":562},[557,1259,1148],{"class":566},[557,1261,1262],{"class":1151},"\"week\"",[557,1264,1187],{"class":566},[557,1266,557],{"class":1141},[557,1268,1269],{"class":566},">Week\u003C\u002F",[557,1271,557],{"class":1141},[557,1273,1229],{"class":566},[557,1275,1184],{"class":1141},[557,1277,1155],{"class":566},[557,1279,1280,1282,1284,1286,1288,1290,1292,1294,1296,1298,1300,1302,1304,1307,1309,1311,1314,1316,1318,1320],{"class":149,"line":667},[557,1281,1160],{"class":566},[557,1283,1184],{"class":1141},[557,1285,1187],{"class":566},[557,1287,1190],{"class":1141},[557,1289,1193],{"class":562},[557,1291,1148],{"class":566},[557,1293,1198],{"class":1151},[557,1295,1201],{"class":562},[557,1297,1148],{"class":566},[557,1299,1206],{"class":1151},[557,1301,1209],{"class":562},[557,1303,1148],{"class":566},[557,1305,1306],{"class":1151},"\"month\"",[557,1308,1187],{"class":566},[557,1310,557],{"class":1141},[557,1312,1313],{"class":566},">Month\u003C\u002F",[557,1315,557],{"class":1141},[557,1317,1229],{"class":566},[557,1319,1184],{"class":1141},[557,1321,1155],{"class":566},[557,1323,1324,1326,1328,1330,1332,1335,1338,1340,1343,1345,1347],{"class":149,"line":697},[557,1325,1160],{"class":566},[557,1327,557],{"class":1141},[557,1329,1145],{"class":562},[557,1331,1148],{"class":566},[557,1333,1334],{"class":1151},"\"segmented__indicator\"",[557,1336,1337],{"class":562}," aria-hidden",[557,1339,1148],{"class":566},[557,1341,1342],{"class":1151},"\"true\"",[557,1344,1229],{"class":566},[557,1346,557],{"class":1141},[557,1348,1155],{"class":566},[557,1350,1351,1354,1356],{"class":149,"line":790},[557,1352,1353],{"class":566},"\u003C\u002F",[557,1355,1142],{"class":1141},[557,1357,1155],{"class":566},[548,1359,1361],{"className":550,"code":1360,"language":552,"meta":553,"style":553},".segmented {\n  --count: 3;\n  --index: 0;\n  position: relative;\n  display: grid;\n  grid-template-columns: repeat(var(--count), 1fr);\n  margin: 0;\n  padding: 0.25rem;\n  border: 0;\n  border-radius: 10px;\n  background: #e2e8f0;\n}\n\n\u002F* The checked option publishes its index for the indicator to read. *\u002F\n.segmented:has(input[value=\"week\"]:checked)  { --index: 1; }\n.segmented:has(input[value=\"month\"]:checked) { --index: 2; }\n\n.segmented label { position: relative; z-index: 1; text-align: center; cursor: pointer; }\n.segmented input { position: absolute; opacity: 0; }\n\n.segmented span {\n  display: block;\n  padding: 0.4rem 0.75rem;\n  color: #475569;\n  transition: color var(--motion-enter);            \u002F* decelerating colour change *\u002F\n}\n.segmented input:checked + span { color: #0f172a; }\n.segmented input:focus-visible + span { outline: 2px solid #4f46e5; outline-offset: 2px; border-radius: 6px; }\n.segmented label:active span { scale: 0.96; transition: scale var(--motion-feedback); }\n\n.segmented__indicator {\n  position: absolute;\n  inset-block: 0.25rem;\n  left: 0.25rem;\n  width: calc((100% - 0.5rem) \u002F var(--count));\n  border-radius: 8px;\n  background: #ffffff;\n  box-shadow: 0 1px 3px rgb(15 23 42 \u002F 0.15);\n  translate: calc(var(--index) * 100%) 0;\n  transition: translate var(--motion-move);           \u002F* symmetric: both ends on screen *\u002F\n}\n",[50,1362,1363,1370,1382,1393,1405,1417,1446,1457,1472,1484,1499,1512,1517,1524,1531,1570,1603,1608,1657,1685,1690,1700,1712,1731,1744,1768,1773,1798,1854,1890,1895,1903,1914,1928,1942,1981,1995,2007,2048,2082,2101],{"__ignoreMap":553},[557,1364,1365,1368],{"class":149,"line":559},[557,1366,1367],{"class":562},".segmented",[557,1369,567],{"class":566},[557,1371,1372,1375,1377,1380],{"class":149,"line":570},[557,1373,1374],{"class":573},"  --count",[557,1376,577],{"class":566},[557,1378,1379],{"class":562},"3",[557,1381,732],{"class":566},[557,1383,1384,1387,1389,1391],{"class":149,"line":606},[557,1385,1386],{"class":573},"  --index",[557,1388,577],{"class":566},[557,1390,623],{"class":562},[557,1392,732],{"class":566},[557,1394,1395,1398,1400,1403],{"class":149,"line":637},[557,1396,1397],{"class":562},"  position",[557,1399,577],{"class":566},[557,1401,1402],{"class":562},"relative",[557,1404,732],{"class":566},[557,1406,1407,1410,1412,1415],{"class":149,"line":667},[557,1408,1409],{"class":562},"  display",[557,1411,577],{"class":566},[557,1413,1414],{"class":562},"grid",[557,1416,732],{"class":566},[557,1418,1419,1422,1424,1427,1429,1431,1433,1436,1439,1441,1444],{"class":149,"line":697},[557,1420,1421],{"class":562},"  grid-template-columns",[557,1423,577],{"class":566},[557,1425,1426],{"class":562},"repeat",[557,1428,583],{"class":566},[557,1430,817],{"class":562},[557,1432,583],{"class":566},[557,1434,1435],{"class":573},"--count",[557,1437,1438],{"class":566},"), ",[557,1440,591],{"class":562},[557,1442,1443],{"class":728},"fr",[557,1445,603],{"class":566},[557,1447,1448,1451,1453,1455],{"class":149,"line":790},[557,1449,1450],{"class":562},"  margin",[557,1452,577],{"class":566},[557,1454,623],{"class":562},[557,1456,732],{"class":566},[557,1458,1459,1462,1464,1467,1470],{"class":149,"line":1108},[557,1460,1461],{"class":562},"  padding",[557,1463,577],{"class":566},[557,1465,1466],{"class":562},"0.25",[557,1468,1469],{"class":728},"rem",[557,1471,732],{"class":566},[557,1473,1475,1478,1480,1482],{"class":149,"line":1474},9,[557,1476,1477],{"class":562},"  border",[557,1479,577],{"class":566},[557,1481,623],{"class":562},[557,1483,732],{"class":566},[557,1485,1487,1490,1492,1494,1497],{"class":149,"line":1486},10,[557,1488,1489],{"class":562},"  border-radius",[557,1491,577],{"class":566},[557,1493,127],{"class":562},[557,1495,1496],{"class":728},"px",[557,1498,732],{"class":566},[557,1500,1502,1505,1507,1510],{"class":149,"line":1501},11,[557,1503,1504],{"class":562},"  background",[557,1506,577],{"class":566},[557,1508,1509],{"class":562},"#e2e8f0",[557,1511,732],{"class":566},[557,1513,1515],{"class":149,"line":1514},12,[557,1516,700],{"class":566},[557,1518,1520],{"class":149,"line":1519},13,[557,1521,1523],{"emptyLinePlaceholder":1522},true,"\n",[557,1525,1527],{"class":149,"line":1526},14,[557,1528,1530],{"class":1529},"sLBg1","\u002F* The checked option publishes its index for the indicator to read. *\u002F\n",[557,1532,1534,1537,1539,1541,1544,1547,1549,1551,1554,1557,1560,1563,1565,1567],{"class":149,"line":1533},15,[557,1535,1536],{"class":562},".segmented:has",[557,1538,583],{"class":566},[557,1540,1190],{"class":1141},[557,1542,1543],{"class":566},"[",[557,1545,1546],{"class":562},"value",[557,1548,1148],{"class":728},[557,1550,1262],{"class":1151},[557,1552,1553],{"class":566},"]",[557,1555,1556],{"class":562},":checked",[557,1558,1559],{"class":566},")  { ",[557,1561,1562],{"class":573},"--index",[557,1564,577],{"class":566},[557,1566,591],{"class":562},[557,1568,1569],{"class":566},"; }\n",[557,1571,1573,1575,1577,1579,1581,1583,1585,1587,1589,1591,1594,1596,1598,1601],{"class":149,"line":1572},16,[557,1574,1536],{"class":562},[557,1576,583],{"class":566},[557,1578,1190],{"class":1141},[557,1580,1543],{"class":566},[557,1582,1546],{"class":562},[557,1584,1148],{"class":728},[557,1586,1306],{"class":1151},[557,1588,1553],{"class":566},[557,1590,1556],{"class":562},[557,1592,1593],{"class":566},") { ",[557,1595,1562],{"class":573},[557,1597,577],{"class":566},[557,1599,1600],{"class":562},"2",[557,1602,1569],{"class":566},[557,1604,1606],{"class":149,"line":1605},17,[557,1607,1523],{"emptyLinePlaceholder":1522},[557,1609,1611,1613,1616,1618,1621,1623,1625,1628,1631,1633,1635,1637,1640,1642,1645,1647,1650,1652,1655],{"class":149,"line":1610},18,[557,1612,1367],{"class":562},[557,1614,1615],{"class":1141}," label",[557,1617,949],{"class":566},[557,1619,1620],{"class":562},"position",[557,1622,577],{"class":566},[557,1624,1402],{"class":562},[557,1626,1627],{"class":566},"; ",[557,1629,1630],{"class":562},"z-index",[557,1632,577],{"class":566},[557,1634,591],{"class":562},[557,1636,1627],{"class":566},[557,1638,1639],{"class":562},"text-align",[557,1641,577],{"class":566},[557,1643,1644],{"class":562},"center",[557,1646,1627],{"class":566},[557,1648,1649],{"class":562},"cursor",[557,1651,577],{"class":566},[557,1653,1654],{"class":562},"pointer",[557,1656,1569],{"class":566},[557,1658,1660,1662,1665,1667,1669,1671,1674,1676,1679,1681,1683],{"class":149,"line":1659},19,[557,1661,1367],{"class":562},[557,1663,1664],{"class":1141}," input",[557,1666,949],{"class":566},[557,1668,1620],{"class":562},[557,1670,577],{"class":566},[557,1672,1673],{"class":562},"absolute",[557,1675,1627],{"class":566},[557,1677,1678],{"class":562},"opacity",[557,1680,577],{"class":566},[557,1682,623],{"class":562},[557,1684,1569],{"class":566},[557,1686,1688],{"class":149,"line":1687},20,[557,1689,1523],{"emptyLinePlaceholder":1522},[557,1691,1693,1695,1698],{"class":149,"line":1692},21,[557,1694,1367],{"class":562},[557,1696,1697],{"class":1141}," span",[557,1699,567],{"class":566},[557,1701,1703,1705,1707,1710],{"class":149,"line":1702},22,[557,1704,1409],{"class":562},[557,1706,577],{"class":566},[557,1708,1709],{"class":562},"block",[557,1711,732],{"class":566},[557,1713,1715,1717,1719,1722,1724,1727,1729],{"class":149,"line":1714},23,[557,1716,1461],{"class":562},[557,1718,577],{"class":566},[557,1720,1721],{"class":562},"0.4",[557,1723,1469],{"class":728},[557,1725,1726],{"class":562}," 0.75",[557,1728,1469],{"class":728},[557,1730,732],{"class":566},[557,1732,1734,1737,1739,1742],{"class":149,"line":1733},24,[557,1735,1736],{"class":562},"  color",[557,1738,577],{"class":566},[557,1740,1741],{"class":562},"#475569",[557,1743,732],{"class":566},[557,1745,1747,1750,1752,1755,1758,1760,1762,1765],{"class":149,"line":1746},25,[557,1748,1749],{"class":562},"  transition",[557,1751,577],{"class":566},[557,1753,1754],{"class":562},"color",[557,1756,1757],{"class":562}," var",[557,1759,583],{"class":566},[557,1761,983],{"class":573},[557,1763,1764],{"class":566},");            ",[557,1766,1767],{"class":1529},"\u002F* decelerating colour change *\u002F\n",[557,1769,1771],{"class":149,"line":1770},26,[557,1772,700],{"class":566},[557,1774,1776,1778,1780,1782,1785,1787,1789,1791,1793,1796],{"class":149,"line":1775},27,[557,1777,1367],{"class":562},[557,1779,1664],{"class":1141},[557,1781,1556],{"class":562},[557,1783,1784],{"class":728}," +",[557,1786,1697],{"class":1141},[557,1788,949],{"class":566},[557,1790,1754],{"class":562},[557,1792,577],{"class":566},[557,1794,1795],{"class":562},"#0f172a",[557,1797,1569],{"class":566},[557,1799,1801,1803,1805,1808,1810,1812,1814,1817,1819,1821,1823,1826,1829,1831,1834,1836,1838,1840,1842,1845,1847,1850,1852],{"class":149,"line":1800},28,[557,1802,1367],{"class":562},[557,1804,1664],{"class":1141},[557,1806,1807],{"class":562},":focus-visible",[557,1809,1784],{"class":728},[557,1811,1697],{"class":1141},[557,1813,949],{"class":566},[557,1815,1816],{"class":562},"outline",[557,1818,577],{"class":566},[557,1820,1600],{"class":562},[557,1822,1496],{"class":728},[557,1824,1825],{"class":562}," solid",[557,1827,1828],{"class":562}," #4f46e5",[557,1830,1627],{"class":566},[557,1832,1833],{"class":562},"outline-offset",[557,1835,577],{"class":566},[557,1837,1600],{"class":562},[557,1839,1496],{"class":728},[557,1841,1627],{"class":566},[557,1843,1844],{"class":562},"border-radius",[557,1846,577],{"class":566},[557,1848,1849],{"class":562},"6",[557,1851,1496],{"class":728},[557,1853,1569],{"class":566},[557,1855,1857,1859,1861,1864,1866,1868,1871,1873,1876,1878,1880,1882,1884,1886,1888],{"class":149,"line":1856},29,[557,1858,1367],{"class":562},[557,1860,1615],{"class":1141},[557,1862,1863],{"class":562},":active",[557,1865,1697],{"class":1141},[557,1867,949],{"class":566},[557,1869,1870],{"class":562},"scale",[557,1872,577],{"class":566},[557,1874,1875],{"class":562},"0.96",[557,1877,1627],{"class":566},[557,1879,952],{"class":562},[557,1881,1006],{"class":566},[557,1883,817],{"class":562},[557,1885,583],{"class":566},[557,1887,1013],{"class":573},[557,1889,965],{"class":566},[557,1891,1893],{"class":149,"line":1892},30,[557,1894,1523],{"emptyLinePlaceholder":1522},[557,1896,1898,1901],{"class":149,"line":1897},31,[557,1899,1900],{"class":562},".segmented__indicator",[557,1902,567],{"class":566},[557,1904,1906,1908,1910,1912],{"class":149,"line":1905},32,[557,1907,1397],{"class":562},[557,1909,577],{"class":566},[557,1911,1673],{"class":562},[557,1913,732],{"class":566},[557,1915,1917,1920,1922,1924,1926],{"class":149,"line":1916},33,[557,1918,1919],{"class":562},"  inset-block",[557,1921,577],{"class":566},[557,1923,1466],{"class":562},[557,1925,1469],{"class":728},[557,1927,732],{"class":566},[557,1929,1931,1934,1936,1938,1940],{"class":149,"line":1930},34,[557,1932,1933],{"class":562},"  left",[557,1935,577],{"class":566},[557,1937,1466],{"class":562},[557,1939,1469],{"class":728},[557,1941,732],{"class":566},[557,1943,1945,1948,1950,1953,1956,1958,1961,1964,1967,1969,1972,1974,1976,1978],{"class":149,"line":1944},35,[557,1946,1947],{"class":562},"  width",[557,1949,577],{"class":566},[557,1951,1952],{"class":562},"calc",[557,1954,1955],{"class":566},"((",[557,1957,126],{"class":562},[557,1959,1960],{"class":728},"%",[557,1962,1963],{"class":728}," -",[557,1965,1966],{"class":562}," 0.5",[557,1968,1469],{"class":728},[557,1970,1971],{"class":566},") \u002F ",[557,1973,817],{"class":562},[557,1975,583],{"class":566},[557,1977,1435],{"class":573},[557,1979,1980],{"class":566},"));\n",[557,1982,1984,1986,1988,1991,1993],{"class":149,"line":1983},36,[557,1985,1489],{"class":562},[557,1987,577],{"class":566},[557,1989,1990],{"class":562},"8",[557,1992,1496],{"class":728},[557,1994,732],{"class":566},[557,1996,1998,2000,2002,2005],{"class":149,"line":1997},37,[557,1999,1504],{"class":562},[557,2001,577],{"class":566},[557,2003,2004],{"class":562},"#ffffff",[557,2006,732],{"class":566},[557,2008,2010,2013,2015,2017,2020,2022,2025,2027,2030,2032,2035,2038,2041,2043,2046],{"class":149,"line":2009},38,[557,2011,2012],{"class":562},"  box-shadow",[557,2014,577],{"class":566},[557,2016,623],{"class":562},[557,2018,2019],{"class":562}," 1",[557,2021,1496],{"class":728},[557,2023,2024],{"class":562}," 3",[557,2026,1496],{"class":728},[557,2028,2029],{"class":562}," rgb",[557,2031,583],{"class":566},[557,2033,2034],{"class":562},"15",[557,2036,2037],{"class":562}," 23",[557,2039,2040],{"class":562}," 42",[557,2042,510],{"class":566},[557,2044,2045],{"class":562},"0.15",[557,2047,603],{"class":566},[557,2049,2051,2054,2056,2058,2060,2062,2064,2066,2068,2071,2074,2076,2078,2080],{"class":149,"line":2050},39,[557,2052,2053],{"class":562},"  translate",[557,2055,577],{"class":566},[557,2057,1952],{"class":562},[557,2059,583],{"class":566},[557,2061,817],{"class":562},[557,2063,583],{"class":566},[557,2065,1562],{"class":573},[557,2067,825],{"class":566},[557,2069,2070],{"class":728},"*",[557,2072,2073],{"class":562}," 100",[557,2075,1960],{"class":728},[557,2077,825],{"class":566},[557,2079,623],{"class":562},[557,2081,732],{"class":566},[557,2083,2085,2087,2089,2091,2093,2095,2098],{"class":149,"line":2084},40,[557,2086,1749],{"class":562},[557,2088,955],{"class":566},[557,2090,817],{"class":562},[557,2092,583],{"class":566},[557,2094,962],{"class":573},[557,2096,2097],{"class":566},");           ",[557,2099,2100],{"class":1529},"\u002F* symmetric: both ends on screen *\u002F\n",[557,2102,2104],{"class":149,"line":2103},41,[557,2105,700],{"class":566},[14,2107,2108],{},"The indicator moves between two positions that are both visible, so it uses the symmetric curve. The label colour is a state arriving, so it decelerates. The press scale is feedback, so it is fast and linear. None of these values appears in the component — only intent names — so the component inherits any future tuning of the motion system automatically.",[65,2110],{},[68,2112,2114],{"id":2113},"motion-hierarchy-and-choreography","Motion Hierarchy and Choreography",[14,2116,2117],{},"A single well-eased transition is easy. A screen where six things change at once — a panel opens, its content fades in, a badge updates, a button disables, the background dims — is where motion design earns its name. Without a plan, everything animates simultaneously with the same curve and duration, and the result reads as one undifferentiated flash.",[14,2119,2120,2123],{},[31,2121,2122],{},"Establish a primary motion."," In any state change, one element carries the meaning: the dialog appearing, the item being deleted, the card expanding. Give it the most noticeable motion — the longest duration in the change, the most travel. Everything else is secondary and should be quieter: shorter, smaller, or a fade rather than a move.",[14,2125,2126,2129,2130,2133],{},[31,2127,2128],{},"Sequence by cause and effect."," If opening a panel causes its content to load, the panel moves first and the content follows. A delay of 40 to 80 milliseconds between the primary and secondary motions is enough for the eye to register the order without the sequence feeling slow. Custom properties make delays systematic: ",[50,2131,2132],{},"--motion-delay-secondary: 60ms"," on the root, referenced by every secondary animation.",[14,2135,2136,2139],{},[31,2137,2138],{},"Share direction."," Elements that move as part of the same change should move in compatible directions. A drawer sliding in from the right whose contents fade upward reads as two unrelated events; contents that shift slightly from the right, following the drawer, read as one.",[14,2141,2142,2145],{},[31,2143,2144],{},"Keep the total short."," Choreography adds delays, and delays add up. Budget the whole sequence — primary motion plus the last secondary motion's delay and duration — to stay under about half a second for routine interactions. If it does not fit, reduce the number of animated elements rather than speeding each one up; fewer, clearer motions beat many rushed ones.",[14,2147,2148,2151],{},[31,2149,2150],{},"Let reduced motion collapse the sequence."," When motion is reduced, delays become pointless waiting. The token approach handles this naturally if delays are tokens too: set them to zero in the reduced-motion media query along with the movement durations.",[68,2153,2155],{"id":2154},"integration-with-adjacent-css","Integration With Adjacent CSS",[14,2157,2158,2165,2166,2168,2169,2173],{},[31,2159,2160,2161,2164],{},"Custom properties and ",[50,2162,2163],{},"@property","."," Easing tokens are ordinary custom properties, but values that should themselves animate — a colour, an angle, a length — need registration with ",[50,2167,2163],{}," so the browser can interpolate them. The ",[23,2170,2172],{"href":2171},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002F","CSS custom properties architecture"," section covers where tokens live and how registered properties behave.",[14,2175,2176,2179,2180,2183],{},[31,2177,2178],{},"Container queries."," Duration can depend on the space a component has, since larger containers mean longer travel. Container query units inside ",[50,2181,2182],{},"clamp()"," produce durations that grow with the component and stay bounded.",[14,2185,2186,2189,2190,2192,2193,2164],{},[31,2187,2188],{},"Scroll-driven animations."," When progress comes from scroll position, easing works differently: the timing function still applies, but it warps the relationship between scroll distance and motion. Most scroll-linked effects use ",[50,2191,85],{}," and shape the motion with keyframe offsets and ",[50,2194,2195],{},"animation-range",[14,2197,2198,2201,2202,2205],{},[31,2199,2200],{},"View transitions."," The pseudo-elements of a view transition animate with ordinary ",[50,2203,2204],{},"animation"," properties, so the same easing and duration tokens apply to page-level transitions. Using them keeps page transitions consistent with component motion.",[14,2207,2208,2211,2212,2215],{},[31,2209,2210],{},"Cascade layers."," A dedicated ",[50,2213,2214],{},"motion"," layer for easing tokens and reduced-motion overrides keeps motion policy in one place and guarantees the overrides win over component styles regardless of specificity.",[65,2217],{},[68,2219,2221],{"id":2220},"performance-and-accessibility-notes","Performance and Accessibility Notes",[14,2223,2224,2227,2228,2230,2231,2234,2235,368,2238,368,2241,233,2243,2245,2246,2164],{},[31,2225,2226],{},"Easing does not change cost."," A spring or a Bezier curve costs the same per frame as ",[50,2229,85],{},"; the work is in interpolating and rendering the property. Choose curves for feel, and choose ",[18,2232,2233],{},"properties"," for performance — ",[50,2236,2237],{},"transform",[50,2239,2240],{},"translate",[50,2242,1870],{},[50,2244,1678],{}," stay on the compositor, as covered in ",[23,2247,2249],{"href":2248},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Foptimizing-css-animations-for-60fps\u002F","Optimizing CSS Animations for 60fps",[14,2251,2252,2255],{},[31,2253,2254],{},"Overshoot is extra motion."," Springs, bounces and overshoot add movement beyond what the state change requires, which is precisely what users with vestibular disorders ask to avoid. Reduced-motion variants should drop them entirely.",[14,2257,2258,2261],{},[31,2259,2260],{},"Durations affect usability, not just feel."," Long entrances delay access to content; long exits keep stale content on screen. Routine transitions should stay under about 400 milliseconds.",[14,2263,2264,2267],{},[31,2265,2266],{},"Loops need pause mechanisms."," Anything that animates automatically for more than five seconds needs a way to pause it under WCAG 2.2.2, regardless of how gentle its easing is.",[14,2269,2270,2273],{},[31,2271,2272],{},"Motion should never be the only signal."," A state conveyed only by movement — a shake to indicate an error, a bounce to mark a new item — is lost on users who have motion disabled and on screen-reader users. Pair every meaningful motion with a persistent visual change such as colour, text or an icon, and with an accessible announcement where the change matters.",[65,2275],{},[68,2277,2279],{"id":2278},"devtools-debugging-workflow","DevTools Debugging Workflow",[2281,2282,2283,2289,2295,2308,2322],"ol",{},[38,2284,2285,2288],{},[31,2286,2287],{},"Edit curves live."," In Chrome, Edge and Firefox, click the curve icon beside any timing function in the Styles pane. The editor shows the curve, lets you drag control points, and replays a preview. Chromium's editor also offers presets grouped by family.",[38,2290,2291,2294],{},[31,2292,2293],{},"Slow everything down."," The Animations panel in Chromium and Firefox can play all animations at 25% or 10% speed. Many easing problems — a curve that starts too slowly, an overshoot that is too large — are invisible at full speed and obvious at a quarter.",[38,2296,2297,2304,2305,2307],{},[31,2298,2299,2300,2303],{},"Inspect ",[50,2301,2302],{},"linear()"," points."," Chromium's easing editor renders ",[50,2306,2302],{}," values as their polyline, which makes it easy to spot a generator mistake such as a point out of order.",[38,2309,2310,2313,2314,2317,2318,2321],{},[31,2311,2312],{},"Check tokens resolve."," In the Computed pane, a transition using ",[50,2315,2316],{},"var(--motion-enter)"," shows the resolved duration and curve. If it shows ",[50,2319,2320],{},"0s ease",", a token is undefined.",[38,2323,2324,2327,2328,2331],{},[31,2325,2326],{},"Emulate reduced motion."," Use the Rendering drawer in Chromium, or Firefox's accessibility settings, to emulate ",[50,2329,2330],{},"prefers-reduced-motion: reduce"," and confirm the whole system switches.",[65,2333],{},[68,2335,2337],{"id":2336},"browser-compatibility","Browser Compatibility",[389,2339,2340,2356],{},[392,2341,2342],{},[395,2343,2344,2347,2350,2353],{},[398,2345,2346],{},"Feature",[398,2348,2349],{},"Chrome \u002F Edge",[398,2351,2352],{},"Firefox",[398,2354,2355],{},"Safari",[408,2357,2358,2375,2390,2406,2425,2440],{},[395,2359,2360,2366,2369,2372],{},[413,2361,2362,233,2364],{},[50,2363,952],{},[50,2365,52],{},[413,2367,2368],{},"26+ \u002F 12+",[413,2370,2371],{},"16+",[413,2373,2374],{},"9+",[395,2376,2377,2383,2386,2388],{},[413,2378,2379,2382],{},[50,2380,2381],{},"@keyframes"," and per-keyframe timing",[413,2384,2385],{},"43+ \u002F 12+",[413,2387,2371],{},[413,2389,2374],{},[395,2391,2392,2397,2400,2403],{},[413,2393,2394,2396],{},[50,2395,2302],{}," easing",[413,2398,2399],{},"113+",[413,2401,2402],{},"112+",[413,2404,2405],{},"17.2+",[395,2407,2408,2418,2421,2423],{},[413,2409,2410,2413,2414,2417],{},[50,2411,2412],{},"steps()"," with ",[50,2415,2416],{},"jump-*"," positions",[413,2419,2420],{},"Supported in current versions",[413,2422,2420],{},[413,2424,2420],{},[395,2426,2427,2431,2434,2437],{},[413,2428,2429],{},[50,2430,62],{},[413,2432,2433],{},"74+ \u002F 79+",[413,2435,2436],{},"63+",[413,2438,2439],{},"10.1+",[395,2441,2442,2448,2451,2454],{},[413,2443,2444,2447],{},[50,2445,2446],{},":has()"," (segmented control example)",[413,2449,2450],{},"105+",[413,2452,2453],{},"121+",[413,2455,2456],{},"15.4+",[14,2458,2459,2460,2462,2463,2465,2466,2468],{},"For ",[50,2461,2302],{},", declare a ",[50,2464,52],{}," fallback before the ",[50,2467,2302],{}," value; older engines keep the fallback.",[65,2470],{},[68,2472,2474],{"id":2473},"common-pitfalls","Common Pitfalls",[389,2476,2477,2490],{},[392,2478,2479],{},[395,2480,2481,2484,2487],{},[398,2482,2483],{},"Pitfall",[398,2485,2486],{},"Cause",[398,2488,2489],{},"Resolution",[408,2491,2492,2508,2519,2537,2550],{},[395,2493,2494,2497,2505],{},[413,2495,2496],{},"Everything feels sluggish",[413,2498,2499,2501,2502,2504],{},[50,2500,422],{}," or ",[50,2503,425],{}," on entrances",[413,2506,2507],{},"Use a decelerating curve for arrivals",[395,2509,2510,2513,2516],{},[413,2511,2512],{},"Menu lingers after closing",[413,2514,2515],{},"Exit uses the same duration as entry",[413,2517,2518],{},"Shorter exit via the base state's transition",[395,2520,2521,2524,2529],{},[413,2522,2523],{},"Overshoot invisible on fades",[413,2525,2526,2528],{},[50,2527,1678],{}," is clamped to 0–1",[413,2530,2531,2532,2501,2534,2536],{},"Overshoot ",[50,2533,2240],{},[50,2535,1870],{}," instead",[395,2538,2539,2542,2545],{},[413,2540,2541],{},"Sprite slides between frames",[413,2543,2544],{},"Step count does not match distance",[413,2546,2547],{},[50,2548,2549],{},"steps(distance ÷ frame size)",[395,2551,2552,2555,2558],{},[413,2553,2554],{},"Scroll animation lags the scroll",[413,2556,2557],{},"Non-linear easing on a scroll timeline",[413,2559,2560,2561,2563],{},"Use ",[50,2562,85],{},"; shape with keyframe offsets",[65,2565],{},[68,2567,2569],{"id":2568},"faq","FAQ",[14,2571,2572,2575],{},[31,2573,2574],{},"What is the difference between easing and duration?","\nDuration is how long the motion takes. Easing is how progress is distributed across that time: whether it starts fast or slow, whether it overshoots, whether it moves in steps. Two animations with the same duration can feel completely different because of their easing.",[14,2577,2578,2581],{},[31,2579,2580],{},"How many easing curves should a design system have?","\nUsually three to five: a standard ease-out for most entrances and state changes, an ease-in for exits, a symmetric ease-in-out for elements that move between two on-screen positions, and optionally one expressive curve with overshoot or a spring for emphasis.",[14,2583,2584,2593,2594,2596,2597,2600,2601,2603,2604,2606],{},[31,2585,2586,2587,2589,2590,2592],{},"Why does ",[50,2588,422],{}," feel different from ",[50,2591,89],{},"?","\nThe ",[50,2595,422],{}," keyword is ",[50,2598,2599],{},"cubic-bezier(0.25, 0.1, 0.25, 1)",", which starts slightly slowly, accelerates, then decelerates. ",[50,2602,89],{}," starts at full speed. For entrances, ",[50,2605,89],{}," feels more responsive because motion is visible from the first frame.",[14,2608,2609,2612,2613,2615],{},[31,2610,2611],{},"Should scroll-driven animations use easing?","\nUsually ",[50,2614,85],{},". A scroll timeline maps scroll position to progress, and a non-linear timing function distorts that mapping so the element moves at a different rate from the scroll. Shape the motion with keyframe offsets instead.",[14,2617,2618,2621],{},[31,2619,2620],{},"How should motion design handle reduced-motion preferences?","\nTreat reduced motion as a first-class variant of the design, not an afterthought. Movement, scaling, parallax and bounce are removed or replaced with short fades, and duration tokens let the whole system switch with one media query.",[68,2623,2625],{"id":2624},"related","Related",[35,2627,2628,2633,2638,2643,2648,2653,2660],{},[38,2629,2630,2632],{},[23,2631,227],{"href":226}," — the duration scale in depth.",[38,2634,2635,2637],{},[23,2636,232],{"href":231}," — expressive single curves.",[38,2639,2640,2642],{},[23,2641,237],{"href":236}," — physical motion in pure CSS.",[38,2644,2645,2647],{},[23,2646,242],{"href":241}," — frame-by-frame effects.",[38,2649,2650,2652],{},[23,2651,247],{"href":246}," — asymmetric transitions.",[38,2654,2655,2659],{},[23,2656,2658],{"href":2657},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fcss-transition-timing-functions\u002F","CSS Transition Timing Functions"," — the built-in curves.",[38,2661,2662,2666],{},[23,2663,2665],{"href":2664},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-space-scale-with-clamp\u002F","Fluid Space Scale With clamp()"," — the spatial scale motion tokens can mirror.",[2668,2669,2670],"style",{},"html pre.shiki code .s-5SL, html code.shiki .s-5SL{--shiki-default:#023B95;--shiki-dark:#91CBFF}html pre.shiki code .suds8, html code.shiki .suds8{--shiki-default:#0E1116;--shiki-dark:#F0F3F6}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);}html pre.shiki code .sHUrx, html code.shiki .sHUrx{--shiki-default:#A0111F;--shiki-dark:#FF9492}html pre.shiki code .sne4z, html code.shiki .sne4z{--shiki-default:#024C1A;--shiki-dark:#72F088}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}",{"title":553,"searchDepth":570,"depth":570,"links":2672},[2673,2677,2678,2685,2686,2687,2688,2689,2690,2691,2692,2693],{"id":70,"depth":570,"text":71,"children":2674},[2675,2676],{"id":252,"depth":606,"text":253},{"id":345,"depth":606,"text":346},{"id":386,"depth":570,"text":387},{"id":541,"depth":570,"text":542,"children":2679},[2680,2681,2682,2683,2684],{"id":545,"depth":606,"text":546},{"id":703,"depth":606,"text":704},{"id":795,"depth":606,"text":796},{"id":935,"depth":606,"text":936},{"id":1018,"depth":606,"text":1019},{"id":1118,"depth":570,"text":1119},{"id":2113,"depth":570,"text":2114},{"id":2154,"depth":570,"text":2155},{"id":2220,"depth":570,"text":2221},{"id":2278,"depth":570,"text":2279},{"id":2336,"depth":570,"text":2337},{"id":2473,"depth":570,"text":2474},{"id":2568,"depth":570,"text":2569},{"id":2624,"depth":570,"text":2625},"Design UI motion that feels intentional: timing functions as a system, duration and easing tokens, overshoot, springs, steps and entry versus exit timing.","md",{"pageTitle":2697,"datePublished":2698,"dateModified":2698,"faq":2699},"Easing and Motion Design in CSS","2026-09-18",[2700,2702,2704,2707,2709],{"q":2574,"a":2701},"Duration is how long the motion takes. Easing is how progress is distributed across that time: whether it starts fast or slow, whether it overshoots, whether it moves in steps. Two animations with the same duration can feel completely different because of their easing.",{"q":2580,"a":2703},"Usually three to five: a standard ease-out for most entrances and state changes, an ease-in for exits, a symmetric ease-in-out for elements that move between two on-screen positions, and optionally one expressive curve with overshoot or a spring for emphasis.",{"q":2705,"a":2706},"Why does ease feel different from ease-out?","The ease keyword is cubic-bezier(0.25, 0.1, 0.25, 1), which starts slightly slowly, accelerates, then decelerates. ease-out starts at full speed. For entrances, ease-out feels more responsive because motion is visible from the first frame.",{"q":2611,"a":2708},"Usually linear. A scroll timeline maps scroll position to progress, and a non-linear timing function distorts that mapping so the element moves at a different rate from the scroll. Shape the motion with keyframe offsets instead.",{"q":2620,"a":2710},"Treat reduced motion as a first-class variant of the design, not an afterthought. Movement, scaling, parallax and bounce are removed or replaced with short fades, and duration tokens let the whole system switch with one media query.","\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design",{"title":5,"description":2694},"css-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Findex","gz0DA4FA7f1lbZyJyIllnluHHoemrGZYBOJhDLrVuPA",[2716,2719,2722,2725,2728,2731,2734,2737,2740,2743,2746,2749,2752,2755,2758,2761,2764,2767,2770,2773,2776,2779,2782,2785,2788,2791,2794,2797,2800,2803,2806,2809,2812,2815,2818,2821,2824,2827,2830,2833,2836,2839,2842,2845,2848,2851,2854,2857,2860,2863,2866,2869,2870,2873,2876,2879,2882,2885,2888,2891,2894,2897,2900,2903,2906,2909,2912,2915,2918,2921,2924,2927,2930,2933,2936,2939,2942,2945,2948,2951,2954,2957,2960,2963,2966,2969,2972,2975,2978,2981,2984,2987,2990,2993,2996,2999,3002,3005,3008,3011,3014,3017,3020,3023,3026,3029,3032,3035,3038,3041,3044,3047,3050,3053,3056,3059,3062,3065,3068,3071,3074,3077,3080,3083,3086,3089,3092,3095,3098,3101,3104,3107,3110,3113,3116,3119,3122,3125,3128,3131,3134,3137,3140,3143,3146,3149,3152,3155,3158,3161,3164,3167,3170,3173,3176,3179,3182,3185,3188,3191,3194,3197,3200,3203,3206,3209,3212,3215,3218,3221,3224,3227,3230,3233,3236,3239,3242,3245,3248,3251,3254,3257,3260,3263,3266,3269,3272],{"path":2717,"title":2718},"\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":2720,"title":2721},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fflashing-content-and-seizure-thresholds","Flashing Content and Seizure Thresholds",{"path":2723,"title":2724},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fforced-colors-mode-and-animations","Forced Colors Mode and Animations",{"path":2726,"title":2727},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations","Accessibility in CSS Animations: Patterns, Specs & Best Practices",{"path":2729,"title":2730},"\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":2732,"title":2733},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fprefers-reduced-motion-recipes","prefers-reduced-motion Recipes: A Reduction for Every Common Effect",{"path":2735,"title":2736},"\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":2738,"title":2739},"\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":2741,"title":2742},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fvestibular-safe-animation-patterns","Vestibular-Safe Animation Patterns: Why Some Motion Makes People Sick",{"path":2744,"title":2745},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fwcag-motion-success-criteria","WCAG Motion Success Criteria: What Each One Actually Requires",{"path":2747,"title":2748},"\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":2750,"title":2751},"\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":2753,"title":2754},"\u002Fcss-only-micro-interactions-animations\u002Fclip-path-and-mask-animations","Clip-Path & Mask Animations: Animating Visibility Instead of Position",{"path":2756,"title":2757},"\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":2759,"title":2760},"\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":2762,"title":2763},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions\u002Fanimating-gradients","Animating CSS Gradients: Smooth Colour Motion Without Jumps",{"path":2765,"title":2766},"\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":2768,"title":2769},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions","Color & Theme Transitions: Colour as Part of the Motion System",{"path":2771,"title":2772},"\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":2774,"title":2775},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions\u002Fsmooth-theme-switching-transitions","Smooth Theme Switching: Crossfades, Circular Reveals and No Flash",{"path":2777,"title":2778},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fcontainer-query-hover-affordances","Container Query Hover Affordances: When Narrow Means Persistent, Not Hidden",{"path":2780,"title":2781},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion","Container-Aware Motion: Animation Sized by the Space a Component Actually Has",{"path":2783,"title":2784},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Flayout-change-animations-at-container-breakpoints","Animating Changes at Container Breakpoints",{"path":2786,"title":2787},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fmotion-driven-by-container-style-queries","Motion Driven by Container Style Queries",{"path":2789,"title":2790},"\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":2792,"title":2793},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fsuppressing-motion-in-small-containers","Suppressing Motion in Small Containers: Deliberately Animating Nothing",{"path":2795,"title":2796},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api\u002Fcontrolling-css-animations-from-javascript","Controlling CSS Animations From JavaScript",{"path":2798,"title":2799},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api","CSS Animation vs the Web Animations API: A Decision Guide",{"path":2801,"title":2802},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api\u002Fwaapi-vs-css-for-interruptible-ui","Interruptible UI: CSS Transitions vs WAAPI",{"path":2804,"title":2805},"\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":2807,"title":2808},"\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":2810,"title":2811},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Fcustom-property-fallbacks-and-invalid-values","Custom Property Fallbacks and Invalid Values",{"path":2813,"title":2814},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Ffluid-spacing-tokens-driving-transition-durations","Fluid Spacing Tokens That Drive Transition Durations",{"path":2816,"title":2817},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture","CSS Custom Properties Architecture: Scalable Design Systems & Dynamic UI",{"path":2819,"title":2820},"\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":2822,"title":2823},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Fscoping-custom-properties-to-components","Scoping Custom Properties to Components",{"path":2825,"title":2826},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fcss-transition-timing-functions","CSS Transition Timing Functions: ease, cubic-bezier(), steps() and linear()",{"path":2828,"title":2829},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals","CSS Transition Fundamentals: Architecture, Performance & Patterns",{"path":2831,"title":2832},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Finterrupted-and-reversing-transitions","Interrupted and Reversing Transitions: What Happens Mid-Flight",{"path":2834,"title":2835},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fstarting-style-entry-animations","@starting-style: Animating an Element's Very First Style Change",{"path":2837,"title":2838},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransition-delay-choreography","Choreographing Motion With transition-delay",{"path":2840,"title":2841},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransition-shorthand-and-multiple-properties","The transition Shorthand and Multiple Properties",{"path":2843,"title":2844},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransitioning-display-with-allow-discrete","Transitioning display with transition-behavior: allow-discrete and @starting-style",{"path":2846,"title":2847},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Fanimating-dialog-open-and-close","Animating \u003Cdialog> Open and Close: Both Directions, No Library",{"path":2849,"title":2850},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Fbackdrop-animations","Animating ::backdrop: Fades and Blurs Behind Dialogs and Popovers",{"path":2852,"title":2853},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations","Dialog & Popover Animations: Motion for the Top Layer",{"path":2855,"title":2856},"\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":2858,"title":2859},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Fpopover-entry-and-exit-transitions","Popover Menus That Animate From Their Anchor",{"path":2861,"title":2862},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fchoosing-animation-durations","Choosing Animation Durations: How Long Motion Should Last",{"path":2864,"title":2865},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fcubic-bezier-overshoot-and-anticipation","Overshoot and Anticipation With cubic-bezier(): Motion With Character",{"path":2867,"title":2868},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fentry-vs-exit-easing","Entry vs Exit Easing: Different Curves for Arriving and Leaving",{"path":2711,"title":5},{"path":2871,"title":2872},"\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":2874,"title":2875},"\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":2877,"title":2878},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Faccessible-css-only-tooltips","Accessible CSS-Only Tooltips and Hover Cards With  and ",{"path":2880,"title":2881},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Fbutton-press-and-active-states","Button Press and  States",{"path":2883,"title":2884},"\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":2886,"title":2887},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Ffocus-within-form-patterns"," Form Patterns: Styling a Group From the Field Inside It",{"path":2889,"title":2890},"\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":2892,"title":2893},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design","Hover & Focus State Design: Spec-Compliant Patterns for Modern UIs",{"path":2895,"title":2896},"\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":2898,"title":2899},"\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":2901,"title":2902},"\u002Fcss-only-micro-interactions-animations","CSS-Only Micro-Interactions & Animations: Architecture, Performance & Implementation",{"path":2904,"title":2905},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fanimation-composition-and-stacking","Stacking Animations With animation-composition",{"path":2907,"title":2908},"\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":2910,"title":2911},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcontainer-query-triggered-keyframe-animations","Container-Query-Triggered Keyframe Animations: Animate Differently per Available Space",{"path":2913,"title":2914},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcss-only-accordions-and-disclosure","CSS-Only Accordions and Disclosure Widgets with details and summary",{"path":2916,"title":2917},"\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":2919,"title":2920},"\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":2922,"title":2923},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns","Keyframe Animation Patterns: Spec-Compliant Architectures for Modern UIs",{"path":2925,"title":2926},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fmulti-step-keyframes-and-per-keyframe-easing","Multi-Step Keyframes and Per-Keyframe Easing",{"path":2928,"title":2929},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fstaggered-list-animations-with-custom-properties","Staggered List Animations Using --i Index Custom Properties",{"path":2931,"title":2932},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fanimating-box-shadow-and-filters-cheaply","Animating box-shadow and Filters Cheaply",{"path":2934,"title":2935},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fcontain-property-for-animation-performance","The contain Property for Animation Performance",{"path":2937,"title":2938},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fcss-triggers-layout-paint-composite","Layout, Paint and Composite: What Triggers What",{"path":2940,"title":2941},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration","Performance & GPU Acceleration in CSS: A Developer’s Blueprint",{"path":2943,"title":2944},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Foptimizing-css-animations-for-60fps","Optimizing CSS Animations for 60fps: Budgeting the Frame",{"path":2946,"title":2947},"\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":2949,"title":2950},"\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":2952,"title":2953},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations","Scroll-Driven Animations: Binding Motion to Scroll Position in Pure CSS",{"path":2955,"title":2956},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-driven-animation-fallbacks","Shipping Scroll-Driven Animations Without Breaking Anything",{"path":2958,"title":2959},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-driven-parallax-effects","Scroll-Driven Parallax Effects in CSS",{"path":2961,"title":2962},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-progress-bar-without-javascript","A Reading Progress Bar Driven by scroll(root)",{"path":2964,"title":2965},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-triggered-reveal-animations","Reveal-on-Scroll with view() and animation-range",{"path":2967,"title":2968},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Ftimeline-scope-for-cross-element-animations","timeline-scope for Cross-Element Animations",{"path":2970,"title":2971},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fview-timeline-and-animation-range","View Timelines and animation-range",{"path":2973,"title":2974},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fcross-document-view-transitions","Cross-Document View Transitions",{"path":2976,"title":2977},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers","View Transitions for CSS Developers: the Pseudo-Element Tree, Snapshots, and Named Elements",{"path":2979,"title":2980},"\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":2982,"title":2983},"\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":2985,"title":2986},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transition-types-and-classes","View Transition Types and Classes",{"path":2988,"title":2989},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transitions-for-list-reordering","View Transitions for List Reordering",{"path":2991,"title":2992},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transitions-with-reduced-motion","Honouring prefers-reduced-motion in View Transitions",{"path":2994,"title":2995},"\u002F","Modern CSS Layouts & Micro-Interactions",{"path":2997,"title":2998},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-positioned-tooltips","Anchor-Positioned Tooltips: Tethering, Flipping, and Getting the Semantics Right",{"path":3000,"title":3001},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-positioning-fallbacks","Anchor Positioning Fallbacks: A Graceful Floor for Older Browser Versions",{"path":3003,"title":3004},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-size-for-matching-widths","anchor-size(): Overlays That Match Their Trigger's Size",{"path":3006,"title":3007},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays","CSS Anchor Positioning and Overlays: Tethering Elements Without JavaScript",{"path":3009,"title":3010},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fpopover-attribute-and-css-styling","The popover Attribute: Top-Layer Overlays With No JavaScript",{"path":3012,"title":3013},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fpopover-light-dismiss-and-stacking","Popover Light Dismiss, Nesting and Stacking",{"path":3015,"title":3016},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fposition-area-grid-explained","position-area: The Anchor Placement Grid",{"path":3018,"title":3019},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fcontainer-query-polyfill-tradeoffs","Container Query Polyfills: What They Cost and When to Skip Them",{"path":3021,"title":3022},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Ffeature-detection-with-supports","Feature Detection with @supports: Syntax, Semantics, and the Traps",{"path":3024,"title":3025},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fhandling-container-query-fallbacks-for-older-browsers","Handling Container Query Fallbacks for Older Browsers",{"path":3027,"title":3028},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks","Container Query Fallbacks: Spec-Compliant CSS Strategies for Legacy Browsers",{"path":3030,"title":3031},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fintrinsic-layout-fallbacks-without-queries","Intrinsic Layout Fallbacks: Baselines That Adapt Without Any Query",{"path":3033,"title":3034},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Ftesting-fallbacks-without-old-browsers","Testing CSS Fallbacks Without an Old Browser",{"path":3036,"title":3037},"\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":3039,"title":3040},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-query-range-and-logic-operators","Container Query Range Syntax and Logic Operators",{"path":3042,"title":3043},"\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":3045,"title":3046},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-type-size-vs-inline-size","Choosing container-type: inline-size, size, or normal",{"path":3048,"title":3049},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-vs-media-queries-comparison","Container vs Media Queries: Choosing the Right Reference Box",{"path":3051,"title":3052},"\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":3054,"title":3055},"\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":3057,"title":3058},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics","Container Query Syntax Basics",{"path":3060,"title":3061},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fnesting-and-naming-container-queries","Nesting and Naming Container Queries: Targeting the Right Ancestor",{"path":3063,"title":3064},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fauto-fit-minmax-responsive-grids","Responsive Grids with repeat(auto-fit, minmax())",{"path":3066,"title":3067},"\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":3069,"title":3070},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fgrid-auto-flow-dense-packing","grid-auto-flow: dense for Packed Layouts",{"path":3072,"title":3073},"\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":3075,"title":3076},"\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":3078,"title":3079},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts","CSS Grid and Subgrid Layouts for Responsive Interfaces",{"path":3081,"title":3082},"\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":3084,"title":3085},"\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":3087,"title":3088},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fsubgrid-vs-nested-grid","Subgrid vs an Independently Nested Grid",{"path":3090,"title":3091},"\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":3093,"title":3094},"\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":3096,"title":3097},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflex-grow-and-flex-shrink-explained","flex-grow and flex-shrink Explained",{"path":3099,"title":3100},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflex-wrap-intrinsic-responsive-rows","Breakpoint-Free Responsive Rows With flex-wrap and flex-basis",{"path":3102,"title":3103},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflexbox-gap-and-spacing","Flexbox gap vs Margins: Spacing Items Without Edge Hacks",{"path":3105,"title":3106},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns","Flexbox Layout Patterns: One-Dimensional Layout for Real Components",{"path":3108,"title":3109},"\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":3111,"title":3112},"\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":3114,"title":3115},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Fdebugging-clamp-values","Debugging clamp(): Values That Are Ignored, Stuck or Never Fluid",{"path":3117,"title":3118},"\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":3120,"title":3121},"\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":3123,"title":3124},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-type-accessibility-and-zoom","Fluid Type, Accessibility and Zoom: The vw-Only Trap",{"path":3126,"title":3127},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-typography-without-javascript","Fluid Typography Without JavaScript: A Precision CSS Reference",{"path":3129,"title":3130},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp","Fluid Typography with clamp(): A Practical Guide for Modern CSS",{"path":3132,"title":3133},"\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":3135,"title":3136},"\u002Fmastering-container-queries-responsive-layouts","Mastering Container Queries & Responsive Layouts",{"path":3138,"title":3139},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Faspect-ratio-for-responsive-media","Using aspect-ratio for Responsive Media and Preventing Layout Shift",{"path":3141,"title":3142},"\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":3144,"title":3145},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques","Intrinsic Sizing Techniques: Modern CSS Layouts for Responsive UI",{"path":3147,"title":3148},"\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":3150,"title":3151},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fmin-max-fit-content-explained","min-content, max-content, and fit-content() Explained",{"path":3153,"title":3154},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fobject-fit-and-object-position","object-fit and object-position: Images That Fit Any Box",{"path":3156,"title":3157},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fpreventing-flex-and-grid-overflow","The min-width: auto Trap in Flex and Grid Layouts",{"path":3159,"title":3160},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-for-reset-and-tokens","Cascade Layers for Reset and Design Tokens",{"path":3162,"title":3163},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-vs-specificity-hacks","Cascade Layers vs Specificity Hacks: Ordering Instead of Escalating",{"path":3165,"title":3166},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcss-scope-for-component-styles","@scope for Component Styles: Short Selectors That Cannot Leak",{"path":3168,"title":3169},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies","Modern CSS Reset Strategies: A Spec-Compliant Foundation",{"path":3171,"title":3172},"\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":3174,"title":3175},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fwriting-a-minimal-modern-reset","Writing a Minimal Modern CSS Reset: Every Line Justified",{"path":3177,"title":3178},"\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":3180,"title":3181},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has\u002Fempty-and-loading-states-with-has","Empty and Loading States With ()",{"path":3183,"title":3184},"\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":3186,"title":3187},"\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":3189,"title":3190},"\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":3192,"title":3193},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has","Parent-Aware Layouts With :has(): Letting Containers React to Their Contents",{"path":3195,"title":3196},"\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":3198,"title":3199},"\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":3201,"title":3202},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fcontainer-query-data-tables","Container Query Data Tables: Reflowing Tables to Cards",{"path":3204,"title":3205},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fcontainer-query-sidebar-layouts","Container Query Sidebar Layouts That Travel Between Contexts",{"path":3207,"title":3208},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns","Responsive Component Patterns: Architecture & Implementation",{"path":3210,"title":3211},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-forms-with-container-queries","Responsive Forms with Container Queries: Reflow Without Losing the Wiring",{"path":3213,"title":3214},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-hero-sections-with-container-queries","Responsive Hero Sections With Container Queries",{"path":3216,"title":3217},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-navigation-without-media-queries","Responsive Navigation Without Media Queries Using Container Queries",{"path":3219,"title":3220},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-pricing-tables","Responsive Pricing Tables: Aligned Features, a Clear Recommendation, Any Width",{"path":3222,"title":3223},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Ftabs-that-become-accordions","Tabs That Become an Accordion: One Component, Two Layouts",{"path":3225,"title":3226},"\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts\u002Fcss-only-carousel-with-scroll-snap","A CSS-Only Carousel With Scroll Snap",{"path":3228,"title":3229},"\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":3231,"title":3232},"\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts","Scroll Snap & Overflow Layouts: Designing Components That Scroll on Purpose",{"path":3234,"title":3235},"\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":3237,"title":3238},"\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":3240,"title":3241},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fcombining-size-and-style-queries","Combining Size and Style Container Queries",{"path":3243,"title":3244},"\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":3246,"title":3247},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state","Style Queries and Container State: Token-Driven Component Variants",{"path":3249,"title":3250},"\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":3252,"title":3253},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fstyle-query-component-variants","Component Variants With Style Queries: One Token, Many Looks",{"path":3255,"title":3256},"\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":3258,"title":3259},"\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":3261,"title":3262},"\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":3264,"title":3265},"\u002Fmastering-container-queries-responsive-layouts\u002Fviewport-units-and-mobile-layout","Viewport Units & Mobile Layout: Designing for the Screen You Actually Get",{"path":3267,"title":3268},"\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":3270,"title":3271},"\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":3273,"title":3274},"\u002Fmastering-container-queries-responsive-layouts\u002Fviewport-units-and-mobile-layout\u002Fvirtual-keyboard-and-interactive-widget","Layouts That Survive the Virtual Keyboard",{"title":3276,"caption":3277,"height":3278,"html":3279,"css":3280},"Segmented control with a symmetric sliding indicator","Click an option or use the arrow keys: the indicator slides with an ease-in-out, the label colour eases out, and presses give instant feedback.",150,"\n\u003Cfieldset class=\"segmented\">\n  \u003Clegend class=\"visually-hidden\">View\u003C\u002Flegend>\n  \u003Clabel>\u003Cinput type=\"radio\" name=\"view\" value=\"day\" checked>\u003Cspan>Day\u003C\u002Fspan>\u003C\u002Flabel>\n  \u003Clabel>\u003Cinput type=\"radio\" name=\"view\" value=\"week\">\u003Cspan>Week\u003C\u002Fspan>\u003C\u002Flabel>\n  \u003Clabel>\u003Cinput type=\"radio\" name=\"view\" value=\"month\">\u003Cspan>Month\u003C\u002Fspan>\u003C\u002Flabel>\n  \u003Cspan class=\"segmented__indicator\" aria-hidden=\"true\">\u003C\u002Fspan>\n\u003C\u002Ffieldset>","\n:root {\n  --motion-enter: 240ms cubic-bezier(0.22, 1, 0.36, 1);\n  --motion-move: 240ms cubic-bezier(0.65, 0, 0.35, 1);\n  --motion-feedback: 90ms linear;\n}\n.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }\n.segmented { --count: 3; --index: 0; position: relative; display: grid; grid-template-columns: repeat(var(--count), 1fr); width: min(100%, 22rem); margin: 0; padding: 0.25rem; border: 0; border-radius: 10px; background: var(--demo-surface); outline: 1px solid var(--demo-border); }\n.segmented:has(input[value=\"week\"]:checked) { --index: 1; }\n.segmented:has(input[value=\"month\"]:checked) { --index: 2; }\n.segmented label { position: relative; z-index: 1; text-align: center; cursor: pointer; }\n.segmented input { position: absolute; opacity: 0; }\n.segmented span { display: block; padding: 0.4rem 0.75rem; color: var(--demo-muted); transition: color var(--motion-enter); }\n.segmented input:checked + span { color: var(--demo-fg); font-weight: 600; }\n.segmented input:focus-visible + span { outline: 2px solid var(--demo-accent); outline-offset: 2px; border-radius: 6px; }\n.segmented label:active span { scale: 0.96; transition: scale var(--motion-feedback); }\n.segmented__indicator { position: absolute; inset-block: 0.25rem; left: 0.25rem; width: calc((100% - 0.5rem) \u002F var(--count)); border-radius: 8px; background: var(--demo-bg); box-shadow: 0 1px 3px rgb(15 23 42 \u002F 0.2); translate: calc(var(--index) * 100%) 0; transition: translate var(--motion-move); }\n@media (prefers-reduced-motion: reduce) { .segmented__indicator, .segmented span { transition: none; } }",1789717745536]