|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: Transparent borders for element states |
| 4 | +description: An old-fashioned CSS trick |
| 5 | +category: Frontend |
| 6 | +tags: [Development,CSS] |
| 7 | +author: [malcolm_young] |
| 8 | +comments: true |
| 9 | +--- |
| 10 | + |
| 11 | +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. |
| 12 | + |
| 13 | +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: |
| 14 | + |
| 15 | +<div class="row"> |
| 16 | + <div class="column small-12 medium-6 small-centered medium-uncentered"> |
| 17 | + <div class="flex-video"> |
| 18 | + <iframe src="https://codepen.io/malcomio/full/abrmwjd"></iframe> |
| 19 | + </div> |
| 20 | + </div> |
| 21 | + <div class="column small-12 medium-6 small-centered medium-uncentered"> |
| 22 | + <div class="flex-video"> |
| 23 | + <iframe src="https://codepen.io/malcomio/full/oNRzwqY"></iframe> |
| 24 | + </div> |
| 25 | + </div> |
| 26 | +</div> |
| 27 | + |
| 28 | +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. |
| 29 | + |
| 30 | +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](https://stackoverflow.com/questions/39385180/css-adding-border-to-button-on-hover-how-avoiding-a-shifting-of-the-following). |
| 31 | + |
| 32 | +<div class="row"> |
| 33 | + <div class="column small-12 medium-6 small-centered medium-uncentered"> |
| 34 | + <div class="flex-video"> |
| 35 | + <iframe src="https://codepen.io/malcomio/full/GRajEXy"></iframe> |
| 36 | + </div> |
| 37 | + </div> |
| 38 | + |
| 39 | + <div class="column small-12 medium-6 small-centered medium-uncentered"> |
| 40 | + <div class="flex-video"> |
| 41 | + <iframe src="https://codepen.io/malcomio/full/MWdjQyv"></iframe> |
| 42 | + </div> |
| 43 | + </div> |
| 44 | +</div> |
| 45 | + |
| 46 | +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](https://blog.codinghorror.com/code-tells-you-how-comments-tell-you-why/). |
0 commit comments