Quick Tip: Fixing the font-weight Problem on Hover States

George Martsoukos

Have you ever tried to change the value of the font-weight property on link states? If yes, you may have noticed that the text shifts.

In this quick tip, we’ll first learn what causes this undesired behavior and then we’ll examine two possible solutions.

Identifying the Problem

As a first step, let’s identify the problem by looking at a simple example. Consider the following visualization:

Menu example

The items are links, so in your CSS you might try something like this:

a:hover {
  font-weight: bold;

Because we usually don’t define a fixed width for items like this, when the user hovers over the links, the text shifts. Of course, this happens because the width of each link gets bigger on hover. To test it, we assign the active class to the first link and add this CSS rule:

.active {
  font-weight: bold;

Lastly, we change the text of the second link to be equal to the first one, like so:

Font-weight on hover

Now, if we open the browser console and target the first two links, we’ll notice that their computed width is different.

You can see what we’ve discussed above in the following CodePen demo:

See the Pen Using the font-weight Property on Hover States by SitePoint (@SitePoint) on CodePen.

Admittedly, it’s not very common to add a bold effect to a hover state, but it may come up at some point. So let’s look at two possible solutions to get around this problem.

Solution 1: Give All Items a Width

As mentioned, perhaps the most obvious solution is to give all list items a width. So, in our example, we set the width of each list item to 24%.

Here’s the result:

See the Pen Fixing font-weight hover states using defined widths by SitePoint (@SitePoint) on CodePen.

Even though the solution above works, it’s might not ideal because there are cases when we might want to avoid adding a fixed width to our elements. With that in mind, let’s discuss a better solution.

Solution 2: Text Shadow

By taking advantage of the text-shadow property, we’re able to somehow simulate the font-weight behavior. We do this by playing with the blur-radius value so as to adjust the shadow according to our needs.

Depending on the fonts used in our projects, we can combine the text-shadow property along with the letter-spacing property to create some nice text effects.

To demonstrate this behavior, we assign a few additional lines of CSS to our links:

a {
  letter-spacing: .1em;
  transition: text-shadow .3s;

a:hover {
  text-shadow: 0 0 .65px #333, 0 0 .65px #333;
  /* use the line below if you want a more intense effect */
  /* text-shadow: 0 0 .9px #333, 0 0 .9px #333, 0 0 .9px #333; */

Here’s the demo:

See the Pen Fixing font-weight hover states with Text Shadow by SitePoint (@SitePoint) on CodePen.

So we avoid the problem of the items moving, and we don’t require adding any kind of widths to the elements. And as you can see, this solution is much nicer than using font-weight because the size of the text isn’t changing at all. So it’s a much cleaner look.


If I needed to solve this problem, I’d likely use one of the two solutions I just described. Do you know of another way to fix this? Let us know in the comments.