Pointer media queries
Creating larger tap targets — like buttons, inputs, or menus — can make interface feels more comfortable and easier to use on touch devices. This is often done with width-based media queries:
.button {
height: 1.4rem;
}
/* if width is 624px or less, make the button larger */
@media (width <= 624px) {
.button {
height: 2rem;
}
}
This is a good start, but it doesn’t capture how diverse devices actually are:
- Large screens might rely on large pointers (like tablets or TV remote).
- Small screens can also use highly precise input (like stylus).
Using viewport alone misses this nuance. Instead we can use pointer media query which targets devices by pointer precision:
(pointer: coarse)
for low-precision input, like fingers on tv remote(pointer: fine)
for high-precision input, like stylus, mouse or trackpad
Instead of assuming all small screens are touch-based (or all large ones aren’t), pointer: coarse
lets us respond to how users actually interact.
.button {
height: 1.4rem;
}
/* if pointer is coarse, make the button larger */
@media (pointer: coarse) {
.button {
height: 2rem;
}
}
This helps make interfaces more comfortable and accessible to use, no matter the screen size.
To take this even further and make more scalable, it can be integrated into your design system variables.
:root {
--target-size-sm: 1rem;
--target-size-md: 1.4rem;
--target-size-lg: 2rem;
}
@media (pointer: coarse) {
:root {
--target-size-sm: 1.4rem;
--target-size-md: 2rem;
--target-size-lg: 2.5rem;
}
}
Which you then can use for any buttons, inputs, menu items and other interactive elements.
.button {
height: var(--target-size-md);
}
.button-lg {
height: var(--target-size-lg);
}
.button-sm {
height: var(--target-size-sm);
}
This way the change happening in one place in your configuration and all interactive elements will have consustent sizing.
Magic ✨