[{"data":1,"prerenderedAt":1752},["ShallowReactive",2],{"page-\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Ftarget-size-and-pointer-accessibility":3,"content-all-pages":1490},{"id":4,"title":5,"body":6,"description":1472,"extension":1473,"meta":1474,"navigation":495,"path":1486,"seo":1487,"stem":1488,"__hash__":1489},"content\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Ftarget-size-and-pointer-accessibility\u002Findex.md","Target Size and Pointer Accessibility: Meeting 2.5.8 Without Redesigning",{"type":7,"value":8,"toc":1461},"minimark",[9,13,28,34,55,60,70,79,95,99,102,105,223,226,230,234,237,307,322,329,332,336,339,584,1191,1194,1197,1201,1218,1229,1233,1241,1367,1370,1374,1394,1398,1404,1410,1416,1422,1426,1457],[10,11,5],"h1",{"id":12},"target-size-and-pointer-accessibility-meeting-258-without-redesigning",[14,15,16,17,22,23,27],"p",{},"A design system ships 16-pixel icon buttons in a dense toolbar, an audit flags every one of them against WCAG 2.5.8, and the proposed fix — make all the icons bigger — would break the visual density the toolbar was designed for. The fix is unnecessary. The criterion does not measure how big something looks; it measures how big the region that accepts a pointer action is, and CSS lets those two numbers diverge. This page covers the two target-size criteria, the exceptions that legitimately let a control stay small, and the two implementation techniques for growing a hit area. It sits under ",[18,19,21],"a",{"href":20},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002F","Accessibility in CSS Animations"," alongside the motion rules in ",[18,24,26],{"href":25},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fwcag-motion-success-criteria\u002F","WCAG Motion Success Criteria","; this one is about the pointer rather than the animation.",[14,29,30],{},[31,32,33],"strong",{},"What this page settles:",[35,36,37,41,44,52],"ul",{},[38,39,40],"li",{},"The exact wording and level of 2.5.8 and 2.5.5",[38,42,43],{},"Why a visually small control can still pass",[38,45,46,47,51],{},"Padding versus a ",[48,49,50],"code",{},"::after"," overlay, and when each is right",[38,53,54],{},"How the spacing exception is measured",[56,57,59],"h2",{"id":58},"two-criteria-two-levels","Two criteria, two levels",[14,61,62,65,66,69],{},[31,63,64],{},"2.5.8 Target Size (Minimum)"," is ",[31,67,68],{},"Level AA",", introduced in WCAG 2.2. It requires that the size of the target for pointer inputs is at least 24 by 24 CSS pixels, except where one of five exceptions applies.",[14,71,72,65,75,78],{},[31,73,74],{},"2.5.5 Target Size (Enhanced)",[31,76,77],{},"Level AAA",". It requires at least 44 by 44 CSS pixels, and it carries a shorter exception list. Before WCAG 2.2 this criterion was simply called \"Target Size\"; the rename to \"Enhanced\" happened when the AA minimum was added, which is why older audit reports sometimes cite 2.5.5 at 44 pixels as though it were the binding rule. For an AA target it is not.",[14,80,81,82,85,86,89,90,94],{},"The unit matters. A CSS pixel is not a device pixel and is not affected by the user's browser zoom in the way people often assume — the criterion is evaluated in the CSS coordinate space, so a ",[48,83,84],{},"width: 24px"," box satisfies the measurement regardless of the display's pixel density. It is also not affected by ",[48,87,88],{},"transform: scale()"," in the way a naive reading suggests, because a scaled element's ",[91,92,93],"em",{},"rendered"," target does change; if you shrink a control with a transform, you have shrunk its target too.",[56,96,98],{"id":97},"what-target-means","What \"target\" means",[14,100,101],{},"The target is the region of the display that will accept a pointer action for that control. For a normal element that is its border box — content plus padding plus border — and anything else that is hit-testable on top of it, such as an absolutely positioned pseudo-element child. Margin is not part of the target; margin is empty space that belongs to no one, which is exactly why it is useless for this purpose and padding is not.",[14,103,104],{},"That single definition is what makes dense interfaces salvageable. The icon glyph, the SVG artwork, the visible background — none of those are what gets measured. The diagram below shows the three situations that matter: a control whose border box is the glyph and therefore fails, the same glyph inside a padded box that passes, and two undersized targets that pass on spacing alone.",[106,107,113,114,113,118,113,122,113,129,113,141,113,147,113,152,113,160,113,164,113,167,113,170,113,173,113,182,113,185,113,188,113,191,113,195,113,198,113,205,113,209,113,212,113,215,113,218],"svg",{"viewBox":108,"role":109,"ariaLabel":110,"xmlns":111,"style":112},"0 0 720 340","img","Three target size cases: undersized, padded to 24 pixels, and separated by spacing","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;height:auto;max-width:720px;margin:2rem 0","\n  ",[115,116,117],"title",{},"Three ways a small control relates to 2.5.8",[119,120,121],"desc",{},"A 16 pixel target fails, the same glyph padded to a 24 pixel border box passes, and two undersized targets pass because their 24 pixel circles do not intersect.",[123,124,128],"text",{"x":125,"y":126,"style":127},"360","26","text-anchor:middle;fill:currentColor;font:700 17px sans-serif","The glyph is not the target",[130,131],"rect",{"x":132,"y":133,"width":134,"height":135,"rx":136,"fill":137,"stroke":138,"strokeWidth":139,"opacity":140},"20","48","210","250","10","none","currentColor","1.5","0.5",[123,142,146],{"x":143,"y":144,"style":145},"125","76","text-anchor:middle;fill:currentColor;font:600 14px sans-serif","Fails 2.5.8",[123,148,151],{"x":143,"y":149,"style":150},"98","text-anchor:middle;fill:currentColor;font:12px ui-monospace,monospace;opacity:0.8","padding: 0",[130,153],{"x":154,"y":155,"width":156,"height":156,"rx":157,"fill":158,"opacity":159},"103","130","44","4","#7aa2ff","0.32",[123,161,163],{"x":143,"y":135,"style":162},"text-anchor:middle;fill:currentColor;font:12px sans-serif;opacity:0.85","target = 16 CSS px",[130,165],{"x":166,"y":133,"width":134,"height":135,"rx":136,"fill":137,"stroke":138,"strokeWidth":139,"opacity":140},"255",[123,168,169],{"x":125,"y":144,"style":145},"Passes: padding",[123,171,172],{"x":125,"y":149,"style":150},"padding: 4px",[130,174],{"x":175,"y":176,"width":177,"height":177,"rx":178,"fill":137,"stroke":158,"strokeWidth":179,"strokeDashArray":180},"327","119","66","6","2",[181,157],"5",[130,183],{"x":184,"y":155,"width":156,"height":156,"rx":157,"fill":158,"opacity":159},"338",[123,186,187],{"x":125,"y":135,"style":162},"border box = 24 CSS px",[130,189],{"x":190,"y":133,"width":134,"height":135,"rx":136,"fill":137,"stroke":138,"strokeWidth":139,"opacity":140},"490",[123,192,194],{"x":193,"y":144,"style":145},"595","Passes: spacing",[123,196,197],{"x":193,"y":149,"style":150},"circles clear",[199,200],"circle",{"cx":201,"cy":202,"r":203,"fill":137,"stroke":158,"strokeWidth":179,"strokeDashArray":204},"537","152","33",[181,157],[199,206],{"cx":207,"cy":202,"r":203,"fill":137,"stroke":158,"strokeWidth":179,"strokeDashArray":208},"627",[181,157],[130,210],{"x":211,"y":155,"width":156,"height":156,"rx":157,"fill":158,"opacity":159},"515",[130,213],{"x":214,"y":155,"width":156,"height":156,"rx":157,"fill":158,"opacity":159},"605",[123,216,217],{"x":193,"y":135,"style":162},"no overlap, so allowed",[123,219,222],{"x":125,"y":220,"style":221},"326","text-anchor:middle;fill:currentColor;font:12px sans-serif;opacity:0.7","Not to scale. 2.5.8 measures the region that accepts the pointer action.",[14,224,225],{},"The demo makes the same point interactively. Both close buttons draw a 16-pixel glyph; hover each row and the tinted area shows how much of the screen actually responds.",[227,228],"live-demo",{"name":229},"a11ym-target-size-padding",[56,231,233],{"id":232},"the-five-exceptions-to-258","The five exceptions to 2.5.8",[14,235,236],{},"A control smaller than 24 by 24 CSS pixels still conforms if any one of these holds:",[238,239,240,253],"table",{},[241,242,243],"thead",{},[244,245,246,250],"tr",{},[247,248,249],"th",{},"Exception",[247,251,252],{},"What it covers",[254,255,256,267,277,287,297],"tbody",{},[244,257,258,264],{},[259,260,261],"td",{},[31,262,263],{},"Spacing",[259,265,266],{},"Undersized targets positioned so that a 24-pixel-diameter circle centred on each one does not intersect another target, or the circle of another undersized target.",[244,268,269,274],{},[259,270,271],{},[31,272,273],{},"Equivalent",[259,275,276],{},"Another control on the same page performs the same function and does meet the size requirement.",[244,278,279,284],{},[259,280,281],{},[31,282,283],{},"Inline",[259,285,286],{},"The target is in a sentence, or its size is otherwise constrained by the line-height of non-target text.",[244,288,289,294],{},[259,290,291],{},[31,292,293],{},"User agent control",[259,295,296],{},"The size is determined by the user agent and has not been modified by the author.",[244,298,299,304],{},[259,300,301],{},[31,302,303],{},"Essential",[259,305,306],{},"A particular presentation of the target is legally required or essential to the information being conveyed.",[14,308,309,310,313,314,317,318,321],{},"The Spacing exception is the one that rescues dense toolbars, and it is worth stating its geometry carefully: the test is on 24-pixel ",[91,311,312],{},"diameter"," circles — radius 12 — centred on the bounding box of each undersized target. If those circles stay clear of each other, and clear of any other target, the targets pass. In practice this means roughly 24 pixels of centre-to-centre separation, which you buy with ",[48,315,316],{},"gap"," or ",[48,319,320],{},"margin"," rather than by growing anything.",[14,323,324,325,328],{},"The Inline exception is why body-copy links do not need 24-pixel-tall hit areas. A link in the middle of a paragraph is constrained by the surrounding text's line box, and forcing it taller would break the paragraph. Note this covers links ",[91,326,327],{},"in"," text — it does not cover a row of small standalone links styled to look like a nav, which is a common misreading.",[14,330,331],{},"The Equivalent exception is genuinely useful for icon-only shortcuts: a tiny \"duplicate\" icon in a table row is fine if a full-size \"Duplicate\" item also exists in that row's menu.",[56,333,335],{"id":334},"complete-working-implementation","Complete working implementation",[14,337,338],{},"Two techniques, in one file. The first grows the border box; the second leaves the box alone and overlays a larger hit region.",[340,341,346],"pre",{"className":342,"code":343,"language":344,"meta":345,"style":345},"language-html shiki shiki-themes github-light-high-contrast github-dark-high-contrast","\u003Cdiv class=\"toolbar\">\n  \u003Cbutton class=\"tool\" type=\"button\" aria-label=\"Bold\">B\u003C\u002Fbutton>\n  \u003Cbutton class=\"tool\" type=\"button\" aria-label=\"Italic\">I\u003C\u002Fbutton>\n  \u003Cbutton class=\"tool\" type=\"button\" aria-label=\"Underline\">U\u003C\u002Fbutton>\n\u003C\u002Fdiv>\n\n\u003Cp class=\"meta\">\n  Updated 5 minutes ago —\n  \u003Ca class=\"chip\" href=\"#history\">history\u003C\u002Fa>\n  \u003Ca class=\"chip\" href=\"#revert\">revert\u003C\u002Fa>\n\u003C\u002Fp>\n","html","",[48,347,348,375,414,447,480,490,497,513,519,548,575],{"__ignoreMap":345},[349,350,353,357,361,365,368,372],"span",{"class":351,"line":352},"line",1,[349,354,356],{"class":355},"suds8","\u003C",[349,358,360],{"class":359},"sne4z","div",[349,362,364],{"class":363},"s-5SL"," class",[349,366,367],{"class":355},"=",[349,369,371],{"class":370},"sT6z2","\"toolbar\"",[349,373,374],{"class":355},">\n",[349,376,378,381,384,386,388,391,394,396,399,402,404,407,410,412],{"class":351,"line":377},2,[349,379,380],{"class":355},"  \u003C",[349,382,383],{"class":359},"button",[349,385,364],{"class":363},[349,387,367],{"class":355},[349,389,390],{"class":370},"\"tool\"",[349,392,393],{"class":363}," type",[349,395,367],{"class":355},[349,397,398],{"class":370},"\"button\"",[349,400,401],{"class":363}," aria-label",[349,403,367],{"class":355},[349,405,406],{"class":370},"\"Bold\"",[349,408,409],{"class":355},">B\u003C\u002F",[349,411,383],{"class":359},[349,413,374],{"class":355},[349,415,417,419,421,423,425,427,429,431,433,435,437,440,443,445],{"class":351,"line":416},3,[349,418,380],{"class":355},[349,420,383],{"class":359},[349,422,364],{"class":363},[349,424,367],{"class":355},[349,426,390],{"class":370},[349,428,393],{"class":363},[349,430,367],{"class":355},[349,432,398],{"class":370},[349,434,401],{"class":363},[349,436,367],{"class":355},[349,438,439],{"class":370},"\"Italic\"",[349,441,442],{"class":355},">I\u003C\u002F",[349,444,383],{"class":359},[349,446,374],{"class":355},[349,448,450,452,454,456,458,460,462,464,466,468,470,473,476,478],{"class":351,"line":449},4,[349,451,380],{"class":355},[349,453,383],{"class":359},[349,455,364],{"class":363},[349,457,367],{"class":355},[349,459,390],{"class":370},[349,461,393],{"class":363},[349,463,367],{"class":355},[349,465,398],{"class":370},[349,467,401],{"class":363},[349,469,367],{"class":355},[349,471,472],{"class":370},"\"Underline\"",[349,474,475],{"class":355},">U\u003C\u002F",[349,477,383],{"class":359},[349,479,374],{"class":355},[349,481,483,486,488],{"class":351,"line":482},5,[349,484,485],{"class":355},"\u003C\u002F",[349,487,360],{"class":359},[349,489,374],{"class":355},[349,491,493],{"class":351,"line":492},6,[349,494,496],{"emptyLinePlaceholder":495},true,"\n",[349,498,500,502,504,506,508,511],{"class":351,"line":499},7,[349,501,356],{"class":355},[349,503,14],{"class":359},[349,505,364],{"class":363},[349,507,367],{"class":355},[349,509,510],{"class":370},"\"meta\"",[349,512,374],{"class":355},[349,514,516],{"class":351,"line":515},8,[349,517,518],{"class":355},"  Updated 5 minutes ago —\n",[349,520,522,524,526,528,530,533,536,538,541,544,546],{"class":351,"line":521},9,[349,523,380],{"class":355},[349,525,18],{"class":359},[349,527,364],{"class":363},[349,529,367],{"class":355},[349,531,532],{"class":370},"\"chip\"",[349,534,535],{"class":363}," href",[349,537,367],{"class":355},[349,539,540],{"class":370},"\"#history\"",[349,542,543],{"class":355},">history\u003C\u002F",[349,545,18],{"class":359},[349,547,374],{"class":355},[349,549,551,553,555,557,559,561,563,565,568,571,573],{"class":351,"line":550},10,[349,552,380],{"class":355},[349,554,18],{"class":359},[349,556,364],{"class":363},[349,558,367],{"class":355},[349,560,532],{"class":370},[349,562,535],{"class":363},[349,564,367],{"class":355},[349,566,567],{"class":370},"\"#revert\"",[349,569,570],{"class":355},">revert\u003C\u002F",[349,572,18],{"class":359},[349,574,374],{"class":355},[349,576,578,580,582],{"class":351,"line":577},11,[349,579,485],{"class":355},[349,581,14],{"class":359},[349,583,374],{"class":355},[340,585,589],{"className":586,"code":587,"language":588,"meta":345,"style":345},"language-css shiki shiki-themes github-light-high-contrast github-dark-high-contrast","\u002F* --- Technique 1: padding grows the border box -----------------------\n   The glyph still renders at 16px. Four pixels of padding on every side\n   makes the border box 24 x 24, and the border box IS the target.\n   min-width\u002Fmin-height guard against a narrow glyph (like \"I\") shrinking\n   the box below the minimum. *\u002F\n.tool {\n  font: 600 16px\u002F1 system-ui, sans-serif;\n  padding: 4px;\n  min-width: 24px;\n  min-height: 24px;\n  border: 0;\n  background: transparent;\n  color: inherit;\n  cursor: pointer;\n}\n\n\u002F* Spacing is independent of size: this gap also keeps the Spacing\n   exception available if a control ever drops below 24px. *\u002F\n.toolbar {\n  display: flex;\n  gap: 8px;\n  align-items: center;\n}\n\n\u002F* --- Technique 2: a pseudo-element overlay ---------------------------\n   Use when the visible box must not grow — here the chips sit on a tight\n   line and padding would push the line-height around. The ::after is a\n   hit-testable child, so it extends the target without changing layout. *\u002F\n.chip {\n  position: relative;          \u002F* containing block for the overlay *\u002F\n  font-size: 0.8rem;\n}\n\n.chip::after {\n  content: \"\";\n  position: absolute;\n  left: 50%;\n  top: 50%;\n  translate: -50% -50%;\n  \u002F* Never shrink below the element itself: max() keeps wide chips fully\n     clickable while lifting narrow ones up to 24px. *\u002F\n  width: max(100%, 24px);\n  height: 24px;\n  \u002F* Transparent, but still receives pointer events. *\u002F\n  background: transparent;\n}\n\n\u002F* Overlays on neighbours must not overlap, or the later one in the\n   painting order silently steals clicks from the earlier one. *\u002F\n.chip + .chip {\n  margin-inline-start: 12px;\n}\n\n\u002F* The indicator must follow the visible box, not the enlarged target,\n   or the ring will look detached from the control. *\u002F\n.tool:focus-visible,\n.chip:focus-visible {\n  outline: 2px solid currentColor;\n  outline-offset: 2px;\n}\n","css",[48,590,591,597,602,607,612,617,625,661,674,688,701,713,726,739,752,758,763,769,775,783,796,811,824,829,834,840,846,852,858,866,883,899,904,909,917,930,942,958,972,992,998,1004,1032,1046,1052,1063,1068,1073,1079,1085,1098,1113,1118,1123,1129,1135,1144,1152,1172,1186],{"__ignoreMap":345},[349,592,593],{"class":351,"line":352},[349,594,596],{"class":595},"sLBg1","\u002F* --- Technique 1: padding grows the border box -----------------------\n",[349,598,599],{"class":351,"line":377},[349,600,601],{"class":595},"   The glyph still renders at 16px. Four pixels of padding on every side\n",[349,603,604],{"class":351,"line":416},[349,605,606],{"class":595},"   makes the border box 24 x 24, and the border box IS the target.\n",[349,608,609],{"class":351,"line":449},[349,610,611],{"class":595},"   min-width\u002Fmin-height guard against a narrow glyph (like \"I\") shrinking\n",[349,613,614],{"class":351,"line":482},[349,615,616],{"class":595},"   the box below the minimum. *\u002F\n",[349,618,619,622],{"class":351,"line":492},[349,620,621],{"class":363},".tool",[349,623,624],{"class":355}," {\n",[349,626,627,630,633,636,639,643,646,649,652,655,658],{"class":351,"line":499},[349,628,629],{"class":363},"  font",[349,631,632],{"class":355},": ",[349,634,635],{"class":363},"600",[349,637,638],{"class":363}," 16",[349,640,642],{"class":641},"sHUrx","px",[349,644,645],{"class":355},"\u002F",[349,647,648],{"class":363},"1",[349,650,651],{"class":363}," system-ui",[349,653,654],{"class":355},", ",[349,656,657],{"class":363},"sans-serif",[349,659,660],{"class":355},";\n",[349,662,663,666,668,670,672],{"class":351,"line":515},[349,664,665],{"class":363},"  padding",[349,667,632],{"class":355},[349,669,157],{"class":363},[349,671,642],{"class":641},[349,673,660],{"class":355},[349,675,676,679,681,684,686],{"class":351,"line":521},[349,677,678],{"class":363},"  min-width",[349,680,632],{"class":355},[349,682,683],{"class":363},"24",[349,685,642],{"class":641},[349,687,660],{"class":355},[349,689,690,693,695,697,699],{"class":351,"line":550},[349,691,692],{"class":363},"  min-height",[349,694,632],{"class":355},[349,696,683],{"class":363},[349,698,642],{"class":641},[349,700,660],{"class":355},[349,702,703,706,708,711],{"class":351,"line":577},[349,704,705],{"class":363},"  border",[349,707,632],{"class":355},[349,709,710],{"class":363},"0",[349,712,660],{"class":355},[349,714,716,719,721,724],{"class":351,"line":715},12,[349,717,718],{"class":363},"  background",[349,720,632],{"class":355},[349,722,723],{"class":363},"transparent",[349,725,660],{"class":355},[349,727,729,732,734,737],{"class":351,"line":728},13,[349,730,731],{"class":363},"  color",[349,733,632],{"class":355},[349,735,736],{"class":363},"inherit",[349,738,660],{"class":355},[349,740,742,745,747,750],{"class":351,"line":741},14,[349,743,744],{"class":363},"  cursor",[349,746,632],{"class":355},[349,748,749],{"class":363},"pointer",[349,751,660],{"class":355},[349,753,755],{"class":351,"line":754},15,[349,756,757],{"class":355},"}\n",[349,759,761],{"class":351,"line":760},16,[349,762,496],{"emptyLinePlaceholder":495},[349,764,766],{"class":351,"line":765},17,[349,767,768],{"class":595},"\u002F* Spacing is independent of size: this gap also keeps the Spacing\n",[349,770,772],{"class":351,"line":771},18,[349,773,774],{"class":595},"   exception available if a control ever drops below 24px. *\u002F\n",[349,776,778,781],{"class":351,"line":777},19,[349,779,780],{"class":363},".toolbar",[349,782,624],{"class":355},[349,784,786,789,791,794],{"class":351,"line":785},20,[349,787,788],{"class":363},"  display",[349,790,632],{"class":355},[349,792,793],{"class":363},"flex",[349,795,660],{"class":355},[349,797,799,802,804,807,809],{"class":351,"line":798},21,[349,800,801],{"class":363},"  gap",[349,803,632],{"class":355},[349,805,806],{"class":363},"8",[349,808,642],{"class":641},[349,810,660],{"class":355},[349,812,814,817,819,822],{"class":351,"line":813},22,[349,815,816],{"class":363},"  align-items",[349,818,632],{"class":355},[349,820,821],{"class":363},"center",[349,823,660],{"class":355},[349,825,827],{"class":351,"line":826},23,[349,828,757],{"class":355},[349,830,832],{"class":351,"line":831},24,[349,833,496],{"emptyLinePlaceholder":495},[349,835,837],{"class":351,"line":836},25,[349,838,839],{"class":595},"\u002F* --- Technique 2: a pseudo-element overlay ---------------------------\n",[349,841,843],{"class":351,"line":842},26,[349,844,845],{"class":595},"   Use when the visible box must not grow — here the chips sit on a tight\n",[349,847,849],{"class":351,"line":848},27,[349,850,851],{"class":595},"   line and padding would push the line-height around. The ::after is a\n",[349,853,855],{"class":351,"line":854},28,[349,856,857],{"class":595},"   hit-testable child, so it extends the target without changing layout. *\u002F\n",[349,859,861,864],{"class":351,"line":860},29,[349,862,863],{"class":363},".chip",[349,865,624],{"class":355},[349,867,869,872,874,877,880],{"class":351,"line":868},30,[349,870,871],{"class":363},"  position",[349,873,632],{"class":355},[349,875,876],{"class":363},"relative",[349,878,879],{"class":355},";          ",[349,881,882],{"class":595},"\u002F* containing block for the overlay *\u002F\n",[349,884,886,889,891,894,897],{"class":351,"line":885},31,[349,887,888],{"class":363},"  font-size",[349,890,632],{"class":355},[349,892,893],{"class":363},"0.8",[349,895,896],{"class":641},"rem",[349,898,660],{"class":355},[349,900,902],{"class":351,"line":901},32,[349,903,757],{"class":355},[349,905,907],{"class":351,"line":906},33,[349,908,496],{"emptyLinePlaceholder":495},[349,910,912,915],{"class":351,"line":911},34,[349,913,914],{"class":363},".chip::after",[349,916,624],{"class":355},[349,918,920,923,925,928],{"class":351,"line":919},35,[349,921,922],{"class":363},"  content",[349,924,632],{"class":355},[349,926,927],{"class":370},"\"\"",[349,929,660],{"class":355},[349,931,933,935,937,940],{"class":351,"line":932},36,[349,934,871],{"class":363},[349,936,632],{"class":355},[349,938,939],{"class":363},"absolute",[349,941,660],{"class":355},[349,943,945,948,950,953,956],{"class":351,"line":944},37,[349,946,947],{"class":363},"  left",[349,949,632],{"class":355},[349,951,952],{"class":363},"50",[349,954,955],{"class":641},"%",[349,957,660],{"class":355},[349,959,961,964,966,968,970],{"class":351,"line":960},38,[349,962,963],{"class":363},"  top",[349,965,632],{"class":355},[349,967,952],{"class":363},[349,969,955],{"class":641},[349,971,660],{"class":355},[349,973,975,978,980,983,985,988,990],{"class":351,"line":974},39,[349,976,977],{"class":363},"  translate",[349,979,632],{"class":355},[349,981,982],{"class":363},"-50",[349,984,955],{"class":641},[349,986,987],{"class":363}," -50",[349,989,955],{"class":641},[349,991,660],{"class":355},[349,993,995],{"class":351,"line":994},40,[349,996,997],{"class":595},"  \u002F* Never shrink below the element itself: max() keeps wide chips fully\n",[349,999,1001],{"class":351,"line":1000},41,[349,1002,1003],{"class":595},"     clickable while lifting narrow ones up to 24px. *\u002F\n",[349,1005,1007,1010,1012,1015,1018,1021,1023,1025,1027,1029],{"class":351,"line":1006},42,[349,1008,1009],{"class":363},"  width",[349,1011,632],{"class":355},[349,1013,1014],{"class":363},"max",[349,1016,1017],{"class":355},"(",[349,1019,1020],{"class":363},"100",[349,1022,955],{"class":641},[349,1024,654],{"class":355},[349,1026,683],{"class":363},[349,1028,642],{"class":641},[349,1030,1031],{"class":355},");\n",[349,1033,1035,1038,1040,1042,1044],{"class":351,"line":1034},43,[349,1036,1037],{"class":363},"  height",[349,1039,632],{"class":355},[349,1041,683],{"class":363},[349,1043,642],{"class":641},[349,1045,660],{"class":355},[349,1047,1049],{"class":351,"line":1048},44,[349,1050,1051],{"class":595},"  \u002F* Transparent, but still receives pointer events. *\u002F\n",[349,1053,1055,1057,1059,1061],{"class":351,"line":1054},45,[349,1056,718],{"class":363},[349,1058,632],{"class":355},[349,1060,723],{"class":363},[349,1062,660],{"class":355},[349,1064,1066],{"class":351,"line":1065},46,[349,1067,757],{"class":355},[349,1069,1071],{"class":351,"line":1070},47,[349,1072,496],{"emptyLinePlaceholder":495},[349,1074,1076],{"class":351,"line":1075},48,[349,1077,1078],{"class":595},"\u002F* Overlays on neighbours must not overlap, or the later one in the\n",[349,1080,1082],{"class":351,"line":1081},49,[349,1083,1084],{"class":595},"   painting order silently steals clicks from the earlier one. *\u002F\n",[349,1086,1088,1090,1093,1096],{"class":351,"line":1087},50,[349,1089,863],{"class":363},[349,1091,1092],{"class":641}," +",[349,1094,1095],{"class":363}," .chip",[349,1097,624],{"class":355},[349,1099,1101,1104,1106,1109,1111],{"class":351,"line":1100},51,[349,1102,1103],{"class":363},"  margin-inline-start",[349,1105,632],{"class":355},[349,1107,1108],{"class":363},"12",[349,1110,642],{"class":641},[349,1112,660],{"class":355},[349,1114,1116],{"class":351,"line":1115},52,[349,1117,757],{"class":355},[349,1119,1121],{"class":351,"line":1120},53,[349,1122,496],{"emptyLinePlaceholder":495},[349,1124,1126],{"class":351,"line":1125},54,[349,1127,1128],{"class":595},"\u002F* The indicator must follow the visible box, not the enlarged target,\n",[349,1130,1132],{"class":351,"line":1131},55,[349,1133,1134],{"class":595},"   or the ring will look detached from the control. *\u002F\n",[349,1136,1138,1141],{"class":351,"line":1137},56,[349,1139,1140],{"class":363},".tool:focus-visible",[349,1142,1143],{"class":355},",\n",[349,1145,1147,1150],{"class":351,"line":1146},57,[349,1148,1149],{"class":363},".chip:focus-visible",[349,1151,624],{"class":355},[349,1153,1155,1158,1160,1162,1164,1167,1170],{"class":351,"line":1154},58,[349,1156,1157],{"class":363},"  outline",[349,1159,632],{"class":355},[349,1161,179],{"class":363},[349,1163,642],{"class":641},[349,1165,1166],{"class":363}," solid",[349,1168,1169],{"class":363}," currentColor",[349,1171,660],{"class":355},[349,1173,1175,1178,1180,1182,1184],{"class":351,"line":1174},59,[349,1176,1177],{"class":363},"  outline-offset",[349,1179,632],{"class":355},[349,1181,179],{"class":363},[349,1183,642],{"class":641},[349,1185,660],{"class":355},[349,1187,1189],{"class":351,"line":1188},60,[349,1190,757],{"class":355},[14,1192,1193],{},"The second technique is easier to see than to read. Both rows below are the same markup; only the second one carries the overlay.",[227,1195],{"name":1196},"a11ym-target-size-overlay",[56,1198,1200],{"id":1199},"the-technique-that-makes-it-work","The technique that makes it work",[14,1202,1203,1206,1207,1209,1210,1213,1214,1217],{},[48,1204,1205],{},"width: max(100%, 24px)"," on the overlay is the detail that makes the pseudo-element approach safe to apply globally. A fixed ",[48,1208,84],{}," overlay on a chip whose text is 80 pixels wide would ",[91,1211,1212],{},"shrink"," the effective target — the overlay paints on top and captures the pointer, so the exposed area becomes the overlay's, not the element's. ",[48,1215,1216],{},"max()"," makes the overlay at least as wide as the element it belongs to and at least 24 pixels, so it can only ever add area. The same reasoning applies to height when your control has a taller line box than the minimum.",[14,1219,1220,1221,1224,1225,1228],{},"The second half of the technique is the containing block. ",[48,1222,1223],{},"position: absolute"," resolves against the nearest positioned ancestor, so without ",[48,1226,1227],{},"position: relative"," on the element itself the overlay would size and place itself against some ancestor far up the tree, producing a giant invisible click-catcher over half the page. That failure is silent — nothing looks wrong — which is why it is worth testing overlays by temporarily giving them a visible background.",[56,1230,1232],{"id":1231},"variation-sizing-up-for-coarse-pointers","Variation: sizing up for coarse pointers",[14,1234,1235,1236,1240],{},"24 pixels is a conformance floor, not a usability target. On touch devices the practical comfortable minimum is closer to 44, and you can raise it selectively rather than everywhere by testing the pointer's precision, a technique covered in ",[18,1237,1239],{"href":1238},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Fpointer-and-hover-media-queries\u002F","Pointer and Hover Media Queries",":",[340,1242,1244],{"className":586,"code":1243,"language":588,"meta":345,"style":345},"\u002F* Coarse pointer = finger or stylus. Lift the same controls to the\n   2.5.5 (AAA) figure without changing the desktop toolbar's density. *\u002F\n@media (pointer: coarse) {\n  .tool {\n    min-width: 44px;\n    min-height: 44px;\n    padding: 14px;\n  }\n  .chip::after {\n    width: max(100%, 44px);\n    height: 44px;\n  }\n}\n",[48,1245,1246,1251,1256,1264,1271,1284,1297,1311,1316,1323,1346,1359,1363],{"__ignoreMap":345},[349,1247,1248],{"class":351,"line":352},[349,1249,1250],{"class":595},"\u002F* Coarse pointer = finger or stylus. Lift the same controls to the\n",[349,1252,1253],{"class":351,"line":377},[349,1254,1255],{"class":595},"   2.5.5 (AAA) figure without changing the desktop toolbar's density. *\u002F\n",[349,1257,1258,1261],{"class":351,"line":416},[349,1259,1260],{"class":641},"@media",[349,1262,1263],{"class":355}," (pointer: coarse) {\n",[349,1265,1266,1269],{"class":351,"line":449},[349,1267,1268],{"class":363},"  .tool",[349,1270,624],{"class":355},[349,1272,1273,1276,1278,1280,1282],{"class":351,"line":482},[349,1274,1275],{"class":363},"    min-width",[349,1277,632],{"class":355},[349,1279,156],{"class":363},[349,1281,642],{"class":641},[349,1283,660],{"class":355},[349,1285,1286,1289,1291,1293,1295],{"class":351,"line":492},[349,1287,1288],{"class":363},"    min-height",[349,1290,632],{"class":355},[349,1292,156],{"class":363},[349,1294,642],{"class":641},[349,1296,660],{"class":355},[349,1298,1299,1302,1304,1307,1309],{"class":351,"line":499},[349,1300,1301],{"class":363},"    padding",[349,1303,632],{"class":355},[349,1305,1306],{"class":363},"14",[349,1308,642],{"class":641},[349,1310,660],{"class":355},[349,1312,1313],{"class":351,"line":515},[349,1314,1315],{"class":355},"  }\n",[349,1317,1318,1321],{"class":351,"line":521},[349,1319,1320],{"class":363},"  .chip::after",[349,1322,624],{"class":355},[349,1324,1325,1328,1330,1332,1334,1336,1338,1340,1342,1344],{"class":351,"line":550},[349,1326,1327],{"class":363},"    width",[349,1329,632],{"class":355},[349,1331,1014],{"class":363},[349,1333,1017],{"class":355},[349,1335,1020],{"class":363},[349,1337,955],{"class":641},[349,1339,654],{"class":355},[349,1341,156],{"class":363},[349,1343,642],{"class":641},[349,1345,1031],{"class":355},[349,1347,1348,1351,1353,1355,1357],{"class":351,"line":577},[349,1349,1350],{"class":363},"    height",[349,1352,632],{"class":355},[349,1354,156],{"class":363},[349,1356,642],{"class":641},[349,1358,660],{"class":355},[349,1360,1361],{"class":351,"line":715},[349,1362,1315],{"class":355},[349,1364,1365],{"class":351,"line":728},[349,1366,757],{"class":355},[14,1368,1369],{},"Because the padded technique keeps the glyph at 16 pixels, this scales the target without scaling the artwork — the toolbar looks the same and simply becomes easier to hit.",[56,1371,1373],{"id":1372},"browser-support","Browser support",[14,1375,1376,1377,1379,1380,1383,1384,1386,1387,1390,1391,1393],{},"Everything here is long-established CSS. ",[48,1378,1216],{}," in a length context is supported across all current engines, and the ",[48,1381,1382],{},"translate"," property used for centring the overlay is available in Chrome 104, Edge 104, Firefox 72 and Safari 14.1. If you need to support engines older than the standalone ",[48,1385,1382],{}," property, ",[48,1388,1389],{},"transform: translate(-50%, -50%)"," is an exact substitute with universal support. Media queries for ",[48,1392,749],{}," are likewise supported everywhere in current use.",[56,1395,1397],{"id":1396},"faq","FAQ",[14,1399,1400,1403],{},[31,1401,1402],{},"What is the minimum target size under WCAG 2.2?","\nSuccess Criterion 2.5.8 Target Size (Minimum) is Level AA and requires targets to be at least 24 by 24 CSS pixels, unless one of its five exceptions applies. The enhanced version, 2.5.5 Target Size (Enhanced), is Level AAA and asks for 44 by 44 CSS pixels.",[14,1405,1406,1409],{},[31,1407,1408],{},"Does a 16 pixel icon automatically fail 2.5.8?","\nNo. The criterion measures the target, which is the region that accepts the pointer action, not the painted artwork. A 16 pixel glyph inside a button with 4 pixels of padding on every side has a 24 by 24 target and passes.",[14,1411,1412,1415],{},[31,1413,1414],{},"When can a target be smaller than 24 by 24 pixels?","\nFive exceptions apply: sufficient spacing between undersized targets, an equivalent control of adequate size elsewhere on the page, targets inline in a sentence or block of text, targets whose presentation is determined by the user agent, and cases where the specific size is essential.",[14,1417,1418,1421],{},[31,1419,1420],{},"Should I use padding or a pseudo-element to grow a hit area?","\nPrefer padding when the element can grow without disturbing the layout, because the border box is unambiguously the target. Use an absolutely positioned pseudo-element overlay when the visual size must stay fixed, and check that overlays on adjacent controls do not overlap.",[56,1423,1425],{"id":1424},"related","Related",[35,1427,1428,1433,1438,1443,1450],{},[38,1429,1430,1432],{},[18,1431,21],{"href":20}," — the parent guide for accessibility work on this site.",[38,1434,1435,1437],{},[18,1436,26],{"href":25}," — the motion criteria that sit beside these pointer ones.",[38,1439,1440,1442],{},[18,1441,1239],{"href":1238}," — detecting coarse pointers before you resize anything.",[38,1444,1445,1449],{},[18,1446,1448],{"href":1447},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fcreating-accessible-focus-indicators\u002F","Creating Accessible Focus Indicators"," — keeping the ring attached to the visible box.",[38,1451,1452,1456],{},[18,1453,1455],{"href":1454},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-forms-with-container-queries\u002F","Responsive Forms With Container Queries"," — control sizing that responds to available space rather than viewport.",[1458,1459,1460],"style",{},"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 .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .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}",{"title":345,"searchDepth":377,"depth":377,"links":1462},[1463,1464,1465,1466,1467,1468,1469,1470,1471],{"id":58,"depth":377,"text":59},{"id":97,"depth":377,"text":98},{"id":232,"depth":377,"text":233},{"id":334,"depth":377,"text":335},{"id":1199,"depth":377,"text":1200},{"id":1231,"depth":377,"text":1232},{"id":1372,"depth":377,"text":1373},{"id":1396,"depth":377,"text":1397},{"id":1424,"depth":377,"text":1425},"How to meet WCAG 2.5.8 Target Size Minimum at 24 by 24 CSS pixels with padding or a pseudo-element overlay, plus the spacing exception and the AAA rule.","md",{"pageTitle":1475,"datePublished":1476,"dateModified":1476,"faq":1477},"Target Size: WCAG 2.5.8 and 2.5.5 in CSS","2026-07-20",[1478,1480,1482,1484],{"q":1402,"a":1479},"Success Criterion 2.5.8 Target Size (Minimum) is Level AA and requires targets to be at least 24 by 24 CSS pixels, unless one of its five exceptions applies. The enhanced version, 2.5.5 Target Size (Enhanced), is Level AAA and asks for 44 by 44 CSS pixels.",{"q":1408,"a":1481},"No. The criterion measures the target, which is the region that accepts the pointer action, not the painted artwork. A 16 pixel glyph inside a button with 4 pixels of padding on every side has a 24 by 24 target and passes.",{"q":1414,"a":1483},"Five exceptions apply: sufficient spacing between undersized targets, an equivalent control of adequate size elsewhere on the page, targets inline in a sentence or block of text, targets whose presentation is determined by the user agent, and cases where the specific size is essential.",{"q":1420,"a":1485},"Prefer padding when the element can grow without disturbing the layout, because the border box is unambiguously the target. Use an absolutely positioned pseudo-element overlay when the visual size must stay fixed, and check that overlays on adjacent controls do not overlap.","\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Ftarget-size-and-pointer-accessibility",{"title":5,"description":1472},"css-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Ftarget-size-and-pointer-accessibility\u002Findex","b_9eKeOsk-ZHgYn4LPhvIw5PGTsZmDZohYIzmOeMnZc",[1491,1494,1497,1500,1503,1504,1507,1510,1513,1516,1519,1522,1525,1528,1531,1534,1537,1540,1543,1546,1549,1552,1555,1558,1561,1564,1567,1570,1573,1576,1579,1582,1585,1588,1591,1594,1597,1600,1603,1606,1609,1612,1615,1618,1621,1624,1627,1629,1632,1635,1638,1641,1644,1647,1650,1653,1656,1659,1662,1665,1668,1671,1674,1677,1680,1683,1686,1689,1692,1695,1698,1701,1704,1707,1710,1713,1716,1719,1722,1725,1728,1731,1734,1737,1740,1743,1746,1749],{"path":1492,"title":1493},"\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":1495,"title":1496},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations","Accessibility in CSS Animations: Patterns, Specs & Best Practices",{"path":1498,"title":1499},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fprefers-reduced-motion-recipes","prefers-reduced-motion Recipes: A Reduction for Every Common Effect",{"path":1501,"title":1502},"\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":1486,"title":5},{"path":1505,"title":1506},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fvestibular-safe-animation-patterns","Vestibular-Safe Animation Patterns: Why Some Motion Makes People Sick",{"path":1508,"title":1509},"\u002Fcss-only-micro-interactions-animations\u002Faccessibility-in-css-animations\u002Fwcag-motion-success-criteria","WCAG Motion Success Criteria: What Each One Actually Requires",{"path":1511,"title":1512},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fcontainer-query-hover-affordances","Container Query Hover Affordances: When Narrow Means Persistent, Not Hidden",{"path":1514,"title":1515},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion","Container-Aware Motion: Animation Sized by the Space a Component Actually Has",{"path":1517,"title":1518},"\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":1520,"title":1521},"\u002Fcss-only-micro-interactions-animations\u002Fcontainer-aware-motion\u002Fsuppressing-motion-in-small-containers","Suppressing Motion in Small Containers: Deliberately Animating Nothing",{"path":1523,"title":1524},"\u002Fcss-only-micro-interactions-animations\u002Fcss-animation-vs-web-animations-api","CSS Animation vs the Web Animations API: A Decision Guide",{"path":1526,"title":1527},"\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":1529,"title":1530},"\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":1532,"title":1533},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture\u002Ffluid-spacing-tokens-driving-transition-durations","Fluid Spacing Tokens That Drive Transition Durations",{"path":1535,"title":1536},"\u002Fcss-only-micro-interactions-animations\u002Fcss-custom-properties-architecture","CSS Custom Properties Architecture: Scalable Design Systems & Dynamic UI",{"path":1538,"title":1539},"\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":1541,"title":1542},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fcss-transition-timing-functions","CSS Transition Timing Functions: ease, cubic-bezier(), steps() and linear()",{"path":1544,"title":1545},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals","CSS Transition Fundamentals: Architecture, Performance & Patterns",{"path":1547,"title":1548},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Fstarting-style-entry-animations","@starting-style: Animating an Element's Very First Style Change",{"path":1550,"title":1551},"\u002Fcss-only-micro-interactions-animations\u002Fcss-transition-fundamentals\u002Ftransitioning-display-with-allow-discrete","Transitioning display with transition-behavior: allow-discrete and @starting-style",{"path":1553,"title":1554},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Faccessible-css-only-tooltips","Accessible CSS-Only Tooltips and Hover Cards With  and ",{"path":1556,"title":1557},"\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":1559,"title":1560},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design\u002Ffocus-within-form-patterns"," Form Patterns: Styling a Group From the Field Inside It",{"path":1562,"title":1563},"\u002Fcss-only-micro-interactions-animations\u002Fhover-focus-state-design","Hover & Focus State Design: Spec-Compliant Patterns for Modern UIs",{"path":1565,"title":1566},"\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":1568,"title":1569},"\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":1571,"title":1572},"\u002Fcss-only-micro-interactions-animations","CSS-Only Micro-Interactions & Animations: Architecture, Performance & Implementation",{"path":1574,"title":1575},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcontainer-query-triggered-keyframe-animations","Container-Query-Triggered Keyframe Animations: Animate Differently per Available Space",{"path":1577,"title":1578},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fcss-only-accordions-and-disclosure","CSS-Only Accordions and Disclosure Widgets with details and summary",{"path":1580,"title":1581},"\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":1583,"title":1584},"\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":1586,"title":1587},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns","Keyframe Animation Patterns: Spec-Compliant Architectures for Modern UIs",{"path":1589,"title":1590},"\u002Fcss-only-micro-interactions-animations\u002Fkeyframe-animation-patterns\u002Fstaggered-list-animations-with-custom-properties","Staggered List Animations Using --i Index Custom Properties",{"path":1592,"title":1593},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration","Performance & GPU Acceleration in CSS: A Developer’s Blueprint",{"path":1595,"title":1596},"\u002Fcss-only-micro-interactions-animations\u002Fperformance-gpu-acceleration\u002Foptimizing-css-animations-for-60fps","Optimizing CSS Animations for 60fps: Budgeting the Frame",{"path":1598,"title":1599},"\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":1601,"title":1602},"\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":1604,"title":1605},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations","Scroll-Driven Animations: Binding Motion to Scroll Position in Pure CSS",{"path":1607,"title":1608},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-driven-animation-fallbacks","Shipping Scroll-Driven Animations Without Breaking Anything",{"path":1610,"title":1611},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-progress-bar-without-javascript","A Reading Progress Bar Driven by scroll(root)",{"path":1613,"title":1614},"\u002Fcss-only-micro-interactions-animations\u002Fscroll-driven-animations\u002Fscroll-triggered-reveal-animations","Reveal-on-Scroll with view() and animation-range",{"path":1616,"title":1617},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers","View Transitions for CSS Developers: the Pseudo-Element Tree, Snapshots, and Named Elements",{"path":1619,"title":1620},"\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":1622,"title":1623},"\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":1625,"title":1626},"\u002Fcss-only-micro-interactions-animations\u002Fview-transitions-for-css-developers\u002Fview-transitions-with-reduced-motion","Honouring prefers-reduced-motion in View Transitions",{"path":645,"title":1628},"Modern CSS Layouts & Micro-Interactions",{"path":1630,"title":1631},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-positioned-tooltips","Anchor-Positioned Tooltips: Tethering, Flipping, and Getting the Semantics Right",{"path":1633,"title":1634},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fanchor-positioning-fallbacks","Anchor Positioning Fallbacks: A Graceful Floor for Older Browser Versions",{"path":1636,"title":1637},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays","CSS Anchor Positioning and Overlays: Tethering Elements Without JavaScript",{"path":1639,"title":1640},"\u002Fmastering-container-queries-responsive-layouts\u002Fanchor-positioning-and-overlays\u002Fpopover-attribute-and-css-styling","The popover Attribute: Top-Layer Overlays With No JavaScript",{"path":1642,"title":1643},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Ffeature-detection-with-supports","Feature Detection with @supports: Syntax, Semantics, and the Traps",{"path":1645,"title":1646},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks\u002Fhandling-container-query-fallbacks-for-older-browsers","Handling Container Query Fallbacks for Older Browsers",{"path":1648,"title":1649},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-fallbacks","Container Query Fallbacks: Spec-Compliant CSS Strategies for Legacy Browsers",{"path":1651,"title":1652},"\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":1654,"title":1655},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-type-size-vs-inline-size","Choosing container-type: inline-size, size, or normal",{"path":1657,"title":1658},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fcontainer-vs-media-queries-comparison","Container vs Media Queries: Choosing the Right Reference Box",{"path":1660,"title":1661},"\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":1663,"title":1664},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics","Container Query Syntax Basics",{"path":1666,"title":1667},"\u002Fmastering-container-queries-responsive-layouts\u002Fcontainer-query-syntax-basics\u002Fnesting-and-naming-container-queries","Nesting and Naming Container Queries: Targeting the Right Ancestor",{"path":1669,"title":1670},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fauto-fit-minmax-responsive-grids","Responsive Grids with repeat(auto-fit, minmax())",{"path":1672,"title":1673},"\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":1675,"title":1676},"\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":1678,"title":1679},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts","CSS Grid and Subgrid Layouts for Responsive Interfaces",{"path":1681,"title":1682},"\u002Fmastering-container-queries-responsive-layouts\u002Fcss-grid-and-subgrid-layouts\u002Fsubgrid-vs-nested-grid","Subgrid vs an Independently Nested Grid",{"path":1684,"title":1685},"\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":1687,"title":1688},"\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":1690,"title":1691},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-type-accessibility-and-zoom","Fluid Type, Accessibility and Zoom: The vw-Only Trap",{"path":1693,"title":1694},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp\u002Ffluid-typography-without-javascript","Fluid Typography Without JavaScript: A Precision CSS Reference",{"path":1696,"title":1697},"\u002Fmastering-container-queries-responsive-layouts\u002Ffluid-typography-with-clamp","Fluid Typography with clamp(): A Practical Guide for Modern CSS",{"path":1699,"title":1700},"\u002Fmastering-container-queries-responsive-layouts","Mastering Container Queries & Responsive Layouts",{"path":1702,"title":1703},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Faspect-ratio-for-responsive-media","Using aspect-ratio for Responsive Media and Preventing Layout Shift",{"path":1705,"title":1706},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques","Intrinsic Sizing Techniques: Modern CSS Layouts for Responsive UI",{"path":1708,"title":1709},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fmin-max-fit-content-explained","min-content, max-content, and fit-content() Explained",{"path":1711,"title":1712},"\u002Fmastering-container-queries-responsive-layouts\u002Fintrinsic-sizing-techniques\u002Fpreventing-flex-and-grid-overflow","The min-width: auto Trap in Flex and Grid Layouts",{"path":1714,"title":1715},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-for-reset-and-tokens","Cascade Layers for Reset and Design Tokens",{"path":1717,"title":1718},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies\u002Fcascade-layers-vs-specificity-hacks","Cascade Layers vs Specificity Hacks: Ordering Instead of Escalating",{"path":1720,"title":1721},"\u002Fmastering-container-queries-responsive-layouts\u002Fmodern-css-reset-strategies","Modern CSS Reset Strategies: A Spec-Compliant Foundation",{"path":1723,"title":1724},"\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":1726,"title":1727},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fcontainer-query-data-tables","Container Query Data Tables: Reflowing Tables to Cards",{"path":1729,"title":1730},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fcontainer-query-sidebar-layouts","Container Query Sidebar Layouts That Travel Between Contexts",{"path":1732,"title":1733},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns","Responsive Component Patterns: Architecture & Implementation",{"path":1735,"title":1736},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-forms-with-container-queries","Responsive Forms with Container Queries: Reflow Without Losing the Wiring",{"path":1738,"title":1739},"\u002Fmastering-container-queries-responsive-layouts\u002Fresponsive-component-patterns\u002Fresponsive-navigation-without-media-queries","Responsive Navigation Without Media Queries Using Container Queries",{"path":1741,"title":1742},"\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":1744,"title":1745},"\u002Fmastering-container-queries-responsive-layouts\u002Fstyle-queries-and-container-state","Style Queries and Container State: Token-Driven Component Variants",{"path":1747,"title":1748},"\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":1750,"title":1751},"\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",1784566157608]