HTML & CSS
Article

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

By 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.

Conclusion

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.

George Martsoukos
Meet the author
George is a freelance web developer and an enthusiast writer for some of the largest web development magazines in the world (SitePoint, Tuts+). He loves anything related to the Web and he is addicted to learning new technologies every day.
  • http://www.adriansandu.com Adrian SANDU

    That’s a very ingenious trick and I’ll definitely use it if I have to solve a similar problem in the future.

  • zralokh3

    From my experience sometimes it is a lot more beneficial to use min-width instead of width, when trying to solve the above issue.

  • http://georgemarts.com/ George Martsoukos

    This looks good, but with limited browser support…

  • il_matita

    To avoid the blurred effect with the text-shadow solution the a:hover clause could be:

    text-shadow: .65px 0 0 #333, -.65px 0 0 #333;

    Maybe it is better without the transition.

    • http://georgemarts.com/ George Martsoukos

      Nice one! Personally, I prefer this effect (blurred text). I’ve seen that it works well with some popular web fonts like Fira Sans. But I like as well your solution because some people may don’t like it.

  • Rui Nunes

    Doesn’t seem to be working on Safari (OSX Version 9.0.3 (11601.4.4))

    • http://georgemarts.com/ George Martsoukos

      I don’t have a real device to test it, but I think that there are differences in how browsers display the text-shadow property. For example, if you try the following value which generates a pretty intense effect, you’ll probably notice that it works.

      text-shadow: 0 0 2px #333, 0 0 2px #333, 0 0 2px #333;

  • http://georgemarts.com/ George Martsoukos

    Sure, this solution is similar to another one which has already been proposed!

  • James Ferrell

    That’s a real css trick. Chris Coyier would be proud. :)

  • PawelGIX

    My answer to this problem.
    Just do not do it. This is ugly. Bad design decision.
    Especially in conjunction with the :hover.

  • Nazar Pelekh

    It’s not the answer… text with shadow is little blur

  • Dennis Lembrée

    I think the title means to say “on Hover AND FOCUS States”.

Recommended

Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in Front-end, once a week, for free.