I was working on the responsiveness of my portfolio website when I discovered a CSS media query that changed how I think about responsive design.
I initially thought I needed a way to detect whether the website was being viewed on a mobile device or tablet.
I did that by checking if the height of the document body was greater than its width hoping it would be a reliable solution.
const isVertical= document.body.clientHeight > document.body.clientWidth;
Enter fullscreen mode Exit fullscreen mode
I realized that I was checking the device’s portrait orientation instead of checking for the device type.
While researching the issue, I encountered this CSS media query that checks if the user’s primary input device can conveniently hover over DOM elements.
@media (hover: hover) {
/* styles for devices that support hover */
}
Enter fullscreen mode Exit fullscreen mode
Tailwind also supports this through arbitrary variants
<Card className="[@media(hover:hover)]:bg-teal-800" />
Enter fullscreen mode Exit fullscreen mode
Devices that match
- Desktops with mouse
- Laptops with trackpad
- Most devices with a mouse pointer
Devices that do not match
- Touch-only phones
- Touch-only tablets
However, devices with an attached mouse or trackpad may behave differently
For example,
.button{
opacity: 1;
}
@media (hover: hover) {
.button{
opacity: 0;
}
.card:hover .button{
opacity: 1;
}
}
Enter fullscreen mode Exit fullscreen mode
On mobile devices,
- The button is always visible
-
:hoverrules are ignored
On a laptop,
- The button starts hidden
- Appears when the card is hovered
This can also be used the other way around to explicitly check if the device is unable to hover over DOM elements.
@media (hover: none) {
/* styles for devices that do not support hover */
}
Enter fullscreen mode Exit fullscreen mode
or in tailwind as [@media(hover:none)]:bg-teal-800
Another useful media feature is @media (pointer: fine), which checks pointer precision of the primary pointing device. A table below describes how both the queries respond with primary input devices.
Pointer characteristics are implementation-dependent and may vary across browsers and operating systems.
Since we have already discussed hover and pointer there are two important properties that I believe must be mentioned.
@media (any-hover: hover) {
/* styles */
}
@media (any-pointer: fine) {
/* styles */
}
Enter fullscreen mode Exit fullscreen mode
These differ from
hover
pointer
Enter fullscreen mode Exit fullscreen mode
because they consider all available inputs rather than just the primary one.
For example,
- Tablet + mouse attached
might report
hover: none
Enter fullscreen mode Exit fullscreen mode
but
any-hover: hover
Enter fullscreen mode Exit fullscreen mode
This was a small discovery, but it changed the way I approach responsive design. If you’re building interactions that depend on hover or pointer precision, these media queries are worth keeping in mind.
답글 남기기