How and Why I Avoid Magic Numbers in CSS
Tags: webdev, css
Published: 2020-01-22 18:18:27

---
title: How and Why I Avoid Magic Numbers in CSS
description: Writing styles with arbitrary numbers is brittle and unmaintainable, so use Grid and CSS custom properties instead
published: true
tags: #webdev #css
---

## Introduction

There's a great article called [Code smells in CSS](https://csswizardry.com/2012/11/code-smells-in-css/#magic-numbers) by Harry Roberts that first introduced me to the concept of magic numbers in CSS.

When Harry wrote the article in 2012, there weren't too many great solutions for dealing with these problems. But since then, we've gotten Grid and Flex layout, along with CSS custom properties (variables!) so we can now avoid many of the pitfalls.

The basic idea of magic numbers is that writing styles with arbitrary numbers like the following is brittle and unmaintainable:

```css
.container {
	height: 250px;
}
.box1 {
	padding-left: 4px;
	position: relative;
	top: 11px;
}
.box2 {
	padding-left: 2px;
	padding-right: 4px;
	position: relative;
	top: 7px;
}
```

For one thing, what's so special about these numbers?  Even if there were comments, you might not know all that they're doing unless you look at the markup, or how they relate to the other numbers.

Let's say `.box1` and `.box2` are next to each other.

Focusing on `.box2`, let's first look at its `padding` -- 2 on the left and 4 on the right. The left padding is defining the space between the components, and the right side in defining the outer right margin of the page. That's not very conducive to composability. What if we wanted to reverse the order? We would have to sift out the 2 and 4, reverse them, and apply them to the other component. It would be better if the container could manage these details.

The `11px` and `7px` `top` values here are vertically centering the boxes inside their container. That's precarious, in case the content changes. There are better ways to achieve this.

## Grid Layout

In the example above, with one padding defining the space between components, and the other defining the page margin, we can leave all those details to the grid container. The container gets the following:

```css
.container {
	display: grid;
	padding: 0 4px;
	grid-gap: 2px;
	align-items: center;
	grid-auto-flow: column;
	height: 250px;
}
```

Now the interior components don't need padding.

Notice also how Grid supports `align-` and `justify-` properties that can do the work of centering and aligning, so we can lose the `11px` and `7px` `top` value altogether.

(Flexbox also has these alignment properties, but the support for `gap` is still limited, unfortunately.)

## Custom Properties

Any time that we still need to use specific numbers, we can replace them with CSS custom properties: `--page-padding: 4px` and `--gap-width: 2px`

Note: I think it's fair to be cautious with a statement like this, and to be conservative when applying this rule in practice. There are potential performance considerations when using CSS custom properties all over the place. But in my experience, the bottleneck in rendering a page hasn't been the CSS.

In keeping with this, we can keep the `250px` `height` as-is, because it's unique.

Similarly, `--page-padding` might be a better candidate for being a custom property than `--gap-width`, for example. If the gap between the components is unique, keeping it `2px` might be fine.

But what if, when it was originally conceived by the designer, the space between the components was designed to be half of the page padding? If so, you might want to preserve the relationship in case the page padding changes in the future.

You can use `calc` for this purpose:

```css
.container {
	display: grid;
	padding: 0 var(--page-padding);
	grid-gap: calc(var(--page-padding) / 2);
	align-items: center;
	grid-auto-flow: column;
	height: 250px;
}
```

Now we're down to just one magic number, and one  appropriately-named custom property. In my opinion, that's much easier to reason about and the intent of the code is clearer.

I found a similar article on Dev that goes even more in depth if you want to check it out: https://dev.to/adrianbdesigns/mastering-css-magic-numbers-2297

✌️