[{"data":1,"prerenderedAt":1498},["ShallowReactive",2],{"page-\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fcontain-property-for-animation-performance":3,"content-all-pages":933,"live-demo:contain-paint-clip":1492},{"id":4,"title":5,"body":6,"description":916,"extension":917,"meta":918,"navigation":389,"path":929,"seo":930,"stem":931,"__hash__":932},"content\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fcontain-property-for-animation-performance\u002Findex.md","The contain Property for Animation Performance",{"type":7,"value":8,"toc":904},"minimark",[9,13,46,51,56,119,212,216,219,223,573,579,594,598,613,617,625,698,702,705,759,771,775,789,793,799,803,819,823,829,838,860,869,873,901],[10,11,5],"h1",{"id":12},"the-contain-property-for-animation-performance",[14,15,16,17,21,22,25,26,30,31,34,35,40,41,45],"p",{},"The cheapest animations only touch ",[18,19,20],"code",{},"transform"," and ",[18,23,24],{},"opacity",". Real interfaces cannot always stay inside that pair: a widget whose content changes size, a live-updating counter, an accordion that genuinely pushes content down, a loading placeholder whose text swaps in. Each triggers layout or paint, and by default the browser has to assume the change ",[27,28,29],"em",{},"might"," affect anything on the page. The ",[18,32,33],{},"contain"," property removes that assumption. It is a promise from the author — \"nothing in here affects anything out there\" — that the browser uses to restrict layout and paint to one subtree. This page explains the containment types, where each helps animation, and the side effects that make containment a deliberate choice rather than a blanket optimisation. It belongs to ",[36,37,39],"a",{"href":38},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002F","Performance & GPU Acceleration"," in the ",[36,42,44],{"href":43},"\u002Fcss-only-micro-interactions-animations\u002F","CSS-Only Micro-Interactions & Animations"," guide.",[47,48,50],"h2",{"id":49},"the-containment-types","The containment types",[14,52,53,55],{},[18,54,33],{}," accepts four individual types and two shorthands:",[57,58,59,69,77,89,97,109],"ul",{},[60,61,62,68],"li",{},[63,64,65],"strong",{},[18,66,67],{},"layout"," — the element's internal layout is independent of the rest of the page. Changes inside it do not cause layout outside it. The element becomes a containing block for absolutely and fixed-positioned descendants and establishes an independent formatting context.",[60,70,71,76],{},[63,72,73],{},[18,74,75],{},"paint"," — descendants are not painted outside the element's bounds; overflow is clipped. The browser can skip painting the subtree entirely when the element is off screen.",[60,78,79,84,85,88],{},[63,80,81],{},[18,82,83],{},"size"," — the element's size is computed as if it had no children. It must get its size from elsewhere — explicit dimensions or ",[18,86,87],{},"contain-intrinsic-size",".",[60,90,91,96],{},[63,92,93],{},[18,94,95],{},"style"," — counters and quotes inside the element do not affect the outside. Rarely relevant to animation.",[60,98,99,104,105,108],{},[63,100,101],{},[18,102,103],{},"content"," — shorthand for ",[18,106,107],{},"layout paint style",". The practical default for components.",[60,110,111,104,116,88],{},[63,112,113],{},[18,114,115],{},"strict",[18,117,118],{},"size layout paint style",[120,121,127,128,127,132,127,136,127,144,127,156,127,159,127,167,127,172,127,177,127,181,127,187,127,191,127,193,127,196,127,198,127,202,127,208],"svg",{"viewBox":122,"role":123,"ariaLabel":124,"xmlns":125,"style":126},"0 0 720 300","img","A page with one contained widget: when the widget's content changes, layout and paint work stays inside its boundary instead of spreading to the rest of the page","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;height:auto;max-width:720px;margin:2rem 0","\n  ",[129,130,131],"title",{},"Containment draws a boundary around the work",[133,134,135],"desc",{},"Two page mockups. Left, without containment: a widget's content changes and highlighted work spreads across the header, sidebar and main area because the browser must check everything. Right, with contain: content on the widget: only the widget is highlighted, because layout and paint are confined to it.",[137,138,143],"text",{"textAnchor":139,"x":140,"y":141,"style":142},"middle","360","26","text-anchor:middle;fill:currentColor;font:700 17px sans-serif","Same change, smaller blast radius",[145,146],"rect",{"x":147,"y":148,"width":149,"height":150,"rx":151,"fill":152,"stroke":153,"strokeWidth":154,"opacity":155},"30","50","310","210","10","none","currentColor","1.5","0.6",[145,157],{"x":158,"y":148,"width":149,"height":150,"rx":151,"fill":152,"stroke":153,"strokeWidth":154,"opacity":155},"380",[145,160],{"x":161,"y":162,"width":163,"height":147,"rx":164,"fill":165,"opacity":166},"45","64","280","4","#7aa2ff","0.3",[145,168],{"x":161,"y":169,"width":170,"height":171,"rx":164,"fill":165,"opacity":166},"104","80","140",[145,173],{"x":174,"y":169,"width":175,"height":176,"rx":164,"fill":165,"opacity":155},"135","190","60",[145,178],{"x":174,"y":179,"width":175,"height":180,"rx":164,"fill":165,"opacity":166},"174","70",[137,182,186],{"textAnchor":139,"x":183,"y":184,"style":185},"230","139","text-anchor:middle;fill:currentColor;font:600 12px sans-serif","changing widget",[145,188],{"x":189,"y":162,"width":163,"height":147,"rx":164,"fill":153,"opacity":190},"395","0.1",[145,192],{"x":189,"y":169,"width":170,"height":171,"rx":164,"fill":153,"opacity":190},[145,194],{"x":195,"y":169,"width":175,"height":176,"rx":164,"fill":165,"opacity":155},"485",[145,197],{"x":195,"y":179,"width":175,"height":180,"rx":164,"fill":153,"opacity":190},[137,199,201],{"textAnchor":139,"x":200,"y":184,"style":185},"580","contain: content",[137,203,207],{"textAnchor":139,"x":204,"y":205,"style":206},"185","284","text-anchor:middle;fill:currentColor;font:12px sans-serif","no containment: page-wide checks",[137,209,211],{"textAnchor":139,"x":210,"y":205,"style":206},"535","contained: widget only",[47,213,215],{"id":214},"the-complete-implementation","The complete implementation",[14,217,218],{},"A live stock ticker widget whose values update and briefly flash, inside a larger dashboard. The widget's content changes size as numbers change, which would otherwise make the browser re-examine the surrounding layout on every update.",[220,221],"live-demo",{"name":222},"contain-paint-clip",[224,225,230],"pre",{"className":226,"code":227,"language":228,"meta":229,"style":229},"language-css shiki shiki-themes github-light-high-contrast github-dark-high-contrast",".ticker {\n  \u002F* Layout and paint work inside stays inside. *\u002F\n  contain: content;\n  position: relative;   \u002F* anchor for the badge without containment too *\u002F\n  \u002F* Reserve a stable box so the contained widget never resizes the page. *\u002F\n  inline-size: 100%;\n  min-block-size: 6rem;\n  padding: 1rem;\n  border-radius: 10px;\n  background: #0f172a;\n  color: #e2e8f0;\n}\n\n.ticker__value {\n  font-variant-numeric: tabular-nums;   \u002F* digits keep the same width *\u002F\n  transition: color 600ms ease-out;\n}\n\n.ticker__value.is-up   { color: #4ade80; transition-duration: 0s; }\n.ticker__value.is-down { color: #f87171; transition-duration: 0s; }\n\n\u002F* A badge that overflows the corner: clipped by paint containment. *\u002F\n.ticker__badge {\n  position: absolute;\n  inset-block-start: -0.5rem;\n  inset-inline-end: -0.5rem;\n}\n","css","",[18,231,232,245,252,266,283,289,306,322,337,352,365,378,384,391,399,415,437,442,447,480,508,513,519,527,539,554,568],{"__ignoreMap":229},[233,234,237,241],"span",{"class":235,"line":236},"line",1,[233,238,240],{"class":239},"s-5SL",".ticker",[233,242,244],{"class":243},"suds8"," {\n",[233,246,248],{"class":235,"line":247},2,[233,249,251],{"class":250},"sLBg1","  \u002F* Layout and paint work inside stays inside. *\u002F\n",[233,253,255,258,261,263],{"class":235,"line":254},3,[233,256,257],{"class":239},"  contain",[233,259,260],{"class":243},": ",[233,262,103],{"class":239},[233,264,265],{"class":243},";\n",[233,267,269,272,274,277,280],{"class":235,"line":268},4,[233,270,271],{"class":239},"  position",[233,273,260],{"class":243},[233,275,276],{"class":239},"relative",[233,278,279],{"class":243},";   ",[233,281,282],{"class":250},"\u002F* anchor for the badge without containment too *\u002F\n",[233,284,286],{"class":235,"line":285},5,[233,287,288],{"class":250},"  \u002F* Reserve a stable box so the contained widget never resizes the page. *\u002F\n",[233,290,292,295,297,300,304],{"class":235,"line":291},6,[233,293,294],{"class":239},"  inline-size",[233,296,260],{"class":243},[233,298,299],{"class":239},"100",[233,301,303],{"class":302},"sHUrx","%",[233,305,265],{"class":243},[233,307,309,312,314,317,320],{"class":235,"line":308},7,[233,310,311],{"class":239},"  min-block-size",[233,313,260],{"class":243},[233,315,316],{"class":239},"6",[233,318,319],{"class":302},"rem",[233,321,265],{"class":243},[233,323,325,328,330,333,335],{"class":235,"line":324},8,[233,326,327],{"class":239},"  padding",[233,329,260],{"class":243},[233,331,332],{"class":239},"1",[233,334,319],{"class":302},[233,336,265],{"class":243},[233,338,340,343,345,347,350],{"class":235,"line":339},9,[233,341,342],{"class":239},"  border-radius",[233,344,260],{"class":243},[233,346,151],{"class":239},[233,348,349],{"class":302},"px",[233,351,265],{"class":243},[233,353,355,358,360,363],{"class":235,"line":354},10,[233,356,357],{"class":239},"  background",[233,359,260],{"class":243},[233,361,362],{"class":239},"#0f172a",[233,364,265],{"class":243},[233,366,368,371,373,376],{"class":235,"line":367},11,[233,369,370],{"class":239},"  color",[233,372,260],{"class":243},[233,374,375],{"class":239},"#e2e8f0",[233,377,265],{"class":243},[233,379,381],{"class":235,"line":380},12,[233,382,383],{"class":243},"}\n",[233,385,387],{"class":235,"line":386},13,[233,388,390],{"emptyLinePlaceholder":389},true,"\n",[233,392,394,397],{"class":235,"line":393},14,[233,395,396],{"class":239},".ticker__value",[233,398,244],{"class":243},[233,400,402,405,407,410,412],{"class":235,"line":401},15,[233,403,404],{"class":239},"  font-variant-numeric",[233,406,260],{"class":243},[233,408,409],{"class":239},"tabular-nums",[233,411,279],{"class":243},[233,413,414],{"class":250},"\u002F* digits keep the same width *\u002F\n",[233,416,418,421,423,426,429,432,435],{"class":235,"line":417},16,[233,419,420],{"class":239},"  transition",[233,422,260],{"class":243},[233,424,425],{"class":239},"color",[233,427,428],{"class":239}," 600",[233,430,431],{"class":302},"ms",[233,433,434],{"class":239}," ease-out",[233,436,265],{"class":243},[233,438,440],{"class":235,"line":439},17,[233,441,383],{"class":243},[233,443,445],{"class":235,"line":444},18,[233,446,390],{"emptyLinePlaceholder":389},[233,448,450,453,456,458,460,463,466,469,471,474,477],{"class":235,"line":449},19,[233,451,452],{"class":239},".ticker__value.is-up",[233,454,455],{"class":243},"   { ",[233,457,425],{"class":239},[233,459,260],{"class":243},[233,461,462],{"class":239},"#4ade80",[233,464,465],{"class":243},"; ",[233,467,468],{"class":239},"transition-duration",[233,470,260],{"class":243},[233,472,473],{"class":239},"0",[233,475,476],{"class":302},"s",[233,478,479],{"class":243},"; }\n",[233,481,483,486,489,491,493,496,498,500,502,504,506],{"class":235,"line":482},20,[233,484,485],{"class":239},".ticker__value.is-down",[233,487,488],{"class":243}," { ",[233,490,425],{"class":239},[233,492,260],{"class":243},[233,494,495],{"class":239},"#f87171",[233,497,465],{"class":243},[233,499,468],{"class":239},[233,501,260],{"class":243},[233,503,473],{"class":239},[233,505,476],{"class":302},[233,507,479],{"class":243},[233,509,511],{"class":235,"line":510},21,[233,512,390],{"emptyLinePlaceholder":389},[233,514,516],{"class":235,"line":515},22,[233,517,518],{"class":250},"\u002F* A badge that overflows the corner: clipped by paint containment. *\u002F\n",[233,520,522,525],{"class":235,"line":521},23,[233,523,524],{"class":239},".ticker__badge",[233,526,244],{"class":243},[233,528,530,532,534,537],{"class":235,"line":529},24,[233,531,271],{"class":239},[233,533,260],{"class":243},[233,535,536],{"class":239},"absolute",[233,538,265],{"class":243},[233,540,542,545,547,550,552],{"class":235,"line":541},25,[233,543,544],{"class":239},"  inset-block-start",[233,546,260],{"class":243},[233,548,549],{"class":239},"-0.5",[233,551,319],{"class":302},[233,553,265],{"class":243},[233,555,557,560,562,564,566],{"class":235,"line":556},26,[233,558,559],{"class":239},"  inset-inline-end",[233,561,260],{"class":243},[233,563,549],{"class":239},[233,565,319],{"class":302},[233,567,265],{"class":243},[233,569,571],{"class":235,"line":570},27,[233,572,383],{"class":243},[14,574,575,576,578],{},"The demo shows the side effect directly: two widgets with the same overflowing corner badge. The widget without containment shows the badge hanging over its edge; the one with ",[18,577,201],{}," clips it. That clipping is not a bug — it is exactly what makes paint containment fast, because the browser knows nothing inside can draw outside the box.",[14,580,581,582,585,586,589,590,593],{},"The value flash uses asymmetric transitions. Adding ",[18,583,584],{},"is-up"," or ",[18,587,588],{},"is-down"," applies the colour instantly, because those rules set ",[18,591,592],{},"transition-duration: 0s","; removing the class a moment later lets the colour fade back over 600 milliseconds, because the base rule's duration applies to the return. Colour changes trigger paint, and on a dashboard with dozens of tickers updating every second, that paint is exactly the work containment keeps local.",[47,595,597],{"id":596},"variation-containment-without-clipping","Variation: containment without clipping",[14,599,600,601,604,605,608,609,612],{},"If a component must let something overflow — the badge above, a focus ring drawn outside the border, a shadow — drop paint containment and keep the rest: ",[18,602,603],{},"contain: layout style",". Layout work is still confined to the subtree, which is usually the larger saving for components whose content changes size, while painting is no longer clipped. The component still becomes a containing block and a stacking context, so check absolutely positioned descendants and ",[18,606,607],{},"z-index"," values. For components that change content but never size, such as a ticker with fixed-width digits inside a fixed-height box, ",[18,610,611],{},"contain: layout"," alone often captures most of the benefit.",[47,614,616],{"id":615},"the-key-technique-contain-the-region-that-changes-not-the-page","The key technique: contain the region that changes, not the page",[14,618,619,620,585,622,624],{},"Containment pays off when three things are true: the contained element's contents change often (animation, live data, lazy-loaded text), the changes would otherwise trigger layout or paint, and the element sits in a large or complex page where page-wide work is expensive. It does little for elements that only animate ",[18,621,20],{},[18,623,24],{},", which already skip layout and paint.",[120,626,127,629,127,632,127,635,127,638,127,642,127,646,127,650,127,655,127,658,127,662,127,666,127,670,127,674,127,677,127,680,127,683,127,686,127,689,127,692,127,695],{"viewBox":627,"role":123,"ariaLabel":628,"xmlns":125,"style":126},"0 0 720 260","Guidance chart: contain helps when contents change layout or paint often in a complex page; it does little for transform or opacity animations; watch for clipping of overflowing elements",[129,630,631],{},"When containment is worth it",[133,633,634],{},"Three columns. Helps: live-updating widgets, accordions and expanding panels, content that swaps in after loading, off-screen sections. Little effect: transform and opacity animations, small static pages. Watch out: dropdowns, tooltips and focus rings that overflow, fixed-position children, and elements that need size from their content under size containment.",[137,636,637],{"textAnchor":139,"x":140,"y":141,"style":142},"Where contain earns its place",[145,639],{"x":147,"y":148,"width":150,"height":640,"rx":151,"fill":165,"opacity":641},"180","0.25",[145,643],{"x":644,"y":148,"width":150,"height":640,"rx":151,"fill":153,"opacity":645},"255","0.08",[145,647],{"x":648,"y":148,"width":150,"height":640,"rx":151,"fill":153,"opacity":649},"480","0.15",[137,651,654],{"textAnchor":139,"x":174,"y":652,"style":653},"78","text-anchor:middle;fill:currentColor;font:600 14px sans-serif","Helps",[137,656,657],{"textAnchor":139,"x":140,"y":652,"style":653},"Little effect",[137,659,661],{"textAnchor":139,"x":660,"y":652,"style":653},"585","Watch out",[137,663,665],{"textAnchor":139,"x":174,"y":664,"style":206},"112","live-updating widgets",[137,667,669],{"textAnchor":139,"x":174,"y":668,"style":206},"138","expanding panels",[137,671,673],{"textAnchor":139,"x":174,"y":672,"style":206},"164","late-loading content",[137,675,676],{"textAnchor":139,"x":174,"y":175,"style":206},"off-screen sections",[137,678,679],{"textAnchor":139,"x":140,"y":664,"style":206},"transform animations",[137,681,682],{"textAnchor":139,"x":140,"y":668,"style":206},"opacity fades",[137,684,685],{"textAnchor":139,"x":140,"y":672,"style":206},"small, simple pages",[137,687,688],{"textAnchor":139,"x":660,"y":664,"style":206},"overflowing dropdowns",[137,690,691],{"textAnchor":139,"x":660,"y":668,"style":206},"focus rings, shadows",[137,693,694],{"textAnchor":139,"x":660,"y":672,"style":206},"fixed-position children",[137,696,697],{"textAnchor":139,"x":660,"y":175,"style":206},"size from content",[47,699,701],{"id":700},"side-effects-to-plan-for","Side effects to plan for",[14,703,704],{},"Containment changes behaviour, not just performance. Before adding it to a component, check each of these:",[57,706,707,726,736,745],{},[60,708,709,712,713,716,717,720,721,723,724,88],{},[63,710,711],{},"Clipping."," Paint containment clips at the padding box. Anything designed to overflow — a dropdown menu, a tooltip, a badge, an outer focus ring, a large shadow — is cut off. Move such elements outside the contained box, render them in the top layer with the ",[18,714,715],{},"popover"," attribute or ",[18,718,719],{},"\u003Cdialog>",", or use ",[18,722,603],{}," without ",[18,725,75],{},[60,727,728,731,732,735],{},[63,729,730],{},"Positioning context."," Layout and paint containment make the element the containing block for ",[18,733,734],{},"position: fixed"," descendants. A \"fixed\" modal inside a contained card is positioned relative to the card, not the viewport. Top-layer elements are exempt.",[60,737,738,741,742,744],{},[63,739,740],{},"Stacking context."," Layout and paint containment each create a stacking context. Descendants' ",[18,743,607],{}," values are resolved inside it, so a child can no longer rise above an element outside the component.",[60,746,747,750,751,753,754,756,757,88],{},[63,748,749],{},"Size containment."," With ",[18,752,83],{}," (included in ",[18,755,115],{},"), an element without explicit dimensions collapses to zero, because its children no longer contribute to its size. Pair it with fixed sizing or ",[18,758,87],{},[14,760,761,762,764,765,768,769,88],{},"Because of these, ",[18,763,201],{}," belongs on self-contained components with predictable bounds — cards, widgets, list items — and not on layout wrappers that host overlays. A useful rule of thumb: if you would be comfortable giving the element ",[18,766,767],{},"overflow: clip"," and treating it as its own positioning root, it is a good candidate for ",[18,770,201],{},[47,772,774],{"id":773},"containment-and-content-visibility","Containment and content-visibility",[14,776,777,780,781,783,784,788],{},[18,778,779],{},"content-visibility: auto"," builds on containment: it applies layout, style and paint containment and skips rendering the element's contents entirely while it is off screen. For long pages with many animated or heavy sections, it keeps off-screen sections from costing anything until the user scrolls near them. It also implies size containment while skipped, which is why it needs ",[18,782,87],{}," to avoid scrollbar jumps. ",[36,785,787],{"href":786},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fcontent-visibility-and-contain-intrinsic-size\u002F","content-visibility and contain-intrinsic-size"," covers that pairing, including the accessibility considerations for skipped content.",[47,790,792],{"id":791},"measuring-the-difference","Measuring the difference",[14,794,795,796,798],{},"Containment should be justified by measurement, not applied everywhere by habit. Record the interaction in Chromium's Performance panel with and without ",[18,797,33],{},". In the \"Layout\" events, the summary lists the number of nodes that needed layout and the layout root. With containment, the layout root should be the contained element and the node count should drop to its subtree. If the numbers do not change, the browser was already able to scope the work, and containment adds side effects for no benefit. Measure on a mid-range phone as well as a development machine: containment often makes no visible difference on a fast laptop and a large one on a device with a slower processor, where page-wide layout for each update is the difference between a smooth dashboard and one that visibly stutters as data arrives.",[47,800,802],{"id":801},"browser-support","Browser support",[14,804,805,806,808,809,812,813,815,816,818],{},"The ",[18,807,33],{}," property is supported in Chrome 52+, Edge 79+, Firefox 69+ and Safari 15.4+. ",[18,810,811],{},"content-visibility"," is supported in Chrome and Edge 85+, Firefox 125+ and Safari 18+, and ",[18,814,87],{}," in Chrome and Edge 83+, Firefox 107+ and Safari 17+. Browsers that ignore ",[18,817,33],{}," render identically minus the optimisation, apart from the clipping and positioning differences, so test overflowing elements in a supporting browser.",[47,820,822],{"id":821},"faq","FAQ",[14,824,825,828],{},[63,826,827],{},"What does contain: layout do?","\nIt tells the browser that nothing inside the element affects layout outside it, and vice versa. When the element's contents change, the browser can lay out just that subtree instead of checking the rest of the page.",[14,830,831,834,835,837],{},[63,832,833],{},"Why did contain: paint cut off my dropdown?","\nPaint containment clips everything to the element's padding box, like ",[18,836,767],{},". Popovers, tooltips, focus rings and shadows that extend beyond the box are cut off. Keep overflowing elements outside the contained element or in the top layer.",[14,839,840,843,845,846,848,849,21,851,853,854,856,857,859],{},[63,841,842],{},"What is the difference between contain: content and contain: strict?",[18,844,103],{}," is shorthand for ",[18,847,67],{},", ",[18,850,75],{},[18,852,95],{}," containment. ",[18,855,115],{}," adds size containment, which means the element's size ignores its children; without an explicit size it collapses to zero. ",[18,858,103],{}," is the safe default for components.",[14,861,862,865,866,868],{},[63,863,864],{},"Does contain help transform and opacity animations?","\nNot much, because those already skip layout and paint. ",[18,867,33],{}," is most useful when an animation, or the content inside an animated region, changes layout or paint and you want that work confined to the component.",[47,870,872],{"id":871},"related","Related",[57,874,875,880,887,894],{},[60,876,877,879],{},[36,878,39],{"href":38}," — the parent guide.",[60,881,882,886],{},[36,883,885],{"href":884},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fcss-triggers-layout-paint-composite\u002F","Layout, Paint and Composite: What Triggers What"," — which changes need containing.",[60,888,889,893],{},[36,890,892],{"href":891},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fprofiling-animations-in-devtools\u002F","Profiling Animations in DevTools"," — measuring layout scope.",[60,895,896,900],{},[36,897,899],{"href":898},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Fpopover-entry-and-exit-transitions\u002F","Popover Entry and Exit Transitions"," — overlays that escape containment via the top layer.",[95,902,903],{},"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 .sLBg1, html code.shiki .sLBg1{--shiki-default:#66707B;--shiki-dark:#BDC4CC}html pre.shiki code .sHUrx, html code.shiki .sHUrx{--shiki-default:#A0111F;--shiki-dark:#FF9492}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":229,"searchDepth":247,"depth":247,"links":905},[906,907,908,909,910,911,912,913,914,915],{"id":49,"depth":247,"text":50},{"id":214,"depth":247,"text":215},{"id":596,"depth":247,"text":597},{"id":615,"depth":247,"text":616},{"id":700,"depth":247,"text":701},{"id":773,"depth":247,"text":774},{"id":791,"depth":247,"text":792},{"id":801,"depth":247,"text":802},{"id":821,"depth":247,"text":822},{"id":871,"depth":247,"text":872},"Limit how far layout and paint work spreads when a component animates: contain: layout, paint and content, what each promises, and the side effects to plan for.","md",{"pageTitle":5,"datePublished":919,"dateModified":919,"faq":920},"2026-09-18",[921,923,925,927],{"q":827,"a":922},"It tells the browser that nothing inside the element affects layout outside it, and vice versa. When the element's contents change, the browser can lay out just that subtree instead of checking the rest of the page.",{"q":833,"a":924},"Paint containment clips everything to the element's padding box, like overflow: clip. Popovers, tooltips, focus rings and shadows that extend beyond the box are cut off. Keep overflowing elements outside the contained element or in the top layer.",{"q":842,"a":926},"content is shorthand for layout, paint and style containment. strict adds size containment, which means the element's size ignores its children; without an explicit size it collapses to zero. content is the safe default for components.",{"q":864,"a":928},"Not much, because those already skip layout and paint. contain is most useful when an animation, or the content inside an animated region, changes layout or paint and you want that work confined to the component.","\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fcontain-property-for-animation-performance",{"title":5,"description":916},"css-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fcontain-property-for-animation-performance\u002Findex","Wbe2NAF6AQdWQ-p-GmJo4rRlKvgjd5jtougTMeS7ZgE",[934,937,940,943,946,949,952,955,958,961,964,967,970,973,976,979,982,985,988,991,994,997,1000,1003,1006,1009,1012,1015,1018,1021,1024,1027,1030,1033,1036,1039,1042,1045,1048,1051,1054,1057,1060,1063,1066,1069,1072,1075,1078,1081,1084,1087,1090,1093,1096,1099,1102,1105,1108,1111,1114,1117,1120,1123,1126,1129,1132,1135,1138,1141,1144,1147,1150,1153,1154,1156,1159,1162,1165,1168,1171,1174,1177,1180,1183,1186,1189,1192,1195,1198,1201,1204,1207,1210,1213,1216,1219,1222,1225,1228,1231,1234,1237,1240,1243,1246,1249,1252,1255,1258,1261,1264,1267,1270,1273,1276,1279,1282,1285,1288,1291,1294,1297,1300,1303,1306,1309,1312,1315,1318,1321,1324,1327,1330,1333,1336,1339,1342,1345,1348,1351,1354,1357,1360,1363,1366,1369,1372,1375,1378,1381,1384,1387,1390,1393,1396,1399,1402,1405,1408,1411,1414,1417,1420,1423,1426,1429,1432,1435,1438,1441,1444,1447,1450,1453,1456,1459,1462,1465,1468,1471,1474,1477,1480,1483,1486,1489],{"path":935,"title":936},"\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":938,"title":939},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fflashing-content-and-seizure-thresholds","Flashing Content and Seizure Thresholds",{"path":941,"title":942},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fforced-colors-mode-and-animations","Forced Colors Mode and Animations",{"path":944,"title":945},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations","Accessibility in CSS Animations: Patterns, Specs & Best Practices",{"path":947,"title":948},"\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":950,"title":951},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fprefers-reduced-motion-recipes","prefers-reduced-motion Recipes: A Reduction for Every Common Effect",{"path":953,"title":954},"\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":956,"title":957},"\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":959,"title":960},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fvestibular-safe-animation-patterns","Vestibular-Safe Animation Patterns: Why Some Motion Makes People Sick",{"path":962,"title":963},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fwcag-motion-success-criteria","WCAG Motion Success Criteria: What Each One Actually Requires",{"path":965,"title":966},"\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":968,"title":969},"\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":971,"title":972},"\u002Fcss-only-micro-interactions-animations\u002Fclip-path-and-mask-animations","Clip-Path & Mask Animations: Animating Visibility Instead of Position",{"path":974,"title":975},"\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":977,"title":978},"\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":980,"title":981},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions\u002Fanimating-gradients","Animating CSS Gradients: Smooth Colour Motion Without Jumps",{"path":983,"title":984},"\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":986,"title":987},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions","Color & Theme Transitions: Colour as Part of the Motion System",{"path":989,"title":990},"\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":992,"title":993},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions\u002Fsmooth-theme-switching-transitions","Smooth Theme Switching: Crossfades, Circular Reveals and No Flash",{"path":995,"title":996},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fcontainer-query-hover-affordances","Container Query Hover Affordances: When Narrow Means Persistent, Not Hidden",{"path":998,"title":999},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion","Container-Aware Motion: Animation Sized by the Space a Component Actually Has",{"path":1001,"title":1002},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Flayout-change-animations-at-container-breakpoints","Animating Changes at Container Breakpoints",{"path":1004,"title":1005},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fmotion-driven-by-container-style-queries","Motion Driven by Container Style Queries",{"path":1007,"title":1008},"\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":1010,"title":1011},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fsuppressing-motion-in-small-containers","Suppressing Motion in Small Containers: Deliberately Animating Nothing",{"path":1013,"title":1014},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api\u002Fcontrolling-css-animations-from-javascript","Controlling CSS Animations From JavaScript",{"path":1016,"title":1017},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api","CSS Animation vs the Web Animations API: A Decision Guide",{"path":1019,"title":1020},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api\u002Fwaapi-vs-css-for-interruptible-ui","Interruptible UI: CSS Transitions vs WAAPI",{"path":1022,"title":1023},"\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":1025,"title":1026},"\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":1028,"title":1029},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Fcustom-property-fallbacks-and-invalid-values","Custom Property Fallbacks and Invalid Values",{"path":1031,"title":1032},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Ffluid-spacing-tokens-driving-transition-durations","Fluid Spacing Tokens That Drive Transition Durations",{"path":1034,"title":1035},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture","CSS Custom Properties Architecture: Scalable Design Systems & Dynamic UI",{"path":1037,"title":1038},"\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":1040,"title":1041},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Fscoping-custom-properties-to-components","Scoping Custom Properties to Components",{"path":1043,"title":1044},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fcss-transition-timing-functions","CSS Transition Timing Functions: ease, cubic-bezier(), steps() and linear()",{"path":1046,"title":1047},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals","CSS Transition Fundamentals: Architecture, Performance & Patterns",{"path":1049,"title":1050},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Finterrupted-and-reversing-transitions","Interrupted and Reversing Transitions: What Happens Mid-Flight",{"path":1052,"title":1053},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fstarting-style-entry-animations","@starting-style: Animating an Element's Very First Style Change",{"path":1055,"title":1056},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransition-delay-choreography","Choreographing Motion With transition-delay",{"path":1058,"title":1059},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransition-shorthand-and-multiple-properties","The transition Shorthand and Multiple Properties",{"path":1061,"title":1062},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransitioning-display-with-allow-discrete","Transitioning display with transition-behavior: allow-discrete and @starting-style",{"path":1064,"title":1065},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Fanimating-dialog-open-and-close","Animating \u003Cdialog> Open and Close: Both Directions, No Library",{"path":1067,"title":1068},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Fbackdrop-animations","Animating ::backdrop: Fades and Blurs Behind Dialogs and Popovers",{"path":1070,"title":1071},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations","Dialog & Popover Animations: Motion for the Top Layer",{"path":1073,"title":1074},"\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":1076,"title":1077},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Fpopover-entry-and-exit-transitions","Popover Menus That Animate From Their Anchor",{"path":1079,"title":1080},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fchoosing-animation-durations","Choosing Animation Durations: How Long Motion Should Last",{"path":1082,"title":1083},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fcubic-bezier-overshoot-and-anticipation","Overshoot and Anticipation With cubic-bezier(): Motion With Character",{"path":1085,"title":1086},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fentry-vs-exit-easing","Entry vs Exit Easing: Different Curves for Arriving and Leaving",{"path":1088,"title":1089},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design","Easing & Motion Design: Making CSS Motion Feel Intentional",{"path":1091,"title":1092},"\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":1094,"title":1095},"\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":1097,"title":1098},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Faccessible-css-only-tooltips","Accessible CSS-Only Tooltips and Hover Cards With  and ",{"path":1100,"title":1101},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Fbutton-press-and-active-states","Button Press and  States",{"path":1103,"title":1104},"\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":1106,"title":1107},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Ffocus-within-form-patterns"," Form Patterns: Styling a Group From the Field Inside It",{"path":1109,"title":1110},"\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":1112,"title":1113},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design","Hover & Focus State Design: Spec-Compliant Patterns for Modern UIs",{"path":1115,"title":1116},"\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":1118,"title":1119},"\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":1121,"title":1122},"\u002Fcss-only-micro-interactions-animations","CSS-Only Micro-Interactions & Animations: Architecture, Performance & Implementation",{"path":1124,"title":1125},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fanimation-composition-and-stacking","Stacking Animations With animation-composition",{"path":1127,"title":1128},"\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":1130,"title":1131},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcontainer-query-triggered-keyframe-animations","Container-Query-Triggered Keyframe Animations: Animate Differently per Available Space",{"path":1133,"title":1134},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcss-only-accordions-and-disclosure","CSS-Only Accordions and Disclosure Widgets with details and summary",{"path":1136,"title":1137},"\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":1139,"title":1140},"\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":1142,"title":1143},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns","Keyframe Animation Patterns: Spec-Compliant Architectures for Modern UIs",{"path":1145,"title":1146},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fmulti-step-keyframes-and-per-keyframe-easing","Multi-Step Keyframes and Per-Keyframe Easing",{"path":1148,"title":1149},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fstaggered-list-animations-with-custom-properties","Staggered List Animations Using --i Index Custom Properties",{"path":1151,"title":1152},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fanimating-box-shadow-and-filters-cheaply","Animating box-shadow and Filters Cheaply",{"path":929,"title":5},{"path":1155,"title":885},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fcss-triggers-layout-paint-composite",{"path":1157,"title":1158},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration","Performance & GPU Acceleration in CSS: A Developer’s Blueprint",{"path":1160,"title":1161},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Foptimizing-css-animations-for-60fps","Optimizing CSS Animations for 60fps: Budgeting the Frame",{"path":1163,"title":1164},"\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":1166,"title":1167},"\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":1169,"title":1170},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations","Scroll-Driven Animations: Binding Motion to Scroll Position in Pure CSS",{"path":1172,"title":1173},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-driven-animation-fallbacks","Shipping Scroll-Driven Animations Without Breaking Anything",{"path":1175,"title":1176},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-driven-parallax-effects","Scroll-Driven Parallax Effects in CSS",{"path":1178,"title":1179},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-progress-bar-without-javascript","A Reading Progress Bar Driven by scroll(root)",{"path":1181,"title":1182},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-triggered-reveal-animations","Reveal-on-Scroll with view() and animation-range",{"path":1184,"title":1185},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Ftimeline-scope-for-cross-element-animations","timeline-scope for Cross-Element Animations",{"path":1187,"title":1188},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fview-timeline-and-animation-range","View Timelines and animation-range",{"path":1190,"title":1191},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fcross-document-view-transitions","Cross-Document View Transitions",{"path":1193,"title":1194},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers","View Transitions for CSS Developers: the Pseudo-Element Tree, Snapshots, and Named Elements",{"path":1196,"title":1197},"\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":1199,"title":1200},"\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":1202,"title":1203},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transition-types-and-classes","View Transition Types and Classes",{"path":1205,"title":1206},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transitions-for-list-reordering","View Transitions for List Reordering",{"path":1208,"title":1209},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transitions-with-reduced-motion","Honouring prefers-reduced-motion in View Transitions",{"path":1211,"title":1212},"\u002F","Modern CSS Layouts & Micro-Interactions",{"path":1214,"title":1215},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-positioned-tooltips","Anchor-Positioned Tooltips: Tethering, Flipping, and Getting the Semantics Right",{"path":1217,"title":1218},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-positioning-fallbacks","Anchor Positioning Fallbacks: A Graceful Floor for Older Browser Versions",{"path":1220,"title":1221},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-size-for-matching-widths","anchor-size(): Overlays That Match Their Trigger's Size",{"path":1223,"title":1224},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays","CSS Anchor Positioning and Overlays: Tethering Elements Without JavaScript",{"path":1226,"title":1227},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fpopover-attribute-and-css-styling","The popover Attribute: Top-Layer Overlays With No JavaScript",{"path":1229,"title":1230},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fpopover-light-dismiss-and-stacking","Popover Light Dismiss, Nesting and Stacking",{"path":1232,"title":1233},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fposition-area-grid-explained","position-area: The Anchor Placement Grid",{"path":1235,"title":1236},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fcontainer-query-polyfill-tradeoffs","Container Query Polyfills: What They Cost and When to Skip Them",{"path":1238,"title":1239},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Ffeature-detection-with-supports","Feature Detection with @supports: Syntax, Semantics, and the Traps",{"path":1241,"title":1242},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fhandling-container-query-fallbacks-for-older-browsers","Handling Container Query Fallbacks for Older Browsers",{"path":1244,"title":1245},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks","Container Query Fallbacks: Spec-Compliant CSS Strategies for Legacy Browsers",{"path":1247,"title":1248},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fintrinsic-layout-fallbacks-without-queries","Intrinsic Layout Fallbacks: Baselines That Adapt Without Any Query",{"path":1250,"title":1251},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Ftesting-fallbacks-without-old-browsers","Testing CSS Fallbacks Without an Old Browser",{"path":1253,"title":1254},"\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":1256,"title":1257},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-query-range-and-logic-operators","Container Query Range Syntax and Logic Operators",{"path":1259,"title":1260},"\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":1262,"title":1263},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-type-size-vs-inline-size","Choosing container-type: inline-size, size, or normal",{"path":1265,"title":1266},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-vs-media-queries-comparison","Container vs Media Queries: Choosing the Right Reference Box",{"path":1268,"title":1269},"\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":1271,"title":1272},"\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":1274,"title":1275},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics","Container Query Syntax Basics",{"path":1277,"title":1278},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fnesting-and-naming-container-queries","Nesting and Naming Container Queries: Targeting the Right Ancestor",{"path":1280,"title":1281},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fauto-fit-minmax-responsive-grids","Responsive Grids with repeat(auto-fit, minmax())",{"path":1283,"title":1284},"\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":1286,"title":1287},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fgrid-auto-flow-dense-packing","grid-auto-flow: dense for Packed Layouts",{"path":1289,"title":1290},"\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":1292,"title":1293},"\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":1295,"title":1296},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts","CSS Grid and Subgrid Layouts for Responsive Interfaces",{"path":1298,"title":1299},"\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":1301,"title":1302},"\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":1304,"title":1305},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fsubgrid-vs-nested-grid","Subgrid vs an Independently Nested Grid",{"path":1307,"title":1308},"\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":1310,"title":1311},"\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":1313,"title":1314},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflex-grow-and-flex-shrink-explained","flex-grow and flex-shrink Explained",{"path":1316,"title":1317},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflex-wrap-intrinsic-responsive-rows","Breakpoint-Free Responsive Rows With flex-wrap and flex-basis",{"path":1319,"title":1320},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflexbox-gap-and-spacing","Flexbox gap vs Margins: Spacing Items Without Edge Hacks",{"path":1322,"title":1323},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns","Flexbox Layout Patterns: One-Dimensional Layout for Real Components",{"path":1325,"title":1326},"\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":1328,"title":1329},"\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":1331,"title":1332},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Fdebugging-clamp-values","Debugging clamp(): Values That Are Ignored, Stuck or Never Fluid",{"path":1334,"title":1335},"\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":1337,"title":1338},"\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":1340,"title":1341},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-type-accessibility-and-zoom","Fluid Type, Accessibility and Zoom: The vw-Only Trap",{"path":1343,"title":1344},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-typography-without-javascript","Fluid Typography Without JavaScript: A Precision CSS Reference",{"path":1346,"title":1347},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp","Fluid Typography with clamp(): A Practical Guide for Modern CSS",{"path":1349,"title":1350},"\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":1352,"title":1353},"\u002Fmastering-container-queries-responsive-layouts","Mastering Container Queries & Responsive Layouts",{"path":1355,"title":1356},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Faspect-ratio-for-responsive-media","Using aspect-ratio for Responsive Media and Preventing Layout Shift",{"path":1358,"title":1359},"\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":1361,"title":1362},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques","Intrinsic Sizing Techniques: Modern CSS Layouts for Responsive UI",{"path":1364,"title":1365},"\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":1367,"title":1368},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fmin-max-fit-content-explained","min-content, max-content, and fit-content() Explained",{"path":1370,"title":1371},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fobject-fit-and-object-position","object-fit and object-position: Images That Fit Any Box",{"path":1373,"title":1374},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fpreventing-flex-and-grid-overflow","The min-width: auto Trap in Flex and Grid Layouts",{"path":1376,"title":1377},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-for-reset-and-tokens","Cascade Layers for Reset and Design Tokens",{"path":1379,"title":1380},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-vs-specificity-hacks","Cascade Layers vs Specificity Hacks: Ordering Instead of Escalating",{"path":1382,"title":1383},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcss-scope-for-component-styles","@scope for Component Styles: Short Selectors That Cannot Leak",{"path":1385,"title":1386},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies","Modern CSS Reset Strategies: A Spec-Compliant Foundation",{"path":1388,"title":1389},"\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":1391,"title":1392},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fwriting-a-minimal-modern-reset","Writing a Minimal Modern CSS Reset: Every Line Justified",{"path":1394,"title":1395},"\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":1397,"title":1398},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has\u002Fempty-and-loading-states-with-has","Empty and Loading States With ()",{"path":1400,"title":1401},"\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":1403,"title":1404},"\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":1406,"title":1407},"\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":1409,"title":1410},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has","Parent-Aware Layouts With :has(): Letting Containers React to Their Contents",{"path":1412,"title":1413},"\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":1415,"title":1416},"\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":1418,"title":1419},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fcontainer-query-data-tables","Container Query Data Tables: Reflowing Tables to Cards",{"path":1421,"title":1422},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fcontainer-query-sidebar-layouts","Container Query Sidebar Layouts That Travel Between Contexts",{"path":1424,"title":1425},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns","Responsive Component Patterns: Architecture & Implementation",{"path":1427,"title":1428},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-forms-with-container-queries","Responsive Forms with Container Queries: Reflow Without Losing the Wiring",{"path":1430,"title":1431},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-hero-sections-with-container-queries","Responsive Hero Sections With Container Queries",{"path":1433,"title":1434},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-navigation-without-media-queries","Responsive Navigation Without Media Queries Using Container Queries",{"path":1436,"title":1437},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-pricing-tables","Responsive Pricing Tables: Aligned Features, a Clear Recommendation, Any Width",{"path":1439,"title":1440},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Ftabs-that-become-accordions","Tabs That Become an Accordion: One Component, Two Layouts",{"path":1442,"title":1443},"\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts\u002Fcss-only-carousel-with-scroll-snap","A CSS-Only Carousel With Scroll Snap",{"path":1445,"title":1446},"\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":1448,"title":1449},"\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts","Scroll Snap & Overflow Layouts: Designing Components That Scroll on Purpose",{"path":1451,"title":1452},"\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":1454,"title":1455},"\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":1457,"title":1458},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fcombining-size-and-style-queries","Combining Size and Style Container Queries",{"path":1460,"title":1461},"\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":1463,"title":1464},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state","Style Queries and Container State: Token-Driven Component Variants",{"path":1466,"title":1467},"\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":1469,"title":1470},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fstyle-query-component-variants","Component Variants With Style Queries: One Token, Many Looks",{"path":1472,"title":1473},"\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":1475,"title":1476},"\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":1478,"title":1479},"\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":1481,"title":1482},"\u002Fmastering-container-queries-responsive-layouts\u002Fviewport-units-and-mobile-layout","Viewport Units & Mobile Layout: Designing for the Screen You Actually Get",{"path":1484,"title":1485},"\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":1487,"title":1488},"\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":1490,"title":1491},"\u002Fmastering-container-queries-responsive-layouts\u002Fviewport-units-and-mobile-layout\u002Fvirtual-keyboard-and-interactive-widget","Layouts That Survive the Virtual Keyboard",{"title":1493,"caption":1494,"height":1495,"html":1496,"css":1497},"Paint containment clips overflow","Both widgets have a badge positioned over the top-right corner. The widget with contain: content clips it at its edge — the side effect that makes paint containment fast.",220,"\n\u003Cdiv class=\"grid\">\n  \u003Cdiv class=\"ticker\">\n    \u003Cspan class=\"ticker__badge\">LIVE\u003C\u002Fspan>\n    \u003Cspan class=\"ticker__label\">No containment\u003C\u002Fspan>\n    \u003Cspan class=\"ticker__value\">142.37\u003C\u002Fspan>\n  \u003C\u002Fdiv>\n  \u003Cdiv class=\"ticker ticker--contained\">\n    \u003Cspan class=\"ticker__badge\">LIVE\u003C\u002Fspan>\n    \u003Cspan class=\"ticker__label\">contain: content\u003C\u002Fspan>\n    \u003Cspan class=\"ticker__value\">142.37\u003C\u002Fspan>\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>","\n.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: 2rem; padding: 2rem 1.5rem; }\n.ticker { position: relative; display: grid; gap: 0.25rem; min-block-size: 6rem; padding: 1rem; border-radius: 10px; background: #0f172a; color: #e2e8f0; }\n.ticker--contained { contain: content; }\n.ticker__label { font-size: 0.8rem; color: #94a3b8; }\n.ticker__value { font-size: 1.6rem; font-weight: 700; font-variant-numeric: tabular-nums; }\n.ticker__badge { position: absolute; inset-block-start: -0.6rem; inset-inline-end: -0.6rem; padding: 0.15rem 0.5rem; border-radius: 999px; background: #dc2626; color: #fff; font-size: 0.7rem; font-weight: 700; letter-spacing: 0.05em; }",1789717748251]