CSS pseudo-classPseudo-classes

:hover

Matches the element the mouse cursor is currently over. The basis of hover effects on buttons, links, and cards.

On this page

Example

#
CSS
.btn {
  background: #7c3aed;
  transition: background-color 0.2s, transform 0.2s;
}

.btn:hover {
  background: #6d28d9;
  transform: translateY(-2px);
}
Preview

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

#
Syntax
selector:hover { property: value; }

Common uses

#
  • .demo:hover

    Hover over the card: it changes color and lifts slightly. The smoothness comes from transition set in the base style.
  • .demo:hover .icon

    Hovering over the card changes an element inside it. The icon reacts whenever the cursor is anywhere over the card.
  • .icon:hover

    Only the icon itself. The card doesn’t change until the cursor touches the star.
  • .demo:not(:hover)

    Flipped around: the card is dimmed and only brightens once the cursor is over it.
  • @media (hover: hover)

    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

Hover over the card: it changes color and lifts slightly. The smoothness comes from transition set in the base style.
.demo:hover {
  background: #7c3aed;
  transform: translateY(-3px);
}

.demo:hover .icon

Hovering over the card changes an element inside it. The icon reacts whenever the cursor is anywhere over the card.
.demo:hover .icon { background: #f59e0b; rotate: 15deg; }

.icon:hover

Only the icon itself. The card doesn’t change until the cursor touches the star.
.icon:hover { background: #10b981; scale: 1.25; }

.demo:not(:hover)

Flipped around: the card is dimmed and only brightens once the cursor is over it.
.demo:not(:hover) { opacity: 0.5; }

@media (hover: hover)

The effect only on devices with a cursor, such as a mouse or trackpad. On a phone the card won’t change.
@media (hover: hover) {
  .demo:hover { background: #0ea5e9; }
}

More examples

#
Buttons visible on hover and keyboard focus
CSS
.lesson .actions {
  opacity: 0;
  transition: opacity 0.2s;
}

.lesson:hover .actions,
.lesson:focus-within .actions {
  opacity: 1;
}
Preview

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 :hover alone. 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. Changing width or margin shifts neighboring elements and can make the layout jump.

Related entries

#

Spotted a mistake or missing an example? Write to us.