Two tips to keep your CSS simpler
Tags: css, clean, html, structure
Published: 2021-05-07 05:50:49

---
title: Two tips to keep your CSS simpler
published: true
description: Two simple but tricky to apply tips on keeping the CSS code cleaner
tags: css, clean, html, structure
//cover_image: https://direct_url_to_image.jpg
---

One of the approaches to write **clean code** is to also write **simple code**. Meaning — do your task in a way that is easy to implement, has fewer things that could break, and overall is easy to understand by other developers.

But how does that happen? Well, while *achieving greatness* might not be what we are going for, trying to simplify things most likely is 🙂

## Goal #1 — clean up your code from unneeded rules

One of the easiest simplifications you can use is to **not** write code. Or if you already wrote it to delete it. Which one? Welp, the one that **does nothing** in particular. Here is an example:

```css
...some-selector p {
	color: black;
	font-size: 1em;
	margin: 1em;
	line-height: 1.7;
}
```

Just looking at this snippet without knowing what is going on around it is not enough to decide what to delete. But, for the sake of the example, let's consider **the most common use case** that you might encounter and see what can we do with the rules:

```css
...some-selector p {
	color: black;  /* Inherittted? */
	font-size: 1em; /* That is default */
	margin: 1em;
	line-height: 1.7; /* for consistency, we might want this set to the parent */
}
```

- If we never set `color` , then it's inherited as black, so there is no point in defining it here.
- `font-size` is the same, unless you changed the font size, there is no point in writing its default value. This often happens while people are debugging, trying to visualize, or changing values while testing.
- `line-height` is slightly different — if you want visual consistency, often you'd like to have a specific font size for regular content and for low character-per-line content. If you define line-heights in many places, keeping things consistent could be a problem.

So, with cleaning up the above, it's possible to end up with **the same result**, but code that looks like this:

```css
...some-selector p {
	margin: 1em;
}
```

We just overwrite the margin sizings. And this could be further simplified if that margin is consistent across the website - if that is the case, we can set it to the top root level just as `p { margin: 1em }` without the `...some-selector` wrapper around it.

**Other code that can be cleaned** is generally something along the lines of:

- `div` with `width: 100%` that doesn't have any other rules or parents that would redefine it
- `height: 100%` for regular content (like a `<p>` tag inside normal `<div>` tag). That height does nothing.
- Complex styles for simple results, but this is harder to showcase or explain — many times there are simpler ways to achieve a design
- Reduce depth — in vanilla CSS it's deleting the parent, in Sass, it's moving your selectors a level or two up.
- Rules that do nothing in particular (could be any)

## Goal #2 - Style only what is needed

Well, this one sounds obvious, isn't it? But we quickly forget it and just *go with it*, it's not like there is some price to how much code is written, right? Well, there is — time and money come into play when maintaining a medium to large codebase becomes sluggish and people stay away from it.

One of the ways to reduce this complication is to **really think about what has to be styled**. How are components connected and which component styles what? Here is an example:

```css
/* Demo component that does one thing only. */
.card { color: red; }
.card .card-title {font-size: 2em}

/* A <section> element right in the website wrapper */
.section-welcome {padding: 5em 0;}
```

If we need a card to be **blue** when it's inside the **`.section-welcome`** element, we have two realistic ways to do it: One is to follow the requirement 1:1 and write `.section-welcome .card {}`, which will overwrite the `.card` styles for us. The other approach is to write a **modifier** for the `.card` element like `.card--secondary` for example.

In this example, we **can decide** which of the two approaches is correct by looking into the design and the requirements. If the welcome section is very specific in its design (something unique for the website) and the `.card` element has to look different **only there**, then it's understandable to nest it inside the `.section-welcome`.

If the `.card` element changes are less specific and could be reused elsewhere, then it's best to have a modifier. A modifier is an extra class you can set to the component, which will style it and its children differently.

**When you might want to use a Modifier:**

- When the visual change is common enough that it can be used elsewhere in the application or website like color, size, spacing changes etc.
- When you can find it used elsewhere in the website. Note* if there are **minor** differences like 4px smaller padding or some opacity to only one element and consistency isn't what your designer needs but instead 1:1 results, then you can mix modifiers with nested selectors.

**When you might want to nest your selector:**

- When there is only one change to a component on the whole app/website for a specific wrapper.
- When you have many wrappers that slightly change a component in a different way. If you were to use modifiers, you would struggle to name them and you'd notice that you can't reuse them.

Some of the tips above are derived from **bad practice in design** - inconsistency, but in the real world, you will be bombarded with all kinds of scenarios — time limitations, bad designs, unrealistic expectations, difficult team members, lack of testing, change of directions and requirements, browser support that requires hacking, the editing experience (not just static code), backend team changing markup or forgetting a class (modifiers especially) and more. So, it takes experience in all of these problems to come up with the **least problematic** approach and apply it.

Overall, each situation might require you to think for a minute on the best approach. **Don't forget you can refactor code!** It's a major reason why big projects get hard to maintain and grow with bad structure — even if you think well of it, put a good architecture, when problems like the ones described above come up, we as developers might often forget things like "If you hack something *now*, come back to refactor it *as soon as possible".*