Menu

CSS Hover: :hover, :active and Link Color States

The :hover pseudo-class styles an element while the pointer is over it. Learn hover effects for buttons and cards, smooth transitions, link colors with :link, :visited, :hover and :active in the right order, and hover on touch screens.

This page includes runnable editors - edit, run, and see output instantly.

How :hover works

:hover is a pseudo-class that matches an element while the mouse pointer is over it. Add it to any selector and write the styles for the hovered state:

Only the declarations in the :hover rule change; everything else carries over from .btn. When the pointer leaves, the element returns to its normal styles.

Smooth hover effects with transition

A hover change is instant unless you add transition to the normal rule (not the :hover rule), so it animates both in and out:

transform and opacity are the cheapest properties to animate; they do not move the elements around them. Animating width, height or margin makes the page reflow on every frame. Durations, delays and easing curves are on the CSS transition page.

Links have four classic states, plus keyboard focus, and the order of the rules matters:

Pseudo-classApplies when
:linkThe link has not been visited
:visitedThe URL is in the browser history
:hoverThe pointer is over it
:activeIt is being pressed
:focus-visibleIt has keyboard focus

All of these have the same specificity, so the later rule wins when two match. A visited link that is hovered matches both :visited and :hover; if :visited comes last, the hover color never shows. The safe order is Link, Visited, Hover, Active (LVHA):

Browsers limit what :visited can change, to stop pages from reading your history. Only color-related properties (color, background-color, border-color, outline-color and a few others) take effect, and scripts always see the unvisited value.

:active: the pressed state

:active matches while the element is being pressed. A small movement makes a button feel physical:

Hovering a parent to style a child

The hover state belongs to the element under the pointer and every ancestor of it. So .card:hover .title styles the title whenever any part of the card is hovered, and the same idea reveals hidden elements:

The :focus-within line matters: without it, a keyboard user tabbing to the Delete button would press an invisible button. Pair every hover-reveal with a focus rule.

Hover on touch screens

Phones and tablets have no pointer that rests over an element. Most mobile browsers apply :hover on the first tap and keep it until you tap somewhere else, so a hover style can appear stuck. Two rules keep this under control:

  • Never put the only way to reach content behind :hover. A menu that opens on hover also needs to open on click.
  • Wrap purely decorative hover effects in a media query that checks for a real hover device:
@media (hover: hover) {
  .card:hover { transform: translateY(-4px); }
}

Common mistakes

  • A space before the colon. .btn :hover means "a hovered element inside .btn". Write .btn:hover.
  • transition only on the :hover rule. It then animates in but snaps back on the way out. Put it on the normal rule.
  • Wrong link order. Keep :link, :visited, :hover, :active in that order.
  • Hover with no focus style. Keyboard users never trigger :hover; give interactive elements a :focus-visible style too.
  • Hover on an element covered by another. An invisible overlay (often an absolute pseudo-element) can catch the pointer. pointer-events: none on the overlay fixes it.

Frequently Asked Questions

How do I add a hover effect in CSS?

Write a rule with :hover after the selector: .btn:hover { background: #1d4ed8; }. The declarations apply while the pointer is over the element. Add transition: background 0.2s; to the normal rule to animate the change.

What is the difference between :hover and :active?

:hover applies while the pointer is over the element. :active applies while it is being pressed, from mouse button down to release. A pressed button is usually both hovered and active.

What order should link pseudo-classes be in?

:link, :visited, :hover, :active (remember LVHA, or "LoVe HAte"). They have equal specificity, so the later rule wins; in any other order a visited or hovered style can hide the hover or active style.

How do I change the link color in CSS?

Style the a element: a { color: #2563eb; }, then a:visited { color: #7c3aed; } and a:hover { color: #1d4ed8; } for the other states. Setting color on a covers both unvisited and visited links.

Does hover work on mobile?

Touch screens have no pointer to rest over an element. Most mobile browsers apply :hover on tap and keep it until you tap elsewhere, which can leave a hover style stuck. Wrap hover-only effects in @media (hover: hover) and never hide essential content behind hover.

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED