[{"data":1,"prerenderedAt":2452},["ShallowReactive",2],{"page-\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts\u002Fcss-only-carousel-with-scroll-snap\u002F":3,"content-all-pages":1888,"live-demo:snap-carousel":2446},{"id":4,"title":5,"body":6,"description":1869,"extension":1870,"meta":1871,"navigation":368,"path":1884,"seo":1885,"stem":1886,"__hash__":1887},"content\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts\u002Fcss-only-carousel-with-scroll-snap\u002Findex.md","A CSS-Only Carousel With Scroll Snap",{"type":7,"value":8,"toc":1857},"minimark",[9,13,28,33,36,39,42,46,74,173,176,180,184,1385,1400,1408,1418,1489,1503,1507,1515,1671,1691,1695,1746,1750,1766,1770,1776,1800,1816,1822,1826,1854],[10,11,5],"h1",{"id":12},"a-css-only-carousel-with-scroll-snap",[14,15,16,17,22,23,27],"p",{},"Carousels are the component most often rebuilt from scratch with a JavaScript library, and the one most often shipped broken: swipe works but the keyboard does not, momentum scrolling feels wrong, a screen reader announces slides that are off screen as if they were visible, and the whole thing weighs more than the images. The narrow problem this page solves is a horizontal carousel that feels native on touch, trackpad and mouse wheel, works from the keyboard, and needs no script — built from an ordinary overflow container plus CSS Scroll Snap. It belongs to ",[18,19,21],"a",{"href":20},"\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts\u002F","Scroll Snap & Overflow Layouts"," in the ",[18,24,26],{"href":25},"\u002Fmastering-container-queries-responsive-layouts\u002F","Mastering Container Queries & Responsive Layouts"," guide.",[29,30,32],"h2",{"id":31},"why-scroll-snap-instead-of-a-script","Why scroll snap instead of a script",[14,34,35],{},"A scripted carousel reimplements scrolling: it listens for pointer events, computes velocity, animates a transform and decides where to stop. Each of those steps is an opportunity to feel slightly unlike the platform. Native scrolling already has momentum tuned per device, already works with trackpads, wheels, touch, arrow keys and screen-reader scrolling gestures, and already runs on the compositor so it stays smooth when the main thread is busy.",[14,37,38],{},"Scroll snap adds exactly one thing to native scrolling: a set of resting positions. When the user finishes a scroll gesture, the browser adjusts the final position to the nearest snap point, using the same momentum physics as the gesture itself. Everything else stays native. That is why a scroll-snap carousel feels right on every device without device-specific code.",[14,40,41],{},"What CSS alone does not give you is state: a \"slide 3 of 7\" indicator that updates as you scroll, or disabling the previous button at the start. Those need either newer CSS features still arriving in browsers or a few lines of script. The pattern below is complete without them and can be enhanced later.",[29,43,45],{"id":44},"how-snapping-works","How snapping works",[14,47,48,49,53,54,58,59,53,62,65,66,69,70,73],{},"Three pieces cooperate. The ",[50,51,52],"strong",{},"scroll container"," declares ",[55,56,57],"code",{},"scroll-snap-type",", choosing the axis and strictness. Each ",[50,60,61],{},"child",[55,63,64],{},"scroll-snap-align",", choosing which of its edges should line up. And the container's ",[55,67,68],{},"scroll-padding"," insets the ",[50,71,72],{},"snapport"," — the area against which alignment is measured — so slides can rest inside visual padding.",[75,76,82,83,82,87,82,91,82,99,82,111,82,116,82,125,82,129,82,137,82,143,82,148,82,153,82,158,82,163,82,166,82,169],"svg",{"viewBox":77,"role":78,"ariaLabel":79,"xmlns":80,"style":81},"0 0 720 320","img","Scroll container with scroll-padding defining a snapport, and slides aligned to its start edge","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;height:auto;max-width:720px;margin:2rem 0","\n  ",[84,85,86],"title",{},"The snapport and snap alignment",[88,89,90],"desc",{},"A scroll container with padding on both sides. The snapport is the inner region after scroll-padding. The current slide's start edge aligns with the snapport's start edge; the next slide peeks in from the right.",[92,93,98],"text",{"textAnchor":94,"x":95,"y":96,"style":97},"middle","360","26","text-anchor:middle;fill:currentColor;font:700 17px sans-serif","Slides align to the snapport, not the box",[100,101],"rect",{"x":102,"y":103,"width":104,"height":105,"rx":106,"fill":107,"stroke":108,"strokeWidth":109,"opacity":110},"60","56","600","160","12","none","currentColor","2","0.7",[92,112,115],{"textAnchor":94,"x":95,"y":113,"style":114},"48","text-anchor:middle;fill:currentColor;font:12px sans-serif","scroll container (scroll-snap-type: x mandatory)",[117,118],"path",{"d":119,"stroke":120,"strokeWidth":121,"strokeDashArray":122},"M100 64 V208","#7aa2ff","3",[123,124],"6","4",[117,126],{"d":127,"stroke":120,"strokeWidth":121,"strokeDashArray":128},"M620 64 V208",[123,124],[100,130],{"x":131,"y":132,"width":133,"height":134,"rx":135,"fill":120,"opacity":136},"104","80","380","112","8","0.34",[92,138,142],{"textAnchor":94,"x":139,"y":140,"style":141},"294","132","text-anchor:middle;fill:currentColor;font:600 13px sans-serif","current slide",[92,144,147],{"textAnchor":94,"x":139,"y":145,"style":146},"154","text-anchor:middle;fill:currentColor;font:12px ui-monospace,monospace","scroll-snap-align: start",[100,149],{"x":150,"y":132,"width":151,"height":134,"rx":135,"fill":120,"opacity":152},"496","120","0.16",[92,154,157],{"textAnchor":94,"x":155,"y":156,"style":114},"556","140","next peeks",[92,159,162],{"textAnchor":94,"x":132,"y":160,"style":161},"244","text-anchor:middle;fill:currentColor;font:11px ui-monospace,monospace","padding",[92,164,162],{"textAnchor":94,"x":165,"y":160,"style":161},"640",[92,167,168],{"textAnchor":94,"x":95,"y":160,"style":114},"snapport = container minus scroll-padding",[92,170,172],{"textAnchor":94,"x":95,"y":139,"style":171},"text-anchor:middle;fill:currentColor;font:12px sans-serif;opacity:0.75","Match scroll-padding to the visual padding so the first slide rests where the design expects.",[14,174,175],{},"The peek of the next slide is not decoration. It is the most important affordance a carousel has: it tells the user there is more content to the side. Carousels that fit exactly one slide per view hide that fact, and users who never try swiping never see slides two to seven.",[29,177,179],{"id":178},"the-complete-implementation","The complete implementation",[181,182],"live-demo",{"name":183},"snap-carousel",[185,186,191],"pre",{"className":187,"code":188,"language":189,"meta":190,"style":190},"language-html shiki shiki-themes github-light-high-contrast github-dark-high-contrast","\u003C!doctype html>\n\u003Chtml lang=\"en\">\n\u003Chead>\n\u003Cmeta charset=\"utf-8\">\n\u003Cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\u003Ctitle>Scroll-snap carousel\u003C\u002Ftitle>\n\u003Cstyle>\n  body { font: 15px\u002F1.5 system-ui, sans-serif; margin: 1.5rem; }\n\n  .carousel {\n    display: grid;\n    \u002F* Each slide is 80% of the scroller so the next one peeks in. *\u002F\n    grid-auto-flow: column;\n    grid-auto-columns: 80%;\n    gap: 1rem;\n\n    overflow-x: auto;\n    overscroll-behavior-x: contain;   \u002F* do not trigger back-swipe at the ends *\u002F\n    scroll-snap-type: x mandatory;    \u002F* always come to rest on a slide *\u002F\n    scroll-padding-inline: 1rem;      \u002F* snapport matches the visual padding *\u002F\n    padding: 0.5rem 1rem 1rem;\n\n    \u002F* Smooth scrolling for the next\u002Fprevious links, but only for users\n       who have not asked for reduced motion. *\u002F\n    scroll-behavior: auto;\n  }\n  @media (prefers-reduced-motion: no-preference) {\n    .carousel { scroll-behavior: smooth; }\n  }\n\n  .carousel:focus-visible {\n    outline: 2px solid #2563eb;\n    outline-offset: 2px;\n  }\n\n  .slide {\n    scroll-snap-align: start;\n    \u002F* Stop fast flicks from skipping slides: each gesture ends on the\n       next or previous slide at most. *\u002F\n    scroll-snap-stop: always;\n    min-height: 10rem;\n    padding: 1rem;\n    border-radius: 12px;\n    background: linear-gradient(135deg, #dbeafe, #c7d2fe);\n    color: #1e1b4b;\n  }\n\n  \u002F* Prev\u002Fnext are ordinary in-page links to slide ids; the browser\n     scrolls the carousel, and snap settles the position. *\u002F\n  .carousel-nav { display: flex; gap: 0.5rem; margin-top: 0.5rem; }\n  .carousel-nav a {\n    padding: 0.4rem 0.8rem;\n    border: 1px solid #94a3b8;\n    border-radius: 6px;\n    color: inherit;\n    text-decoration: none;\n  }\n\u003C\u002Fstyle>\n\u003C\u002Fhead>\n\u003Cbody>\n  \u003Csection aria-labelledby=\"c-title\">\n    \u003Ch2 id=\"c-title\">Featured trails\u003C\u002Fh2>\n    \u003Cdiv class=\"carousel\" tabindex=\"0\" role=\"group\" aria-label=\"Featured trails, scroll horizontally\">\n      \u003Carticle class=\"slide\" id=\"s1\">\u003Ch3>Ridge Loop\u003C\u002Fh3>\u003Cp>12 km, moderate.\u003C\u002Fp>\u003C\u002Farticle>\n      \u003Carticle class=\"slide\" id=\"s2\">\u003Ch3>Lake Path\u003C\u002Fh3>\u003Cp>6 km, easy.\u003C\u002Fp>\u003C\u002Farticle>\n      \u003Carticle class=\"slide\" id=\"s3\">\u003Ch3>Summit Trail\u003C\u002Fh3>\u003Cp>18 km, hard.\u003C\u002Fp>\u003C\u002Farticle>\n      \u003Carticle class=\"slide\" id=\"s4\">\u003Ch3>Forest Walk\u003C\u002Fh3>\u003Cp>4 km, easy.\u003C\u002Fp>\u003C\u002Farticle>\n    \u003C\u002Fdiv>\n    \u003Cnav class=\"carousel-nav\" aria-label=\"Jump to trail\">\n      \u003Ca href=\"#s1\">1\u003C\u002Fa>\u003Ca href=\"#s2\">2\u003C\u002Fa>\u003Ca href=\"#s3\">3\u003C\u002Fa>\u003Ca href=\"#s4\">4\u003C\u002Fa>\n    \u003C\u002Fnav>\n  \u003C\u002Fsection>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>\n","html","",[55,192,193,213,233,243,261,286,300,310,363,370,379,393,400,413,428,443,448,461,478,498,516,540,545,551,557,569,575,584,602,607,612,620,640,654,659,664,672,685,691,697,710,725,738,752,785,798,803,808,814,820,860,870,889,908,921,933,945,950,960,969,979,998,1020,1062,1112,1156,1200,1244,1254,1278,1348,1357,1367,1376],{"__ignoreMap":190},[194,195,198,202,206,210],"span",{"class":196,"line":197},"line",1,[194,199,201],{"class":200},"suds8","\u003C!",[194,203,205],{"class":204},"sne4z","doctype",[194,207,209],{"class":208},"s-5SL"," html",[194,211,212],{"class":200},">\n",[194,214,216,219,221,224,227,231],{"class":196,"line":215},2,[194,217,218],{"class":200},"\u003C",[194,220,189],{"class":204},[194,222,223],{"class":208}," lang",[194,225,226],{"class":200},"=",[194,228,230],{"class":229},"sT6z2","\"en\"",[194,232,212],{"class":200},[194,234,236,238,241],{"class":196,"line":235},3,[194,237,218],{"class":200},[194,239,240],{"class":204},"head",[194,242,212],{"class":200},[194,244,246,248,251,254,256,259],{"class":196,"line":245},4,[194,247,218],{"class":200},[194,249,250],{"class":204},"meta",[194,252,253],{"class":208}," charset",[194,255,226],{"class":200},[194,257,258],{"class":229},"\"utf-8\"",[194,260,212],{"class":200},[194,262,264,266,268,271,273,276,279,281,284],{"class":196,"line":263},5,[194,265,218],{"class":200},[194,267,250],{"class":204},[194,269,270],{"class":208}," name",[194,272,226],{"class":200},[194,274,275],{"class":229},"\"viewport\"",[194,277,278],{"class":208}," content",[194,280,226],{"class":200},[194,282,283],{"class":229},"\"width=device-width, initial-scale=1\"",[194,285,212],{"class":200},[194,287,289,291,293,296,298],{"class":196,"line":288},6,[194,290,218],{"class":200},[194,292,84],{"class":204},[194,294,295],{"class":200},">Scroll-snap carousel\u003C\u002F",[194,297,84],{"class":204},[194,299,212],{"class":200},[194,301,303,305,308],{"class":196,"line":302},7,[194,304,218],{"class":200},[194,306,307],{"class":204},"style",[194,309,212],{"class":200},[194,311,313,316,319,322,325,328,332,335,338,341,344,347,350,353,355,357,360],{"class":196,"line":312},8,[194,314,315],{"class":204},"  body",[194,317,318],{"class":200}," { ",[194,320,321],{"class":208},"font",[194,323,324],{"class":200},": ",[194,326,327],{"class":208},"15",[194,329,331],{"class":330},"sHUrx","px",[194,333,334],{"class":200},"\u002F",[194,336,337],{"class":208},"1.5",[194,339,340],{"class":208}," system-ui",[194,342,343],{"class":200},", ",[194,345,346],{"class":208},"sans-serif",[194,348,349],{"class":200},"; ",[194,351,352],{"class":208},"margin",[194,354,324],{"class":200},[194,356,337],{"class":208},[194,358,359],{"class":330},"rem",[194,361,362],{"class":200},"; }\n",[194,364,366],{"class":196,"line":365},9,[194,367,369],{"emptyLinePlaceholder":368},true,"\n",[194,371,373,376],{"class":196,"line":372},10,[194,374,375],{"class":208},"  .carousel",[194,377,378],{"class":200}," {\n",[194,380,382,385,387,390],{"class":196,"line":381},11,[194,383,384],{"class":208},"    display",[194,386,324],{"class":200},[194,388,389],{"class":208},"grid",[194,391,392],{"class":200},";\n",[194,394,396],{"class":196,"line":395},12,[194,397,399],{"class":398},"sLBg1","    \u002F* Each slide is 80% of the scroller so the next one peeks in. *\u002F\n",[194,401,403,406,408,411],{"class":196,"line":402},13,[194,404,405],{"class":208},"    grid-auto-flow",[194,407,324],{"class":200},[194,409,410],{"class":208},"column",[194,412,392],{"class":200},[194,414,416,419,421,423,426],{"class":196,"line":415},14,[194,417,418],{"class":208},"    grid-auto-columns",[194,420,324],{"class":200},[194,422,132],{"class":208},[194,424,425],{"class":330},"%",[194,427,392],{"class":200},[194,429,431,434,436,439,441],{"class":196,"line":430},15,[194,432,433],{"class":208},"    gap",[194,435,324],{"class":200},[194,437,438],{"class":208},"1",[194,440,359],{"class":330},[194,442,392],{"class":200},[194,444,446],{"class":196,"line":445},16,[194,447,369],{"emptyLinePlaceholder":368},[194,449,451,454,456,459],{"class":196,"line":450},17,[194,452,453],{"class":208},"    overflow-x",[194,455,324],{"class":200},[194,457,458],{"class":208},"auto",[194,460,392],{"class":200},[194,462,464,467,469,472,475],{"class":196,"line":463},18,[194,465,466],{"class":208},"    overscroll-behavior-x",[194,468,324],{"class":200},[194,470,471],{"class":208},"contain",[194,473,474],{"class":200},";   ",[194,476,477],{"class":398},"\u002F* do not trigger back-swipe at the ends *\u002F\n",[194,479,481,484,486,489,492,495],{"class":196,"line":480},19,[194,482,483],{"class":208},"    scroll-snap-type",[194,485,324],{"class":200},[194,487,488],{"class":208},"x",[194,490,491],{"class":208}," mandatory",[194,493,494],{"class":200},";    ",[194,496,497],{"class":398},"\u002F* always come to rest on a slide *\u002F\n",[194,499,501,504,506,508,510,513],{"class":196,"line":500},20,[194,502,503],{"class":208},"    scroll-padding-inline",[194,505,324],{"class":200},[194,507,438],{"class":208},[194,509,359],{"class":330},[194,511,512],{"class":200},";      ",[194,514,515],{"class":398},"\u002F* snapport matches the visual padding *\u002F\n",[194,517,519,522,524,527,529,532,534,536,538],{"class":196,"line":518},21,[194,520,521],{"class":208},"    padding",[194,523,324],{"class":200},[194,525,526],{"class":208},"0.5",[194,528,359],{"class":330},[194,530,531],{"class":208}," 1",[194,533,359],{"class":330},[194,535,531],{"class":208},[194,537,359],{"class":330},[194,539,392],{"class":200},[194,541,543],{"class":196,"line":542},22,[194,544,369],{"emptyLinePlaceholder":368},[194,546,548],{"class":196,"line":547},23,[194,549,550],{"class":398},"    \u002F* Smooth scrolling for the next\u002Fprevious links, but only for users\n",[194,552,554],{"class":196,"line":553},24,[194,555,556],{"class":398},"       who have not asked for reduced motion. *\u002F\n",[194,558,560,563,565,567],{"class":196,"line":559},25,[194,561,562],{"class":208},"    scroll-behavior",[194,564,324],{"class":200},[194,566,458],{"class":208},[194,568,392],{"class":200},[194,570,572],{"class":196,"line":571},26,[194,573,574],{"class":200},"  }\n",[194,576,578,581],{"class":196,"line":577},27,[194,579,580],{"class":330},"  @media",[194,582,583],{"class":200}," (prefers-reduced-motion: no-preference) {\n",[194,585,587,590,592,595,597,600],{"class":196,"line":586},28,[194,588,589],{"class":208},"    .carousel",[194,591,318],{"class":200},[194,593,594],{"class":208},"scroll-behavior",[194,596,324],{"class":200},[194,598,599],{"class":208},"smooth",[194,601,362],{"class":200},[194,603,605],{"class":196,"line":604},29,[194,606,574],{"class":200},[194,608,610],{"class":196,"line":609},30,[194,611,369],{"emptyLinePlaceholder":368},[194,613,615,618],{"class":196,"line":614},31,[194,616,617],{"class":208},"  .carousel:focus-visible",[194,619,378],{"class":200},[194,621,623,626,628,630,632,635,638],{"class":196,"line":622},32,[194,624,625],{"class":208},"    outline",[194,627,324],{"class":200},[194,629,109],{"class":208},[194,631,331],{"class":330},[194,633,634],{"class":208}," solid",[194,636,637],{"class":208}," #2563eb",[194,639,392],{"class":200},[194,641,643,646,648,650,652],{"class":196,"line":642},33,[194,644,645],{"class":208},"    outline-offset",[194,647,324],{"class":200},[194,649,109],{"class":208},[194,651,331],{"class":330},[194,653,392],{"class":200},[194,655,657],{"class":196,"line":656},34,[194,658,574],{"class":200},[194,660,662],{"class":196,"line":661},35,[194,663,369],{"emptyLinePlaceholder":368},[194,665,667,670],{"class":196,"line":666},36,[194,668,669],{"class":208},"  .slide",[194,671,378],{"class":200},[194,673,675,678,680,683],{"class":196,"line":674},37,[194,676,677],{"class":208},"    scroll-snap-align",[194,679,324],{"class":200},[194,681,682],{"class":208},"start",[194,684,392],{"class":200},[194,686,688],{"class":196,"line":687},38,[194,689,690],{"class":398},"    \u002F* Stop fast flicks from skipping slides: each gesture ends on the\n",[194,692,694],{"class":196,"line":693},39,[194,695,696],{"class":398},"       next or previous slide at most. *\u002F\n",[194,698,700,703,705,708],{"class":196,"line":699},40,[194,701,702],{"class":208},"    scroll-snap-stop",[194,704,324],{"class":200},[194,706,707],{"class":208},"always",[194,709,392],{"class":200},[194,711,713,716,718,721,723],{"class":196,"line":712},41,[194,714,715],{"class":208},"    min-height",[194,717,324],{"class":200},[194,719,720],{"class":208},"10",[194,722,359],{"class":330},[194,724,392],{"class":200},[194,726,728,730,732,734,736],{"class":196,"line":727},42,[194,729,521],{"class":208},[194,731,324],{"class":200},[194,733,438],{"class":208},[194,735,359],{"class":330},[194,737,392],{"class":200},[194,739,741,744,746,748,750],{"class":196,"line":740},43,[194,742,743],{"class":208},"    border-radius",[194,745,324],{"class":200},[194,747,106],{"class":208},[194,749,331],{"class":330},[194,751,392],{"class":200},[194,753,755,758,760,763,766,769,772,774,777,779,782],{"class":196,"line":754},44,[194,756,757],{"class":208},"    background",[194,759,324],{"class":200},[194,761,762],{"class":208},"linear-gradient",[194,764,765],{"class":200},"(",[194,767,768],{"class":208},"135",[194,770,771],{"class":330},"deg",[194,773,343],{"class":200},[194,775,776],{"class":208},"#dbeafe",[194,778,343],{"class":200},[194,780,781],{"class":208},"#c7d2fe",[194,783,784],{"class":200},");\n",[194,786,788,791,793,796],{"class":196,"line":787},45,[194,789,790],{"class":208},"    color",[194,792,324],{"class":200},[194,794,795],{"class":208},"#1e1b4b",[194,797,392],{"class":200},[194,799,801],{"class":196,"line":800},46,[194,802,574],{"class":200},[194,804,806],{"class":196,"line":805},47,[194,807,369],{"emptyLinePlaceholder":368},[194,809,811],{"class":196,"line":810},48,[194,812,813],{"class":398},"  \u002F* Prev\u002Fnext are ordinary in-page links to slide ids; the browser\n",[194,815,817],{"class":196,"line":816},49,[194,818,819],{"class":398},"     scrolls the carousel, and snap settles the position. *\u002F\n",[194,821,823,826,828,831,833,836,838,841,843,845,847,849,852,854,856,858],{"class":196,"line":822},50,[194,824,825],{"class":208},"  .carousel-nav",[194,827,318],{"class":200},[194,829,830],{"class":208},"display",[194,832,324],{"class":200},[194,834,835],{"class":208},"flex",[194,837,349],{"class":200},[194,839,840],{"class":208},"gap",[194,842,324],{"class":200},[194,844,526],{"class":208},[194,846,359],{"class":330},[194,848,349],{"class":200},[194,850,851],{"class":208},"margin-top",[194,853,324],{"class":200},[194,855,526],{"class":208},[194,857,359],{"class":330},[194,859,362],{"class":200},[194,861,863,865,868],{"class":196,"line":862},51,[194,864,825],{"class":208},[194,866,867],{"class":204}," a",[194,869,378],{"class":200},[194,871,873,875,877,880,882,885,887],{"class":196,"line":872},52,[194,874,521],{"class":208},[194,876,324],{"class":200},[194,878,879],{"class":208},"0.4",[194,881,359],{"class":330},[194,883,884],{"class":208}," 0.8",[194,886,359],{"class":330},[194,888,392],{"class":200},[194,890,892,895,897,899,901,903,906],{"class":196,"line":891},53,[194,893,894],{"class":208},"    border",[194,896,324],{"class":200},[194,898,438],{"class":208},[194,900,331],{"class":330},[194,902,634],{"class":208},[194,904,905],{"class":208}," #94a3b8",[194,907,392],{"class":200},[194,909,911,913,915,917,919],{"class":196,"line":910},54,[194,912,743],{"class":208},[194,914,324],{"class":200},[194,916,123],{"class":208},[194,918,331],{"class":330},[194,920,392],{"class":200},[194,922,924,926,928,931],{"class":196,"line":923},55,[194,925,790],{"class":208},[194,927,324],{"class":200},[194,929,930],{"class":208},"inherit",[194,932,392],{"class":200},[194,934,936,939,941,943],{"class":196,"line":935},56,[194,937,938],{"class":208},"    text-decoration",[194,940,324],{"class":200},[194,942,107],{"class":208},[194,944,392],{"class":200},[194,946,948],{"class":196,"line":947},57,[194,949,574],{"class":200},[194,951,953,956,958],{"class":196,"line":952},58,[194,954,955],{"class":200},"\u003C\u002F",[194,957,307],{"class":204},[194,959,212],{"class":200},[194,961,963,965,967],{"class":196,"line":962},59,[194,964,955],{"class":200},[194,966,240],{"class":204},[194,968,212],{"class":200},[194,970,972,974,977],{"class":196,"line":971},60,[194,973,218],{"class":200},[194,975,976],{"class":204},"body",[194,978,212],{"class":200},[194,980,982,985,988,991,993,996],{"class":196,"line":981},61,[194,983,984],{"class":200},"  \u003C",[194,986,987],{"class":204},"section",[194,989,990],{"class":208}," aria-labelledby",[194,992,226],{"class":200},[194,994,995],{"class":229},"\"c-title\"",[194,997,212],{"class":200},[194,999,1001,1004,1006,1009,1011,1013,1016,1018],{"class":196,"line":1000},62,[194,1002,1003],{"class":200},"    \u003C",[194,1005,29],{"class":204},[194,1007,1008],{"class":208}," id",[194,1010,226],{"class":200},[194,1012,995],{"class":229},[194,1014,1015],{"class":200},">Featured trails\u003C\u002F",[194,1017,29],{"class":204},[194,1019,212],{"class":200},[194,1021,1023,1025,1028,1031,1033,1036,1039,1041,1044,1047,1049,1052,1055,1057,1060],{"class":196,"line":1022},63,[194,1024,1003],{"class":200},[194,1026,1027],{"class":204},"div",[194,1029,1030],{"class":208}," class",[194,1032,226],{"class":200},[194,1034,1035],{"class":229},"\"carousel\"",[194,1037,1038],{"class":208}," tabindex",[194,1040,226],{"class":200},[194,1042,1043],{"class":229},"\"0\"",[194,1045,1046],{"class":208}," role",[194,1048,226],{"class":200},[194,1050,1051],{"class":229},"\"group\"",[194,1053,1054],{"class":208}," aria-label",[194,1056,226],{"class":200},[194,1058,1059],{"class":229},"\"Featured trails, scroll horizontally\"",[194,1061,212],{"class":200},[194,1063,1065,1068,1071,1073,1075,1078,1080,1082,1085,1088,1091,1094,1096,1098,1100,1103,1105,1108,1110],{"class":196,"line":1064},64,[194,1066,1067],{"class":200},"      \u003C",[194,1069,1070],{"class":204},"article",[194,1072,1030],{"class":208},[194,1074,226],{"class":200},[194,1076,1077],{"class":229},"\"slide\"",[194,1079,1008],{"class":208},[194,1081,226],{"class":200},[194,1083,1084],{"class":229},"\"s1\"",[194,1086,1087],{"class":200},">\u003C",[194,1089,1090],{"class":204},"h3",[194,1092,1093],{"class":200},">Ridge Loop\u003C\u002F",[194,1095,1090],{"class":204},[194,1097,1087],{"class":200},[194,1099,14],{"class":204},[194,1101,1102],{"class":200},">12 km, moderate.\u003C\u002F",[194,1104,14],{"class":204},[194,1106,1107],{"class":200},">\u003C\u002F",[194,1109,1070],{"class":204},[194,1111,212],{"class":200},[194,1113,1115,1117,1119,1121,1123,1125,1127,1129,1132,1134,1136,1139,1141,1143,1145,1148,1150,1152,1154],{"class":196,"line":1114},65,[194,1116,1067],{"class":200},[194,1118,1070],{"class":204},[194,1120,1030],{"class":208},[194,1122,226],{"class":200},[194,1124,1077],{"class":229},[194,1126,1008],{"class":208},[194,1128,226],{"class":200},[194,1130,1131],{"class":229},"\"s2\"",[194,1133,1087],{"class":200},[194,1135,1090],{"class":204},[194,1137,1138],{"class":200},">Lake Path\u003C\u002F",[194,1140,1090],{"class":204},[194,1142,1087],{"class":200},[194,1144,14],{"class":204},[194,1146,1147],{"class":200},">6 km, easy.\u003C\u002F",[194,1149,14],{"class":204},[194,1151,1107],{"class":200},[194,1153,1070],{"class":204},[194,1155,212],{"class":200},[194,1157,1159,1161,1163,1165,1167,1169,1171,1173,1176,1178,1180,1183,1185,1187,1189,1192,1194,1196,1198],{"class":196,"line":1158},66,[194,1160,1067],{"class":200},[194,1162,1070],{"class":204},[194,1164,1030],{"class":208},[194,1166,226],{"class":200},[194,1168,1077],{"class":229},[194,1170,1008],{"class":208},[194,1172,226],{"class":200},[194,1174,1175],{"class":229},"\"s3\"",[194,1177,1087],{"class":200},[194,1179,1090],{"class":204},[194,1181,1182],{"class":200},">Summit Trail\u003C\u002F",[194,1184,1090],{"class":204},[194,1186,1087],{"class":200},[194,1188,14],{"class":204},[194,1190,1191],{"class":200},">18 km, hard.\u003C\u002F",[194,1193,14],{"class":204},[194,1195,1107],{"class":200},[194,1197,1070],{"class":204},[194,1199,212],{"class":200},[194,1201,1203,1205,1207,1209,1211,1213,1215,1217,1220,1222,1224,1227,1229,1231,1233,1236,1238,1240,1242],{"class":196,"line":1202},67,[194,1204,1067],{"class":200},[194,1206,1070],{"class":204},[194,1208,1030],{"class":208},[194,1210,226],{"class":200},[194,1212,1077],{"class":229},[194,1214,1008],{"class":208},[194,1216,226],{"class":200},[194,1218,1219],{"class":229},"\"s4\"",[194,1221,1087],{"class":200},[194,1223,1090],{"class":204},[194,1225,1226],{"class":200},">Forest Walk\u003C\u002F",[194,1228,1090],{"class":204},[194,1230,1087],{"class":200},[194,1232,14],{"class":204},[194,1234,1235],{"class":200},">4 km, easy.\u003C\u002F",[194,1237,14],{"class":204},[194,1239,1107],{"class":200},[194,1241,1070],{"class":204},[194,1243,212],{"class":200},[194,1245,1247,1250,1252],{"class":196,"line":1246},68,[194,1248,1249],{"class":200},"    \u003C\u002F",[194,1251,1027],{"class":204},[194,1253,212],{"class":200},[194,1255,1257,1259,1262,1264,1266,1269,1271,1273,1276],{"class":196,"line":1256},69,[194,1258,1003],{"class":200},[194,1260,1261],{"class":204},"nav",[194,1263,1030],{"class":208},[194,1265,226],{"class":200},[194,1267,1268],{"class":229},"\"carousel-nav\"",[194,1270,1054],{"class":208},[194,1272,226],{"class":200},[194,1274,1275],{"class":229},"\"Jump to trail\"",[194,1277,212],{"class":200},[194,1279,1281,1283,1285,1288,1290,1293,1296,1298,1300,1302,1304,1306,1309,1312,1314,1316,1318,1320,1322,1325,1328,1330,1332,1334,1336,1338,1341,1344,1346],{"class":196,"line":1280},70,[194,1282,1067],{"class":200},[194,1284,18],{"class":204},[194,1286,1287],{"class":208}," href",[194,1289,226],{"class":200},[194,1291,1292],{"class":229},"\"#s1\"",[194,1294,1295],{"class":200},">1\u003C\u002F",[194,1297,18],{"class":204},[194,1299,1087],{"class":200},[194,1301,18],{"class":204},[194,1303,1287],{"class":208},[194,1305,226],{"class":200},[194,1307,1308],{"class":229},"\"#s2\"",[194,1310,1311],{"class":200},">2\u003C\u002F",[194,1313,18],{"class":204},[194,1315,1087],{"class":200},[194,1317,18],{"class":204},[194,1319,1287],{"class":208},[194,1321,226],{"class":200},[194,1323,1324],{"class":229},"\"#s3\"",[194,1326,1327],{"class":200},">3\u003C\u002F",[194,1329,18],{"class":204},[194,1331,1087],{"class":200},[194,1333,18],{"class":204},[194,1335,1287],{"class":208},[194,1337,226],{"class":200},[194,1339,1340],{"class":229},"\"#s4\"",[194,1342,1343],{"class":200},">4\u003C\u002F",[194,1345,18],{"class":204},[194,1347,212],{"class":200},[194,1349,1351,1353,1355],{"class":196,"line":1350},71,[194,1352,1249],{"class":200},[194,1354,1261],{"class":204},[194,1356,212],{"class":200},[194,1358,1360,1363,1365],{"class":196,"line":1359},72,[194,1361,1362],{"class":200},"  \u003C\u002F",[194,1364,987],{"class":204},[194,1366,212],{"class":200},[194,1368,1370,1372,1374],{"class":196,"line":1369},73,[194,1371,955],{"class":200},[194,1373,976],{"class":204},[194,1375,212],{"class":200},[194,1377,1379,1381,1383],{"class":196,"line":1378},74,[194,1380,955],{"class":200},[194,1382,189],{"class":204},[194,1384,212],{"class":200},[14,1386,1387,1388,1391,1392,1395,1396,1399],{},"The grid with ",[55,1389,1390],{},"grid-auto-flow: column"," is the cleanest way to lay slides out in a row with consistent widths; a flex row with ",[55,1393,1394],{},"flex: 0 0 80%"," works equally well. The ",[55,1397,1398],{},"tabindex=\"0\""," on the scroller is what makes keyboard scrolling possible — a focused scroll container responds to arrow keys, Page Up and Page Down — and the label tells screen-reader users what the region is and how to use it.",[29,1401,1403,1404,1407],{"id":1402},"the-key-technique-scroll-snap-stop-and-in-page-links","The key technique: ",[55,1405,1406],{},"scroll-snap-stop"," and in-page links",[14,1409,1410,1411,1414,1415,1417],{},"Two features turn a snapping row into a usable carousel. ",[55,1412,1413],{},"scroll-snap-stop: always"," stops a fast flick from sailing past several slides. By default, a hard swipe can travel across many snap points and settle on a distant one, which is fine for a long list but disorienting in a carousel where each slide deserves a look. With ",[55,1416,707],{},", a gesture can pass at most one snap point.",[75,1419,82,1422,82,1425,82,1428,82,1431,82,1437,82,1442,82,1445,82,1448,82,1451,82,1454,82,1458,82,1463,82,1466,82,1469,82,1471,82,1473,82,1475,82,1477,82,1479,82,1482,82,1486],{"viewBox":1420,"role":78,"ariaLabel":1421,"xmlns":80,"style":81},"0 0 720 260","A fast flick passing three slides with normal stop versus stopping at the next slide with scroll-snap-stop always",[84,1423,1424],{},"scroll-snap-stop: normal versus always",[88,1426,1427],{},"Two rows of five slides. In the top row, labelled normal, a fast flick from slide one ends on slide four. In the bottom row, labelled always, the same flick ends on slide two.",[92,1429,1430],{"textAnchor":94,"x":95,"y":96,"style":97},"The same fast flick, two settings",[92,1432,1436],{"textAnchor":682,"x":1433,"y":1434,"style":1435},"40","72","text-anchor:start;fill:currentColor;font:600 12px ui-monospace,monospace","normal",[100,1438],{"x":151,"y":1439,"width":1440,"height":1433,"rx":123,"fill":120,"opacity":1441},"50","100","0.18",[100,1443],{"x":1444,"y":1439,"width":1440,"height":1433,"rx":123,"fill":120,"opacity":1441},"230",[100,1446],{"x":1447,"y":1439,"width":1440,"height":1433,"rx":123,"fill":120,"opacity":1441},"340",[100,1449],{"x":1450,"y":1439,"width":1440,"height":1433,"rx":123,"fill":120,"opacity":526},"450",[100,1452],{"x":1453,"y":1439,"width":1440,"height":1433,"rx":123,"fill":120,"opacity":1441},"560",[92,1455,438],{"textAnchor":94,"x":1456,"y":1457,"style":114},"170","75",[92,1459,1462],{"textAnchor":94,"x":1460,"y":1457,"style":1461},"500","text-anchor:middle;fill:currentColor;font:600 12px sans-serif","lands on 4",[117,1464],{"d":1465,"fill":107,"stroke":108,"strokeWidth":109,"opacity":110},"M170 104 Q335 140 500 104",[92,1467,707],{"textAnchor":682,"x":1433,"y":1468,"style":1435},"192",[100,1470],{"x":151,"y":1456,"width":1440,"height":1433,"rx":123,"fill":120,"opacity":1441},[100,1472],{"x":1444,"y":1456,"width":1440,"height":1433,"rx":123,"fill":120,"opacity":526},[100,1474],{"x":1447,"y":1456,"width":1440,"height":1433,"rx":123,"fill":120,"opacity":1441},[100,1476],{"x":1450,"y":1456,"width":1440,"height":1433,"rx":123,"fill":120,"opacity":1441},[100,1478],{"x":1453,"y":1456,"width":1440,"height":1433,"rx":123,"fill":120,"opacity":1441},[92,1480,438],{"textAnchor":94,"x":1456,"y":1481,"style":114},"195",[92,1483,1485],{"textAnchor":94,"x":1484,"y":1481,"style":1461},"280","lands on 2",[117,1487],{"d":1488,"fill":107,"stroke":108,"strokeWidth":109,"opacity":110},"M170 224 Q225 244 280 224",[14,1490,1491,1492,1495,1496,1498,1499,1502],{},"The second feature is simply HTML. A link to ",[55,1493,1494],{},"#s3"," asks the browser to scroll ",[55,1497,1494],{}," into view, and when the target is inside a horizontal scroll container, it is that container that scrolls. Snap then settles the position, and ",[55,1500,1501],{},"scroll-behavior: smooth"," animates the jump. The result is a working \"go to slide\" control built from anchor elements, which are keyboard-accessible, work without script, and are announced correctly by assistive technology. The one side effect is a changed URL hash; for most content carousels that is harmless or even useful, since it makes individual slides linkable.",[29,1504,1506],{"id":1505},"variation-responsive-slide-widths-with-container-queries","Variation: responsive slide widths with container queries",[14,1508,1509,1510,1514],{},"80% slides are right on a phone and wasteful on a desktop, where two or three slides should be visible at once. A ",[18,1511,1513],{"href":1512},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002F","container query"," on the carousel's wrapper adjusts the column width without touching the snap rules, because snap alignment is computed from whatever size the slides end up.",[185,1516,1520],{"className":1517,"code":1518,"language":1519,"meta":190,"style":190},"language-css shiki shiki-themes github-light-high-contrast github-dark-high-contrast",".carousel-wrap { container-type: inline-size; }\n\n\u002F* Two slides plus a peek on medium containers. *\u002F\n@container (width > 36rem) {\n  .carousel { grid-auto-columns: calc(45% - 0.5rem); }\n}\n\n\u002F* Three slides plus a peek on wide containers. *\u002F\n@container (width > 60rem) {\n  .carousel { grid-auto-columns: calc(30% - 0.66rem); }\n}\n\n\u002F* Center alignment reads better when several slides are visible. *\u002F\n@container (width > 60rem) {\n  .slide { scroll-snap-align: center; }\n}\n","css",[55,1521,1522,1535,1539,1544,1552,1584,1589,1593,1598,1605,1633,1637,1641,1646,1652,1667],{"__ignoreMap":190},[194,1523,1524,1527,1529,1532],{"class":196,"line":197},[194,1525,1526],{"class":208},".carousel-wrap",[194,1528,318],{"class":200},[194,1530,1531],{"class":208},"container-type",[194,1533,1534],{"class":200},": inline-size; }\n",[194,1536,1537],{"class":196,"line":215},[194,1538,369],{"emptyLinePlaceholder":368},[194,1540,1541],{"class":196,"line":235},[194,1542,1543],{"class":398},"\u002F* Two slides plus a peek on medium containers. *\u002F\n",[194,1545,1546,1549],{"class":196,"line":245},[194,1547,1548],{"class":330},"@container",[194,1550,1551],{"class":200}," (width > 36rem) {\n",[194,1553,1554,1556,1558,1561,1563,1566,1568,1571,1573,1576,1579,1581],{"class":196,"line":263},[194,1555,375],{"class":208},[194,1557,318],{"class":200},[194,1559,1560],{"class":208},"grid-auto-columns",[194,1562,324],{"class":200},[194,1564,1565],{"class":208},"calc",[194,1567,765],{"class":200},[194,1569,1570],{"class":208},"45",[194,1572,425],{"class":330},[194,1574,1575],{"class":330}," -",[194,1577,1578],{"class":208}," 0.5",[194,1580,359],{"class":330},[194,1582,1583],{"class":200},"); }\n",[194,1585,1586],{"class":196,"line":288},[194,1587,1588],{"class":200},"}\n",[194,1590,1591],{"class":196,"line":302},[194,1592,369],{"emptyLinePlaceholder":368},[194,1594,1595],{"class":196,"line":312},[194,1596,1597],{"class":398},"\u002F* Three slides plus a peek on wide containers. *\u002F\n",[194,1599,1600,1602],{"class":196,"line":365},[194,1601,1548],{"class":330},[194,1603,1604],{"class":200}," (width > 60rem) {\n",[194,1606,1607,1609,1611,1613,1615,1617,1619,1622,1624,1626,1629,1631],{"class":196,"line":372},[194,1608,375],{"class":208},[194,1610,318],{"class":200},[194,1612,1560],{"class":208},[194,1614,324],{"class":200},[194,1616,1565],{"class":208},[194,1618,765],{"class":200},[194,1620,1621],{"class":208},"30",[194,1623,425],{"class":330},[194,1625,1575],{"class":330},[194,1627,1628],{"class":208}," 0.66",[194,1630,359],{"class":330},[194,1632,1583],{"class":200},[194,1634,1635],{"class":196,"line":381},[194,1636,1588],{"class":200},[194,1638,1639],{"class":196,"line":395},[194,1640,369],{"emptyLinePlaceholder":368},[194,1642,1643],{"class":196,"line":402},[194,1644,1645],{"class":398},"\u002F* Center alignment reads better when several slides are visible. *\u002F\n",[194,1647,1648,1650],{"class":196,"line":415},[194,1649,1548],{"class":330},[194,1651,1604],{"class":200},[194,1653,1654,1656,1658,1660,1662,1665],{"class":196,"line":430},[194,1655,669],{"class":208},[194,1657,318],{"class":200},[194,1659,64],{"class":208},[194,1661,324],{"class":200},[194,1663,1664],{"class":208},"center",[194,1666,362],{"class":200},[194,1668,1669],{"class":196,"line":445},[194,1670,1588],{"class":200},[14,1672,1673,1674,1677,1678,1682,1683,1686,1687,1690],{},"The same wrapper is a natural place to add entry motion as slides scroll into view. With scroll-driven animations, a slide can fade and scale slightly as it enters the snapport using a ",[55,1675,1676],{},"view()"," timeline on the horizontal axis; the pattern is developed for vertical scrolling in ",[18,1679,1681],{"href":1680},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-triggered-reveal-animations\u002F","Scroll-Triggered Reveal Animations"," and works identically with ",[55,1684,1685],{},"view(inline)",". Keep such motion subtle and wrapped in a ",[55,1688,1689],{},"prefers-reduced-motion: no-preference"," query, because horizontal motion in a carousel is already a lot of movement.",[29,1692,1694],{"id":1693},"accessibility-checklist","Accessibility checklist",[1696,1697,1698,1713,1722,1728,1734,1740],"ul",{},[1699,1700,1701,1704,1705,1708,1709,1712],"li",{},[50,1702,1703],{},"Label the region."," A heading plus an ",[55,1706,1707],{},"aria-label"," or ",[55,1710,1711],{},"aria-labelledby"," on the scroller says what it contains.",[1699,1714,1715,1718,1719,1721],{},[50,1716,1717],{},"Make it focusable."," ",[55,1720,1398],{}," lets keyboard users scroll it; show a visible focus ring.",[1699,1723,1724,1727],{},[50,1725,1726],{},"Keep slides in order."," The DOM order is the reading order; never reorder slides visually.",[1699,1729,1730,1733],{},[50,1731,1732],{},"Do not hide off-screen slides from assistive technology."," They are real content that a screen-reader user can read linearly, which is often a better experience than a scripted carousel that hides them.",[1699,1735,1736,1739],{},[50,1737,1738],{},"No auto-advance."," Content that moves on its own for more than five seconds needs a pause control under WCAG 2.2.2; a scroll-snap carousel only moves when the user moves it.",[1699,1741,1742,1745],{},[50,1743,1744],{},"Visible controls."," Provide the jump links or buttons for users who cannot swipe or do not discover horizontal scrolling.",[29,1747,1749],{"id":1748},"browser-support","Browser support",[14,1751,1752,1753,343,1755,343,1757,1759,1760,1762,1763,1765],{},"CSS Scroll Snap — ",[55,1754,57],{},[55,1756,64],{},[55,1758,1406],{}," and ",[55,1761,68],{}," — is supported in all current versions of Chrome, Edge, Firefox and Safari. ",[55,1764,1501],{}," is supported in Chrome 61+, Edge 79+, Firefox 36+ and Safari 15.4+; elsewhere the jump links scroll instantly, which is still correct. Container queries for responsive slide widths need Chrome and Edge 105+, Firefox 110+ or Safari 16+. In an engine without scroll snap, the carousel is still a horizontally scrolling row of slides — fully usable, just without resting positions.",[29,1767,1769],{"id":1768},"faq","FAQ",[14,1771,1772,1775],{},[50,1773,1774],{},"Is a scroll-snap carousel accessible without JavaScript?","\nIt can be more accessible than many scripted carousels. The slides stay in normal document order, the scroller can receive keyboard focus and be scrolled with arrow keys, and nothing auto-advances. Give the scroller a label, make it focusable, and keep every slide's content reachable without hover.",[14,1777,1778,1788,1790,1791,1793,1794,1796,1797,1799],{},[50,1779,1780,1781,1759,1784,1787],{},"What is the difference between ",[55,1782,1783],{},"mandatory",[55,1785,1786],{},"proximity"," snapping?",[55,1789,1783],{}," always settles on a snap point when scrolling stops, even if the user stopped between two. ",[55,1792,1786],{}," only snaps when the resting position is close to a snap point. Use ",[55,1795,1783],{}," for one-slide-at-a-time carousels and ",[55,1798,1786],{}," for long rows where users may want to rest anywhere.",[14,1801,1802,1805,1806,1808,1809,1811,1812,1815],{},[50,1803,1804],{},"Why does my carousel snap the first slide under a notch or padding?","\nSnap alignment is computed against the scroller's snapport, which is its box minus ",[55,1807,68],{},". Without ",[55,1810,68],{},", start-aligned slides snap flush to the scroller's edge. Set ",[55,1813,1814],{},"scroll-padding-inline"," to match the visual padding so slides come to rest inside it.",[14,1817,1818,1821],{},[50,1819,1820],{},"Should a carousel auto-advance?","\nAvoid it. Auto-advancing content that lasts more than five seconds must have a pause control under WCAG 2.2.2, and moving content distracts and disorients many users. A scroll-snap carousel that only moves when the user moves it avoids the problem entirely.",[29,1823,1825],{"id":1824},"related","Related",[1696,1827,1828,1833,1840,1847],{},[1699,1829,1830,1832],{},[18,1831,21],{"href":20}," — the parent guide to scrolling layouts.",[1699,1834,1835,1839],{},[18,1836,1838],{"href":1837},"\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts\u002Fhorizontal-scrolling-card-rows\u002F","Horizontal Scrolling Card Rows"," — the lighter, proximity-snapped sibling of the carousel.",[1699,1841,1842,1846],{},[18,1843,1845],{"href":1844},"\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts\u002Foverscroll-behavior-for-nested-scrolling\u002F","overscroll-behavior for Nested Scrolling"," — stopping the carousel from dragging the page.",[1699,1848,1849,1853],{},[18,1850,1852],{"href":1851},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-driven-animation-fallbacks\u002F","Scroll-Driven Animation Fallbacks"," — enhancing slides with motion safely.",[307,1855,1856],{},"html pre.shiki code .suds8, html code.shiki .suds8{--shiki-default:#0E1116;--shiki-dark:#F0F3F6}html pre.shiki code .sne4z, html code.shiki .sne4z{--shiki-default:#024C1A;--shiki-dark:#72F088}html pre.shiki code .s-5SL, html code.shiki .s-5SL{--shiki-default:#023B95;--shiki-dark:#91CBFF}html pre.shiki code .sT6z2, html code.shiki .sT6z2{--shiki-default:#032563;--shiki-dark:#ADDCFF}html pre.shiki code .sHUrx, html code.shiki .sHUrx{--shiki-default:#A0111F;--shiki-dark:#FF9492}html pre.shiki code .sLBg1, html code.shiki .sLBg1{--shiki-default:#66707B;--shiki-dark:#BDC4CC}html .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":190,"searchDepth":215,"depth":215,"links":1858},[1859,1860,1861,1862,1864,1865,1866,1867,1868],{"id":31,"depth":215,"text":32},{"id":44,"depth":215,"text":45},{"id":178,"depth":215,"text":179},{"id":1402,"depth":215,"text":1863},"The key technique: scroll-snap-stop and in-page links",{"id":1505,"depth":215,"text":1506},{"id":1693,"depth":215,"text":1694},{"id":1748,"depth":215,"text":1749},{"id":1768,"depth":215,"text":1769},{"id":1824,"depth":215,"text":1825},"Build an accessible carousel with scroll-snap-type, snap alignment and scroll-padding: swipe, trackpad and keyboard support with no script, plus jump links.","md",{"pageTitle":1872,"datePublished":1873,"dateModified":1873,"faq":1874},"CSS-Only Carousel With Scroll Snap","2026-09-18",[1875,1877,1880,1882],{"q":1774,"a":1876},"It can be more accessible than many scripted carousels. The slides stay in normal document order, the scroller can receive keyboard focus and be scrolled with arrow keys, and nothing auto-advances. Give the scroller a label, make it focusable, and keep every slide's content reachable without hover.",{"q":1878,"a":1879},"What is the difference between mandatory and proximity snapping?","mandatory always settles on a snap point when scrolling stops, even if the user stopped between two. proximity only snaps when the resting position is close to a snap point. Use mandatory for one-slide-at-a-time carousels and proximity for long rows where users may want to rest anywhere.",{"q":1804,"a":1881},"Snap alignment is computed against the scroller's snapport, which is its box minus scroll-padding. Without scroll-padding, start-aligned slides snap flush to the scroller's edge. Set scroll-padding-inline to match the visual padding so slides come to rest inside it.",{"q":1820,"a":1883},"Avoid it. Auto-advancing content that lasts more than five seconds must have a pause control under WCAG 2.2.2, and moving content distracts and disorients many users. A scroll-snap carousel that only moves when the user moves it avoids the problem entirely.","\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts\u002Fcss-only-carousel-with-scroll-snap",{"title":5,"description":1869},"mastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts\u002Fcss-only-carousel-with-scroll-snap\u002Findex","yQzFpwC_gpCzcvKsDTwwKAp_X71lSyWguWzWix75s4I",[1889,1892,1895,1898,1901,1904,1907,1910,1913,1916,1919,1922,1925,1928,1931,1934,1937,1940,1943,1946,1949,1952,1955,1958,1961,1964,1967,1970,1973,1976,1979,1982,1985,1988,1991,1994,1997,2000,2003,2006,2009,2012,2015,2018,2021,2024,2027,2030,2033,2036,2039,2042,2045,2048,2051,2054,2057,2060,2063,2066,2069,2072,2075,2078,2081,2084,2087,2090,2093,2096,2099,2102,2105,2108,2111,2114,2117,2120,2123,2126,2129,2132,2135,2138,2141,2144,2147,2150,2153,2156,2159,2162,2165,2168,2170,2173,2176,2179,2182,2185,2188,2191,2194,2197,2200,2203,2206,2209,2212,2215,2218,2221,2224,2227,2230,2233,2236,2239,2242,2245,2248,2251,2254,2257,2260,2263,2266,2269,2272,2275,2278,2281,2284,2287,2290,2293,2296,2299,2302,2305,2308,2310,2313,2316,2319,2322,2325,2328,2331,2334,2337,2340,2343,2346,2349,2352,2355,2358,2361,2364,2367,2370,2373,2376,2379,2382,2385,2388,2391,2394,2397,2398,2401,2404,2407,2410,2413,2416,2419,2422,2425,2428,2431,2434,2437,2440,2443],{"path":1890,"title":1891},"\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":1893,"title":1894},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fflashing-content-and-seizure-thresholds","Flashing Content and Seizure Thresholds",{"path":1896,"title":1897},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fforced-colors-mode-and-animations","Forced Colors Mode and Animations",{"path":1899,"title":1900},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations","Accessibility in CSS Animations: Patterns, Specs & Best Practices",{"path":1902,"title":1903},"\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":1905,"title":1906},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fprefers-reduced-motion-recipes","prefers-reduced-motion Recipes: A Reduction for Every Common Effect",{"path":1908,"title":1909},"\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":1911,"title":1912},"\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":1914,"title":1915},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fvestibular-safe-animation-patterns","Vestibular-Safe Animation Patterns: Why Some Motion Makes People Sick",{"path":1917,"title":1918},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fwcag-motion-success-criteria","WCAG Motion Success Criteria: What Each One Actually Requires",{"path":1920,"title":1921},"\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":1923,"title":1924},"\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":1926,"title":1927},"\u002Fcss-only-micro-interactions-animations\u002Fclip-path-and-mask-animations","Clip-Path & Mask Animations: Animating Visibility Instead of Position",{"path":1929,"title":1930},"\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":1932,"title":1933},"\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":1935,"title":1936},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions\u002Fanimating-gradients","Animating CSS Gradients: Smooth Colour Motion Without Jumps",{"path":1938,"title":1939},"\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":1941,"title":1942},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions","Color & Theme Transitions: Colour as Part of the Motion System",{"path":1944,"title":1945},"\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":1947,"title":1948},"\u002Fcss-only-micro-interactions-animations\u002Fcolor-and-theme-transitions\u002Fsmooth-theme-switching-transitions","Smooth Theme Switching: Crossfades, Circular Reveals and No Flash",{"path":1950,"title":1951},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fcontainer-query-hover-affordances","Container Query Hover Affordances: When Narrow Means Persistent, Not Hidden",{"path":1953,"title":1954},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion","Container-Aware Motion: Animation Sized by the Space a Component Actually Has",{"path":1956,"title":1957},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Flayout-change-animations-at-container-breakpoints","Animating Changes at Container Breakpoints",{"path":1959,"title":1960},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fmotion-driven-by-container-style-queries","Motion Driven by Container Style Queries",{"path":1962,"title":1963},"\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":1965,"title":1966},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fsuppressing-motion-in-small-containers","Suppressing Motion in Small Containers: Deliberately Animating Nothing",{"path":1968,"title":1969},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api\u002Fcontrolling-css-animations-from-javascript","Controlling CSS Animations From JavaScript",{"path":1971,"title":1972},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api","CSS Animation vs the Web Animations API: A Decision Guide",{"path":1974,"title":1975},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api\u002Fwaapi-vs-css-for-interruptible-ui","Interruptible UI: CSS Transitions vs WAAPI",{"path":1977,"title":1978},"\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":1980,"title":1981},"\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":1983,"title":1984},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Fcustom-property-fallbacks-and-invalid-values","Custom Property Fallbacks and Invalid Values",{"path":1986,"title":1987},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Ffluid-spacing-tokens-driving-transition-durations","Fluid Spacing Tokens That Drive Transition Durations",{"path":1989,"title":1990},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture","CSS Custom Properties Architecture: Scalable Design Systems & Dynamic UI",{"path":1992,"title":1993},"\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":1995,"title":1996},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Fscoping-custom-properties-to-components","Scoping Custom Properties to Components",{"path":1998,"title":1999},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fcss-transition-timing-functions","CSS Transition Timing Functions: ease, cubic-bezier(), steps() and linear()",{"path":2001,"title":2002},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals","CSS Transition Fundamentals: Architecture, Performance & Patterns",{"path":2004,"title":2005},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Finterrupted-and-reversing-transitions","Interrupted and Reversing Transitions: What Happens Mid-Flight",{"path":2007,"title":2008},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fstarting-style-entry-animations","@starting-style: Animating an Element's Very First Style Change",{"path":2010,"title":2011},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransition-delay-choreography","Choreographing Motion With transition-delay",{"path":2013,"title":2014},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransition-shorthand-and-multiple-properties","The transition Shorthand and Multiple Properties",{"path":2016,"title":2017},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransitioning-display-with-allow-discrete","Transitioning display with transition-behavior: allow-discrete and @starting-style",{"path":2019,"title":2020},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Fanimating-dialog-open-and-close","Animating \u003Cdialog> Open and Close: Both Directions, No Library",{"path":2022,"title":2023},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Fbackdrop-animations","Animating ::backdrop: Fades and Blurs Behind Dialogs and Popovers",{"path":2025,"title":2026},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations","Dialog & Popover Animations: Motion for the Top Layer",{"path":2028,"title":2029},"\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":2031,"title":2032},"\u002Fcss-only-micro-interactions-animations\u002Fdialog-and-popover-animations\u002Fpopover-entry-and-exit-transitions","Popover Menus That Animate From Their Anchor",{"path":2034,"title":2035},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fchoosing-animation-durations","Choosing Animation Durations: How Long Motion Should Last",{"path":2037,"title":2038},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fcubic-bezier-overshoot-and-anticipation","Overshoot and Anticipation With cubic-bezier(): Motion With Character",{"path":2040,"title":2041},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design\u002Fentry-vs-exit-easing","Entry vs Exit Easing: Different Curves for Arriving and Leaving",{"path":2043,"title":2044},"\u002Fcss-only-micro-interactions-animations\u002Feasing-and-motion-design","Easing & Motion Design: Making CSS Motion Feel Intentional",{"path":2046,"title":2047},"\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":2049,"title":2050},"\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":2052,"title":2053},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Faccessible-css-only-tooltips","Accessible CSS-Only Tooltips and Hover Cards With  and ",{"path":2055,"title":2056},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Fbutton-press-and-active-states","Button Press and  States",{"path":2058,"title":2059},"\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":2061,"title":2062},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Ffocus-within-form-patterns"," Form Patterns: Styling a Group From the Field Inside It",{"path":2064,"title":2065},"\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":2067,"title":2068},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design","Hover & Focus State Design: Spec-Compliant Patterns for Modern UIs",{"path":2070,"title":2071},"\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":2073,"title":2074},"\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":2076,"title":2077},"\u002Fcss-only-micro-interactions-animations","CSS-Only Micro-Interactions & Animations: Architecture, Performance & Implementation",{"path":2079,"title":2080},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fanimation-composition-and-stacking","Stacking Animations With animation-composition",{"path":2082,"title":2083},"\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":2085,"title":2086},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcontainer-query-triggered-keyframe-animations","Container-Query-Triggered Keyframe Animations: Animate Differently per Available Space",{"path":2088,"title":2089},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcss-only-accordions-and-disclosure","CSS-Only Accordions and Disclosure Widgets with details and summary",{"path":2091,"title":2092},"\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":2094,"title":2095},"\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":2097,"title":2098},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns","Keyframe Animation Patterns: Spec-Compliant Architectures for Modern UIs",{"path":2100,"title":2101},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fmulti-step-keyframes-and-per-keyframe-easing","Multi-Step Keyframes and Per-Keyframe Easing",{"path":2103,"title":2104},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fstaggered-list-animations-with-custom-properties","Staggered List Animations Using --i Index Custom Properties",{"path":2106,"title":2107},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fanimating-box-shadow-and-filters-cheaply","Animating box-shadow and Filters Cheaply",{"path":2109,"title":2110},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fcontain-property-for-animation-performance","The contain Property for Animation Performance",{"path":2112,"title":2113},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Fcss-triggers-layout-paint-composite","Layout, Paint and Composite: What Triggers What",{"path":2115,"title":2116},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration","Performance & GPU Acceleration in CSS: A Developer’s Blueprint",{"path":2118,"title":2119},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Foptimizing-css-animations-for-60fps","Optimizing CSS Animations for 60fps: Budgeting the Frame",{"path":2121,"title":2122},"\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":2124,"title":2125},"\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":2127,"title":2128},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations","Scroll-Driven Animations: Binding Motion to Scroll Position in Pure CSS",{"path":2130,"title":2131},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-driven-animation-fallbacks","Shipping Scroll-Driven Animations Without Breaking Anything",{"path":2133,"title":2134},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-driven-parallax-effects","Scroll-Driven Parallax Effects in CSS",{"path":2136,"title":2137},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-progress-bar-without-javascript","A Reading Progress Bar Driven by scroll(root)",{"path":2139,"title":2140},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-triggered-reveal-animations","Reveal-on-Scroll with view() and animation-range",{"path":2142,"title":2143},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Ftimeline-scope-for-cross-element-animations","timeline-scope for Cross-Element Animations",{"path":2145,"title":2146},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fview-timeline-and-animation-range","View Timelines and animation-range",{"path":2148,"title":2149},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fcross-document-view-transitions","Cross-Document View Transitions",{"path":2151,"title":2152},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers","View Transitions for CSS Developers: the Pseudo-Element Tree, Snapshots, and Named Elements",{"path":2154,"title":2155},"\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":2157,"title":2158},"\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":2160,"title":2161},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transition-types-and-classes","View Transition Types and Classes",{"path":2163,"title":2164},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transitions-for-list-reordering","View Transitions for List Reordering",{"path":2166,"title":2167},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transitions-with-reduced-motion","Honouring prefers-reduced-motion in View Transitions",{"path":334,"title":2169},"Modern CSS Layouts & Micro-Interactions",{"path":2171,"title":2172},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-positioned-tooltips","Anchor-Positioned Tooltips: Tethering, Flipping, and Getting the Semantics Right",{"path":2174,"title":2175},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-positioning-fallbacks","Anchor Positioning Fallbacks: A Graceful Floor for Older Browser Versions",{"path":2177,"title":2178},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-size-for-matching-widths","anchor-size(): Overlays That Match Their Trigger's Size",{"path":2180,"title":2181},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays","CSS Anchor Positioning and Overlays: Tethering Elements Without JavaScript",{"path":2183,"title":2184},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fpopover-attribute-and-css-styling","The popover Attribute: Top-Layer Overlays With No JavaScript",{"path":2186,"title":2187},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fpopover-light-dismiss-and-stacking","Popover Light Dismiss, Nesting and Stacking",{"path":2189,"title":2190},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fposition-area-grid-explained","position-area: The Anchor Placement Grid",{"path":2192,"title":2193},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fcontainer-query-polyfill-tradeoffs","Container Query Polyfills: What They Cost and When to Skip Them",{"path":2195,"title":2196},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Ffeature-detection-with-supports","Feature Detection with @supports: Syntax, Semantics, and the Traps",{"path":2198,"title":2199},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fhandling-container-query-fallbacks-for-older-browsers","Handling Container Query Fallbacks for Older Browsers",{"path":2201,"title":2202},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks","Container Query Fallbacks: Spec-Compliant CSS Strategies for Legacy Browsers",{"path":2204,"title":2205},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fintrinsic-layout-fallbacks-without-queries","Intrinsic Layout Fallbacks: Baselines That Adapt Without Any Query",{"path":2207,"title":2208},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Ftesting-fallbacks-without-old-browsers","Testing CSS Fallbacks Without an Old Browser",{"path":2210,"title":2211},"\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":2213,"title":2214},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-query-range-and-logic-operators","Container Query Range Syntax and Logic Operators",{"path":2216,"title":2217},"\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":2219,"title":2220},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-type-size-vs-inline-size","Choosing container-type: inline-size, size, or normal",{"path":2222,"title":2223},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-vs-media-queries-comparison","Container vs Media Queries: Choosing the Right Reference Box",{"path":2225,"title":2226},"\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":2228,"title":2229},"\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":2231,"title":2232},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics","Container Query Syntax Basics",{"path":2234,"title":2235},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fnesting-and-naming-container-queries","Nesting and Naming Container Queries: Targeting the Right Ancestor",{"path":2237,"title":2238},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fauto-fit-minmax-responsive-grids","Responsive Grids with repeat(auto-fit, minmax())",{"path":2240,"title":2241},"\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":2243,"title":2244},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fgrid-auto-flow-dense-packing","grid-auto-flow: dense for Packed Layouts",{"path":2246,"title":2247},"\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":2249,"title":2250},"\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":2252,"title":2253},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts","CSS Grid and Subgrid Layouts for Responsive Interfaces",{"path":2255,"title":2256},"\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":2258,"title":2259},"\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":2261,"title":2262},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fsubgrid-vs-nested-grid","Subgrid vs an Independently Nested Grid",{"path":2264,"title":2265},"\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":2267,"title":2268},"\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":2270,"title":2271},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflex-grow-and-flex-shrink-explained","flex-grow and flex-shrink Explained",{"path":2273,"title":2274},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflex-wrap-intrinsic-responsive-rows","Breakpoint-Free Responsive Rows With flex-wrap and flex-basis",{"path":2276,"title":2277},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns\u002Fflexbox-gap-and-spacing","Flexbox gap vs Margins: Spacing Items Without Edge Hacks",{"path":2279,"title":2280},"\u002Fmastering-container-queries-responsive-layouts\u002Fflexbox-layout-patterns","Flexbox Layout Patterns: One-Dimensional Layout for Real Components",{"path":2282,"title":2283},"\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":2285,"title":2286},"\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":2288,"title":2289},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Fdebugging-clamp-values","Debugging clamp(): Values That Are Ignored, Stuck or Never Fluid",{"path":2291,"title":2292},"\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":2294,"title":2295},"\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":2297,"title":2298},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-type-accessibility-and-zoom","Fluid Type, Accessibility and Zoom: The vw-Only Trap",{"path":2300,"title":2301},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-typography-without-javascript","Fluid Typography Without JavaScript: A Precision CSS Reference",{"path":2303,"title":2304},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp","Fluid Typography with clamp(): A Practical Guide for Modern CSS",{"path":2306,"title":2307},"\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":2309,"title":26},"\u002Fmastering-container-queries-responsive-layouts",{"path":2311,"title":2312},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Faspect-ratio-for-responsive-media","Using aspect-ratio for Responsive Media and Preventing Layout Shift",{"path":2314,"title":2315},"\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":2317,"title":2318},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques","Intrinsic Sizing Techniques: Modern CSS Layouts for Responsive UI",{"path":2320,"title":2321},"\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":2323,"title":2324},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fmin-max-fit-content-explained","min-content, max-content, and fit-content() Explained",{"path":2326,"title":2327},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fobject-fit-and-object-position","object-fit and object-position: Images That Fit Any Box",{"path":2329,"title":2330},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fpreventing-flex-and-grid-overflow","The min-width: auto Trap in Flex and Grid Layouts",{"path":2332,"title":2333},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-for-reset-and-tokens","Cascade Layers for Reset and Design Tokens",{"path":2335,"title":2336},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-vs-specificity-hacks","Cascade Layers vs Specificity Hacks: Ordering Instead of Escalating",{"path":2338,"title":2339},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcss-scope-for-component-styles","@scope for Component Styles: Short Selectors That Cannot Leak",{"path":2341,"title":2342},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies","Modern CSS Reset Strategies: A Spec-Compliant Foundation",{"path":2344,"title":2345},"\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":2347,"title":2348},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fwriting-a-minimal-modern-reset","Writing a Minimal Modern CSS Reset: Every Line Justified",{"path":2350,"title":2351},"\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":2353,"title":2354},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has\u002Fempty-and-loading-states-with-has","Empty and Loading States With ()",{"path":2356,"title":2357},"\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":2359,"title":2360},"\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":2362,"title":2363},"\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":2365,"title":2366},"\u002Fmastering-container-queries-responsive-layouts\u002Fparent-aware-layouts-with-has","Parent-Aware Layouts With :has(): Letting Containers React to Their Contents",{"path":2368,"title":2369},"\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":2371,"title":2372},"\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":2374,"title":2375},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fcontainer-query-data-tables","Container Query Data Tables: Reflowing Tables to Cards",{"path":2377,"title":2378},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fcontainer-query-sidebar-layouts","Container Query Sidebar Layouts That Travel Between Contexts",{"path":2380,"title":2381},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns","Responsive Component Patterns: Architecture & Implementation",{"path":2383,"title":2384},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-forms-with-container-queries","Responsive Forms with Container Queries: Reflow Without Losing the Wiring",{"path":2386,"title":2387},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-hero-sections-with-container-queries","Responsive Hero Sections With Container Queries",{"path":2389,"title":2390},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-navigation-without-media-queries","Responsive Navigation Without Media Queries Using Container Queries",{"path":2392,"title":2393},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-pricing-tables","Responsive Pricing Tables: Aligned Features, a Clear Recommendation, Any Width",{"path":2395,"title":2396},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Ftabs-that-become-accordions","Tabs That Become an Accordion: One Component, Two Layouts",{"path":1884,"title":5},{"path":2399,"title":2400},"\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":2402,"title":2403},"\u002Fmastering-container-queries-responsive-layouts\u002Fscroll-snap-and-overflow-layouts","Scroll Snap & Overflow Layouts: Designing Components That Scroll on Purpose",{"path":2405,"title":2406},"\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":2408,"title":2409},"\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":2411,"title":2412},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fcombining-size-and-style-queries","Combining Size and Style Container Queries",{"path":2414,"title":2415},"\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":2417,"title":2418},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state","Style Queries and Container State: Token-Driven Component Variants",{"path":2420,"title":2421},"\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":2423,"title":2424},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state\u002Fstyle-query-component-variants","Component Variants With Style Queries: One Token, Many Looks",{"path":2426,"title":2427},"\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":2429,"title":2430},"\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":2432,"title":2433},"\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":2435,"title":2436},"\u002Fmastering-container-queries-responsive-layouts\u002Fviewport-units-and-mobile-layout","Viewport Units & Mobile Layout: Designing for the Screen You Actually Get",{"path":2438,"title":2439},"\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":2441,"title":2442},"\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":2444,"title":2445},"\u002Fmastering-container-queries-responsive-layouts\u002Fviewport-units-and-mobile-layout\u002Fvirtual-keyboard-and-interactive-widget","Layouts That Survive the Virtual Keyboard",{"title":2447,"caption":2448,"height":2449,"html":2450,"css":2451},"Scroll-snap carousel with jump links","Swipe, use the trackpad, or focus the row and press the arrow keys: each gesture comes to rest on a slide, and the next slide always peeks in.",300,"\n\u003Csection aria-labelledby=\"c-title\">\n  \u003Ch2 id=\"c-title\">Featured trails\u003C\u002Fh2>\n  \u003Cdiv class=\"carousel\" tabindex=\"0\" role=\"group\" aria-label=\"Featured trails, scroll horizontally\">\n    \u003Carticle class=\"slide\" id=\"s1\">\u003Ch3>Ridge Loop\u003C\u002Fh3>\u003Cp>12 km, moderate.\u003C\u002Fp>\u003C\u002Farticle>\n    \u003Carticle class=\"slide\" id=\"s2\">\u003Ch3>Lake Path\u003C\u002Fh3>\u003Cp>6 km, easy.\u003C\u002Fp>\u003C\u002Farticle>\n    \u003Carticle class=\"slide\" id=\"s3\">\u003Ch3>Summit Trail\u003C\u002Fh3>\u003Cp>18 km, hard.\u003C\u002Fp>\u003C\u002Farticle>\n    \u003Carticle class=\"slide\" id=\"s4\">\u003Ch3>Forest Walk\u003C\u002Fh3>\u003Cp>4 km, easy.\u003C\u002Fp>\u003C\u002Farticle>\n  \u003C\u002Fdiv>\n\u003C\u002Fsection>","\nbody { display: block; }\nh2 { font-size: 1.1rem; margin: 0 0 0.5rem; }\n.carousel {\n  display: grid;\n  grid-auto-flow: column;\n  grid-auto-columns: 80%;\n  gap: 1rem;\n  overflow-x: auto;\n  overscroll-behavior-x: contain;\n  scroll-snap-type: x mandatory;\n  scroll-padding-inline: 1rem;\n  padding: 0.5rem 1rem 1rem;\n}\n.carousel:focus-visible { outline: 2px solid var(--demo-accent); outline-offset: 2px; }\n.slide {\n  scroll-snap-align: start;\n  scroll-snap-stop: always;\n  min-height: 10rem;\n  padding: 1rem;\n  border-radius: 12px;\n  background: linear-gradient(135deg, #dbeafe, #c7d2fe);\n  color: #1e1b4b;\n}\n.slide h3 { margin: 0 0 0.25rem; }",1789717746446]