:hover
Matches the element the mouse cursor is currently over. The basis of hover effects on buttons, links, and cards.
Example
#.btn {
background: #7c3aed;
transition: background-color 0.2s, transform 0.2s;
}
.btn:hover {
background: #6d28d9;
transform: translateY(-2px);
}<button class="btn" type="button" style="padding: 10px 18px; border: 0; border-radius: 10px; color: #fff; font: 600 15px system-ui, sans-serif; cursor: pointer;">Hover over me</button>Definition and usage
#The :hover pseudo-class switches on when the user points the cursor at an element, and off when the cursor moves away. It matches not just the pointed-at element itself, but also all of its ancestors, since the cursor is over all of them at once. That’s why .card:hover .icon changes the icon whenever the cursor is anywhere over the card.
It’s most often paired with transition, so a change in color, shadow, or position feels smooth. For links, remember the order of the rules: :link, :visited, :hover, :active. With equal specificity, the rule written later wins, so putting :visited after :hover would hide the hover effect.
Touchscreens have no cursor. Browsers usually simulate :hover after a tap, and the state can stick to the element until you tap somewhere else. So don’t hide important content behind hover alone, and wrap mouse-only effects in @media (hover: hover).
People using a keyboard never trigger :hover either. It’s worth repeating the hover effect on an interactive element in :focus-visible.
Syntax
#selector:hover { property: value; }Common uses
#- Hover over the card: it changes color and lifts slightly. The smoothness comes from
transitionset in the base style. - Hovering over the card changes an element inside it. The icon reacts whenever the cursor is anywhere over the card.
- Only the icon itself. The card doesn’t change until the cursor touches the star.
- Flipped around: the card is dimmed and only brightens once the cursor is over it.
- The effect only on devices with a cursor, such as a mouse or trackpad. On a phone the card won’t change.
Common uses in practice
#.demo:hover
transition set in the base style..demo:hover {
background: #7c3aed;
transform: translateY(-3px);
}.demo:hover .icon
.demo:hover .icon { background: #f59e0b; rotate: 15deg; }.icon:hover
.icon:hover { background: #10b981; scale: 1.25; }.demo:not(:hover)
.demo:not(:hover) { opacity: 0.5; }@media (hover: hover)
@media (hover: hover) {
.demo:hover { background: #0ea5e9; }
}More examples
#.lesson .actions {
opacity: 0;
transition: opacity 0.2s;
}
.lesson:hover .actions,
.lesson:focus-within .actions {
opacity: 1;
}<style>
.lesson { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 14px; border-radius: 12px; background: #18181b; }
.lesson button { padding: 6px 10px; border: 0; border-radius: 8px; background: #3f3f46; color: #fff; font: inherit; }
</style>
<div class="lesson">
<span>Lesson 4: pseudo-classes</span>
<span class="actions"><button type="button">Edit</button> <button type="button">Delete</button></span>
</div>Hover over the row, or click into the preview and press Tab. The buttons appear in both cases, because the rule combines :hover with :focus-within.
Browser support
#Widely available
Works in all modern browsers, phones included. You can use it without worry.
- Chrome
- Edge
- Firefox
- Safari
Good practices
#- Don’t hide important information or buttons behind
:hoveralone. On a phone, and with keyboard navigation, the user will never see them. - Repeat the hover effect for the keyboard:
.btn:hover, .btn:focus-visible { … }. - On hover, change
transform,opacity, and colors. Changingwidthormarginshifts neighboring elements and can make the layout jump.
Related entries
#- :focus-visibleMatches a focused element only when the browser decides the indicator should be visible, such as during keyboard navigation.
- :activeMatches an element at the moment it’s activated, most often while the mouse button is pressed down on a button or link.
- :focus-withinMatches an element that either has focus itself or contains an element with focus. Lets you highlight an entire form or card.
- :not()Selects elements that match neither the given selector nor any selector in the list.
Spotted a mistake or missing an example? Write to us.