Transparent borders for element states

This article was originally posted on the Capgemini Engineering blog

It’s quite a common design requirement to have a border on some states of an element but not others. For example a set of tabs where the currently active tab is highlighted with a top border, or a button where a border is added on hover.

The problem is that if you add a border to an element, that changes its size, so if you add a border on one state of a component, then the size will change when the state changes, as you can see from these examples:

One simple and elegant solution is to use a transparent border on the other versions of that element, and only change the border colour when the state changes.

This feels like a very old and quite basic piece of advice, so I assumed it must have been written about before, but the only example I’ve found is in this stack overflow answer.

There are other ways to approach this, like using an inset box-shadow, or changing the padding to offset the size of the border, but to me that feels unnecessarily complex, and unintuitive enough that I’d want a comment in the code to explain why.