Back to work
technique//2 min read

Rethinking Hover States

Why most hover effects feel cheap, and how to design interactions that communicate hierarchy and affordance.


Hover states are the handshake between a user and an interface. They communicate "this is interactive" before any click happens. Yet most hover effects are an afterthought — a color swap, maybe an underline.

The problem with opacity

The most common hover pattern is reducing opacity:

.link:hover { opacity: 0.7; }

It works, but it's lazy. Opacity changes feel like the element is fading out, not inviting interaction. The user's instinct is "this is disappearing" rather than "this is responding to me."

Feel the difference yourself — hover each card:

Same card, three hover strategies. Opacity feels like fade-out; translate and background feel like response.

Better alternatives

1. Subtle translate

A small upward shift (1–2px) signals responsiveness without visual noise:

.card {
  transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.card:hover {
  transform: translateY(-2px);
}

2. Background reveal

Show a subtle background on hover to define the interactive area — the same pattern this site uses on work list items.

.item {
  padding: 8px 12px;
  border-radius: 6px;
  transition: background-color 150ms ease;
}
.item:hover {
  background-color: var(--bg-surface);
}

3. Underline animation

For text links, animate the underline from left to right:

Animated underline link

Hover or focus — the underline grows from left to right

Hover or keyboard-focus the link — the underline grows with the interaction.
.link {
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1px;
  background-position: left bottom;
  background-repeat: no-repeat;
  transition: background-size 300ms ease;
}
.link:hover,
.link:focus-visible {
  background-size: 100% 1px;
}

Match the nature of the action

Every hover state should answer: what happens next? If clicking will navigate, the hover should suggest movement. If clicking will expand, the hover should suggest growth.

Hover each — one lifts (navigate), one grows (expand). Same spring, different intent.

Match the interaction's nature, not just its existence.