Hover States and Transitions

Make your site respond to the visitor

8 min read

Great websites feel alive. Move your mouse over a button and it brightens. Hover over a card and it lifts slightly. These little responses tell visitors "yes, you can click this", and they make a site feel cared for. In CSS, they take just a few lines.

The hover pseudo-class

A pseudo-class is a special condition you attach to a selector with a colon. The one you will use most is :hover, which applies only while the visitor's pointer is over the element:

.button {
  background-color: steelblue;
  color: white;
  padding: 12px 24px;
  border-radius: 8px;
}

.button:hover {
  background-color: #2c5f8a;
}

Read the second rule as "a .button, while hovered". The moment the mouse arrives, the darker background applies. The moment it leaves, the normal style returns. You write the two states, and the browser handles the switching.

Links deserve hover styles too. Even something as small as an underline appearing tells the visitor the link is real:

a:hover {
  text-decoration: underline;
}

One more nicety: the cursor

Real buttons made with the <button> tag get a pointer cursor automatically, but if you ever style something else to look clickable, add cursor: pointer; so the mouse arrow becomes the little hand. Small detail, big difference in how trustworthy your interface feels.

Smooth changes with transitions

By default, hover changes snap instantly from one state to the other, which can feel abrupt. The transition property makes the change glide instead. You put it on the normal state, not the hover state:

.button {
  background-color: steelblue;
  transition: background-color 0.2s;
}

.button:hover {
  background-color: #2c5f8a;
}

Read transition: background-color 0.2s; as "whenever background-color changes, take 0.2 seconds to get there". Now the color fades smoothly in both directions, on the way in and on the way out. Keep durations short: 0.15s to 0.3s feels responsive, while anything near a full second starts to feel sluggish.

The lift effect

Here is a favorite combination that you will use on your cards later. The transform property can move an element without disturbing anything around it, and translateY(-4px) nudges it 4px upward:

.card {
  transition: transform 0.2s, box-shadow 0.2s;
}

.card:hover {
  transform: translateY(-4px);
  box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15);
}

On hover, the card floats up and its shadow deepens, as if it rose off the page toward you. It is a tiny effect, it takes six lines, and it instantly makes a site feel modern.

A note on kindness: hover effects should be gentle. Growing, spinning, or flashing elements can be distracting or even unpleasant for some visitors. A subtle color shift or a small lift is plenty.

Quick check

Q1 When does the style in .button:hover apply?

Q2 Where should the transition property go for a smooth hover effect in both directions?

Want to save your progress? It's free.

Create a free account