Understanding the :hover Pseudo‑Class in CSS

Hero image for Understanding the :hover Pseudo‑Class in CSS. Image by Wesley Tingey.
Hero image for 'Understanding the :hover Pseudo‑Class in CSS.' Image by Wesley Tingey.

The :hover pseudoclass is a widely used feature in CSS (and one which even most junior developers should be familiar with). It is a simple yet powerful tool for creating visual feedback, allowing us to apply styles to an element in response to user interaction (when they hover their mouse over it). However, despite being a fairly rudimentary part of CSS, there are still aspects of :hover that can trip up even more seasoned developers.

These challenges often include understanding how :hover interacts within specificity rules, handling hover states across different devices (like touchscreens), and its place in the LOVE HATE rule for link pseudoclasses (which dictates the order of styling to ensure consistent behaviour).


What is a Pseudo‑Class?

Starting with the absolute basics... In CSS a pseudoclass is a keyword that we can add to your selector that specifies a special state of that element. Pseudoclasses allow us to style elements based on things like user interactions, element position, or structural state without needing to add additional classes or IDs in the HTML.

Pseudoclasses help us create dynamic effects in CSS by recognising and styling states like hovered, focused, or visited.

The syntax for a pseudoclass in CSS looks something like this:

selector:pseudo-class {  /* styles for the pseudo-class go here */}

Understanding the :hover PseudoClass

The :hover pseudoclass allows us to apply styles when the user hovers their cursor over the element we've targetted with our selector, for example, a button, link, or image. This allows us to provide visual feedback to the user, making the element more interactive and offering a little enhancement to the user experience.

Here's a basic example showing how we might use :hover on a button:

button:hover {  background-color: #4caf50;  color: white;}

Here, when the user hovers their hovers over the button, the background changes to a green colour (#4caf50), and the text colour changes to white. This only applies whilst the user is hovering over the element, and then reverts when the user moves their cursor away.


:hover within Context of Other PseudoClasses

In frontend development, we would commonly use :hover in combination with other interactionbased pseudoclasses, especially when styling links. When doing so, there are four key pseudoclasses that often work alongside one another:

  • :link targets unvisited links. This is generally the default state for a linkable element like an anchor (<a>).
  • :visited targets links that have been visited.
  • :active targets an element usually a link when it is being activated or clicked upon.
  • :hover targets an element when the user hovers their cursor over it.

When we're using pseudoclasses to style links, there is a very specific order we need to follow for our pseudoclasses in order to ensure consistent behaviour and inheritance between the different styles.

I've long lost the original article I read on the matter twenty years ago, but the crux is that it follows the ordering of the letters in LOVE HATE (this is how I first learned it myself), representing :link, :visited, :hover, and :active, in that order.

Using this method avoids weird inheritance issues and keeps your link styling predictable. Here's how it breaks down:

  1. :link (L) — This pseudoclass targets unvisited links and sets the base styling for all links on the page. It comes first because it represents the default state of a link before any user interaction occurs.
  2. :visited (V) — This styles links that the user has already visited. It appears second so that the browser can override the :link styling if a link has been visited. This ensures that users can visually distinguish between links they have and haven't clicked on yet.
  3. :hover (H) — As we've been discussing in this article, the :hover pseudoclass applies styles when the user places their mouse over a link. It comes after :link and :visited in the sequence, because when we apply hovered styles, we want these to override the default and visited states when the user interacts with it.
  4. :active (A) — This pseudoclass styles a link during the moment that it is being clicked upon or activated. It comes last in the order because it needs to override all of the other states temporarily whilst the user is interacting with the link. The :active state should take precedence only when the link is engaged, reverting back to either :hover, :visited, or :link once the 'active' interaction ends.

The order is designed this way to ensure that more specific interactions (like clicking) override less specific ones (like hovering or simply having been visited). Here's how this ordering looks in practice:

a:link {  color: blue;}a:visited {  color: purple;}a:hover {  color: red;}a:active {  color: green;}

In this example:

  • The link starts blue (:link).
  • Once visited, it turns purple (:visited).
  • When hovered, it turns red (:hover), overriding both the :link and :visited states.
  • Whilst being clicked, it becomes green (:active), temporarily overriding all the other states, but particularly the :hover state, since it is likely that the user's cursor is still hovering over the element whilst clicking upon it.

The LOVE HATE sequence allows us to make sure that the styles we intend are applied in a way that reflects the user's current interaction priorities, maintaining usability and visual consistency.


A Practical Example of :hover with a Button

So, with the more nittygritty technical stuff out of the way, let's look at a more practical example, maybe even some code you might use yourself. For this, buttons are a great example because adding hover effects to buttons can make them feel more responsive and offer a visual guide to the user as they interact with the page.

button {  background-color: #008cba;  color: white;  padding: 10px 20px;  border: none;  cursor: pointer;  transition: background-color 0.3s ease;}button:hover {  background-color: #005f73;}

What we've done here is created styling for a button which changes to a darker shade of blue (from #008cba to #005f73) when it is hovered over. To offer a little more insight into the power of these types of pseudoclasses, I've also added the transition property, which means that the effect animates smoothly between the element's default and hover states:


The Importance of :hover and Accessibility

Whilst :hover can improve interactivity and visual feedback in our application, it's essential to remember accessibility. As you might appreciate, hover effects only work for users who are using a mouse or similar pointing device. Keyboard users, for example, won't see :hover styles at all.

With that in mind, it's generally good practice to combine :hover and :focus pseudoclasses together so that both pointer and keyboard users receive our interactive visual cues.

For example:

button:hover,button:focus {  background-color: #005f73;}

Now, the button background will change to a darker blue when a user triggers either the :hover or :focus pseudoclasses, offering keyboard users the same experience as those using pointer devices.


Wrapping up

The :hover pseudoclass is a powerful tool in CSS that allows us, as frontend developers, to create interactive and visually engaging experiences to signal interactivity to our users. By understanding :hover in the context of other pseudoclasses, especially within the LOVE HATE ordering for links, we can create intuitive, and accessible interactions for our users.

Whether used on links, buttons, or other interactive elements, :hover can add polish to your web designs and make your interfaces feel more dynamic. Just remember to consider accessibility and combine :hover with :focus where needed to ensure a consistent experience across different devices and user preferences.


Categories:

  1. CSS
  2. Development
  3. Front‑End Development
  4. Guides