Skip to content

Hit Areas

Checked by hit-area

A hit area is the part of an element that responds to a click or tap. It does not have to match what you can see. A 16px icon can sit in a 32px button, and nobody notices the extra space until it is missing.

Wrong
16 × 16px targets
Right
32 × 32px targets

The two toolbars look the same. Hover across them, then show the hit areas. The left one asks you to land on the icon itself.

Make the hit area bigger than the thing you can see.

How big

The numbers most guidance agrees on:

  • 24 × 24px: the WCAG 2.2 minimum (2.5.8, level AA). A smaller target only passes if it has enough empty space around it.
  • 44 × 44px: the enhanced level (2.5.5, AAA). Apple uses the same 44 by 44 points as the default size for iOS controls.
  • 48 × 48dp: what Android and Material ask for on touch.

I treat 24px as the floor for anything clickable and 32px as a comfortable size for icon buttons on desktop. On touch, aim for 44px.

Extend the target, not the icon

Sometimes a bigger button would look wrong, like the close button on a chip. Keep the visible circle small and stretch an invisible pseudo-element over it. Drag the slider and try to hit the close buttons.

DesignEngineeringProduct

The button is 14px. An ::after with inset: -8px turns it into a 30px target, and the chip looks exactly the same.

Gaps are dead zones

The space between two targets belongs to neither. Move slowly down the left menu and the highlight drops out between items. A click there does nothing.

Wrong
Right

On the right the items touch. The breathing room comes from padding inside each item, so every pixel of the menu does something.

Usage

app.tsx
<!-- A 16px icon in a 32px button -->
<button class="grid size-8 place-items-center" aria-label="Bold">
  <svg class="size-4">...</svg>
</button>

<!-- A 14px button with a 30px target -->
<button class="relative size-3.5 after:absolute after:-inset-2" aria-label="Remove">
  <svg class="size-2.5">...</svg>
</button>
.close {
  position: relative;
  width: 14px;
  height: 14px;
}

/* Invisible, but it takes the click */
.close::after {
  content: "";
  position: absolute;
  inset: -8px;
}

Don't let an extended area spill onto a neighbor. Where two hit areas overlap, the one painted on top wins, and a click meant for one lands on the other.

Resources

Search concepts

Search for a command to run...