Code, Angular, iOS and more by Aviv Ben-Yosef

CSS Tip: Stop Your Buttons from Flickering

| Comments

With the rise of flat design and it taking over the whole web, I’ve got this pet peeve with buttons that “wiggle” on hover. It’s becoming more and more common to have buttons where in one state they are flat and just have a nice background color, and in the hover state the background color changes and a border is added. Let’s have a look:

The CSS looks like this:

.wiggle-button {
    height: 3em;
    width: 20em;
    background: #007aff;
    border-radius: 5px;
    color: white;

.wiggle-button:hover {
    background: white;
    color: #007aff;
    border: 1px solid #007aff;

As you can see, hovering over the button causes it to wiggle, and the rest of the content below it to move. Not good enough.

The problem is caused because the button has no border on the regular state and a border is added on hover. The new border adds to the actual height and width of the button, making it wiggle and push all elements after it.1

I’ve seen CSS newbies solve this by adding a border with the same color to the normal state, which would work, but isn’t to my taste.

Whenever you want to have an element’s size not change due to inner changes such as borders, paddings, etc. you’re actually thinking about box-sizing: border-box.

So, just adding box-sizing: border-box to our .wiggle-button class gives us this new sexy button:

This is a cleaner solution, in my opinion, since it makes sure the border doesn’t cause size changes to the button. This magical attribute solves our problems in this case just like that, and is supported on all latest browsers2.

I hope you learned something new. Happy coding!

Write maintainable Angular, learn the best practices and get prepared for 2.0!

  1. See here for calculating a CSS element’s size

  2. Some browsers need a vendor prefix, see full information here