How to choose the right CSS properties
Tags: css, webdev, design
Published: 2022-01-05 15:10:16

CSS might seem very daunting. There are many properties to choose from, and it may sometimes look like it's not doing what you tell it to. Or, sometimes you find yourself thinking: "There is more than one way to do this in CSS". In this blog post I'll cover some of these scenarios, and help you understand how you can justify your CSS decisions.

## 1. Edge cases

In my opinion, the most important reasoning behind your CSS usage. If you find yourself in a situation where you have multiple CSS solutions, this should be your first thought. Think of scenarios that might not be included in the design, and how your CSS would react to those. Examples of edge cases include:
- What if the text in this element becomes very long?
- What if the user uses a smaller device?
- What if the user zooms in using the browser zoom?

Let's take for example: how to center a div.

```html
<div class="example">
  <div class="number">1</div>
</div>
```
```css
.example {
  border-radius: 50%;
  background-color: magenta;
  width: 40px;
  height: 40px;
  box-sizing: border-box;
}
```
The `.example` element is a magenta circle of 40x40. Say we want to place this `1` exactly in the middle of the `.example` div. You _could_ do this:
```css
.example {
  padding: 11px 16px;
}
```
Which works, and looks like this:

{% codepen https://codepen.io/Essej2/pen/WNZyGvq %}

Looks perfect! But now watch what happens if it's not 1, but 11 as a number:

{% codepen https://codepen.io/Essej2/pen/NWazRxV %}

Now the text is not centered in the div anymore! A different approach like Flexbox might be your preferred solution then:
```css
.example {
  display: flex;
  align-items: center;
  justify-content: center;
}
```

{% codepen https://codepen.io/Essej2/pen/zYEaKBN %}

Thinking outside of the box can help a great deal in deciding which CSS solution is the right fit, because it actually eliminates "wrong" solutions.

## 2. Browser support

The never-ending struggle of the front-end developer. Browsers all have their unique quirks and features! Or as we developers call them, bugs and inconsistencies. Taking browser support into account can be a deciding factor on which CSS properties to use. The main browsers to take into account are **Safari** and, to a lesser extent, **Internet Explorer 11**.

{% spoiler If you want to know more about why these browsers specifically, click here %}
Safari has a very different approach to development compared to Edge, Chrome or Firefox. They only release new versions every 6 months, and so bugs are always there for at least 6 months. [To read a more extensive rant on Safari, I can recommend this article.](https://httptoolkit.tech/blog/safari-is-killing-the-web/)


[Internet Explorer 11 is reaching its end of life very soon](https://blogs.windows.com/windowsexperience/2021/05/19/the-future-of-internet-explorer-on-windows-10-is-in-microsoft-edge/), and the whole development world will breathe a sigh of relief when it does. The browser has been ridiculously outdated for a while now, and new awesome features like CSS Grid, or Flexbox, were either not implemented at all, or implemented in their own way. This resulted in many inconsistencies when comparing your page in IE11 to for example Google Chrome.
{% endspoiler %}

For example, let's say you want to change the opacity of an element. You could use either of these two lines:

```css
.element {
  filter: opacity(0.5);
  opacity: 0.5;
}
```

The first way, using `filter`, actually performs better because browsers can use hardware acceleration. However, [it's not supported in IE11](https://caniuse.com/css-filters). So, if your users use IE11, you might want to avoid using `filter`. Alternatively, some browsers offer compatibility through the use of _prefixes_ like `-webkit-animation` instead of `animation`. Many projects these days use a form of [Autoprefixer](https://github.com/postcss/autoprefixer) to automatically do this for you.

Whenever you're in doubt about what CSS to use, you could check which approach works best in all browsers. Test your solution in Safari or Internet Explorer, or use [Caniuse](https://caniuse.com/) to check if something is supported in all (or enough) browsers. If there is a clear difference, you'll have your answer.

## Maintainability

From this point the reasoning becomes more subjective, and so I've stopped numbering them. Whatever floats your boat more.

What if someone has to come back to your HTML/CSS and made some adjustments? Will that person be able to understand what's going on in the ruleset? Can they easily amend some of the HTML without the rules becoming invalid? Keep in mind, this person could be you! Think of the future when you write your CSS.

For example, let's say your HTML structure looks like this:
```html
<nav>
  <button>Home</button>
  <button>Options</button>
</nav>
```
If you want your options button to be aligned to the right within the nav, you could achieve that like this:
```css
nav:first-child + * { 
  margin-left: auto;
}
```
And that would be completely fine! For now. If a developer comes back to this after a month or two and makes a slight tweak to the HTML, this CSS will not work anymore. 
Here's some HTML tweaking examples that break this CSS rule:

```html
<nav>
  <button>Home</button>
  <button>Blogs</button> <!-- Now this element is targeted -->
  <button>Options</button>
</nav>
```
```html
<nav>
  <div> <!-- This is now the first child, and it has no sibling -->
    <button>Home</button>
    <button>Options</button>
  <div>
</nav>
```
```html
<nav>
  <img class="company-logo" src="...">
  <button>Home</button> <!-- Now this element is targeted -->
  <button>Options</button>
</nav>
```

Furthermore, it is not very easy to read. Instead, you could do this:

```html
<nav>
  <button class="home-button">Home</button>
  <button class="options-button">Options</button>
</nav>
```
```css
nav .options-button { 
  margin-left: auto;
}
```
This CSS is much clearer to read (the `.options-button` in the `nav` should have space to the left). It is also unaffected if for example a wrapper `<div>` is added around the buttons, or if more menu items are added before it.

## Semantics

This is in my opinion the best way to settle 50/50 questions like: should I use `padding` or `margin`? Should the top element have `margin-bottom` or should the bottom element have `margin-top`? Let me explain what I mean.

Let's take as an example a button containing some text.
```html
<button class="example-button">
  <div>Click me!</div>
</button>
```
You could use either of these rulesets to achieve the same effect:
```css
.example-button {
  padding: 10px;
}

.example-button div {
  margin: 10px;
}
```
Result:

{% codepen https://codepen.io/Essej2/pen/mdBKrrG %}

But which of these rules make more sense? Is it more logical that the button should always have 10px of breathing room on the inside, or that the div inside the button always has 10px of breathing room on the outside?

A trick I like to use here is: _try to imagine there's another element in the equation_. In this case, maybe the button has an icon before the text. In that case, is it more important that the button has the padding, or that the text has the margin? Then it seems more logical that the button should have padding.

Let's look at another example:
```html
<h2 class="example-header">Beautiful header</h2>
<p class="example-text">Lovely bit of text</p>
```
Let's say we want to add 20px of space between these elements. Do you give the `.example-header` a `margin-bottom`? Or the `.example-text` a `margin-top`?

If we apply the same trick as before, we can for example imagine another paragraph before `.example-text`. Would you want the 20px space to be between the two paragraphs, or between the header and the first paragraph? By looking at it this way it makes more sense to add the margin on the bottom of the header.

## Less is more

Performance is important. Longer CSS means more bytes. More bytes means longer loading time. It's not the reasoning I use often, since the differences are often minimal and not as impactful as reducing your JavaScript code, but it's a valid reason to write `margin: 0 3px 6px 1px;` instead of spelling out each individual property.

## Conclusion

I hope this post will help you either make a decision on which CSS properties to use, or justify a decision that you've already made. I now leave it up to you to put these in your personal order of importance. Personally, I love semantics and I find myself often basing my CSS decisions on that rule, after checking for edge cases or browser support. However, I know preferences differ and I want everybody to write their CSS the way they want to. Just, keep this in the back of your mind 😉.