The Most Underused CSS Media Queries: Hover & Any-Hover
Posted on • Last updated on
Today I want to talk about my favorite media queries in CSS, hover
and any-hover
, which let you detect if a user is able to hover over elements on your website. Besides the width-based media queries, to help with responsive design, the hover media queries have been by far the most useful for me. In this article, I’m going to go over two extremely useful ways that I’ve been able to use the hover media queries, but first, let’s talk about how they actually work.
What Do They Even Do?
Starting with hover
, this media query is used to check if the primary input mechanism of a user's device can hover over elements. Generally, a computer's primary input mechanism is a mouse or trackpad, which controls a cursor on a screen; since cursors can move over elements, they are able to hover over things. However, touchscreens have a primary input of touch, which can't really hover over elements...
While hover
is the one that I generally use, there is also any-hover
, which looks at all of the currently available input methods and tells you if any of them can hover over things. An example where this would be useful is if a person is using an iPad with a Bluetooth mouse connected to it. Since the primary input of an iPad is touch, hover
would fail the test, but any-hover
would pass the test because it looks at all input methods, and a mouse, which on an iPad will appear as a tiny circle on the screen, can hover over elements.
Both hover
and any-hover
have two modes: hover
, meaning that the user can hover over elements, and none
, signaling that they can't. Here's what the syntax looks like with hover
; for any-hover
, swap hover
with any-hover
.
@media (hover: hover) {
/* The user can hover - generally with a mouse cursor */
}
@media (hover: none) {
/* No hovering available - generally a touchscreen */
}
Why You Need to Start Using Them
Now, let’s go over the main use cases for the hover media query! I’m going to use hover
for the examples, but they will all work with any-hover
.
Fix Glitchy Hovering on Touchscreens
One of the most useful ways of using hover
is to fix glitchy, also called “sticky”, hover effects on your website. Sticky hovering is caused when there’s a hover animation on an element, but when tapping on it with a touchscreen, the :hover
pseudo-class styling sticks and never goes away.
An example of this issue, that I solved with the hover
media query, is my links, which change background color when hovering over them. Before I learned about the hover
media query, the background highlight effect would remain after a user tapped on a link with a touch screen. This was really annoying, but by wrapping the hover styling in the hover
media query, this is no longer an issue! If you’re curious, here’s the code for the links:
Some HTML:
<a class="blue-link" href="a-link-here" target="_blank">Link Text</a>
The link styling:
.blue-link {
text-decoration: none;
cursor: pointer;
color: var(--second-color);
background-image: linear-gradient(var(--second-color-opaque), var(--second-color-opaque));
background-size: 100% 0px;
background-position: bottom;
background-repeat: no-repeat;
/* 1px padding around background */
background-clip: border-box;
padding: 1px;
margin: -1px;
transition: background-size 150ms;
}
@media (hover: hover) {
.blue-link:hover {
color: var(--constant-light-mode-second-color-dark);
background-size: 100% 100%;
}
}
Display Content on Touchscreens
The other way that I like to use hover
is to automatically show users extra information that would normally only be seen by hovering over an element. Let's say we have some sort of icon/tooltip that, when hovered over, displays additional information about said icon. On a touchscreen, we may want this information to always be visible since there's no hover capability. Here's how we can achieve that:
<div class="info-icon">An icon/button/image</div>
<div class="info-tooltip">Some text explaining what the icon does</div>
.info-tooltip {
display: none;
background-color: lightgray;
}
.info-icon:hover + .info-tooltip {
display: inline-block;
}
@media (hover: none) {
.info-tooltip {
display: inline-block;
}
}
In this snippet, the tooltip is initially set to display: none;
and becomes visible when the user hovers over the info icon. However, it’s shown immediately if the browser (probably a phone) doesn’t support hovering.
Final Thoughts
Both hover
and any-hover
are great ways to ensure that your site works on all types of devices, all while improving users’ experiences. The examples I showed are the most common ways that I use them, but there are basically an endless number of creative use cases for them. Make sure to use them next time you’re writing some responsive CSS!