From my perspective, there are a couple of important things to consider when writing CSS: how readable the code is and how quickly I can navigate it. One might argue that these two mean more or less the same thing. However, I think they differ slightly. In this article, I’ll focus primarily on the readability aspect of it, even though readability and navigation are closely related.
I don’t know about you, but there are certain times when I open a CSS file and my brain goes straight to static. I can’t even… I don’t know where to start.
That is a usual feeling when you are dealing with some unknown code. That is OK. However, I find that feeling much more frequent when dealing with CSS. Sometimes it just feels as if we smashed a bunch of key-value pairs together until it gave the results that we were looking for. I think you know what I’m talking about. Let me be specific.
.awesome-component {
width: 100%;
padding: 20px;
border: 1px solid gray;
border-radius: 4px;
margin-bottom: 1rem;
overflow: hidden;
height: 142px;
position: relative;
transition: height 0.3s ease-in-out;
margin: 0 auto;
background-color: crimson;
}
That is not a lot of code, but from the get-go, it is quite hard for me to understand what it does. To do that I need to read line by line to interpret the declarations and how they relate to each other. Sure, some of them are quite straightforward to understand, but still, it takes quite a bit of time to get the whole picture.
Code like that is usually the result of a few iterations, done by different people over an unknown period. That kind of code is what I like to call organically composed CSS. It is the result of the natural process of writing code that eventually works. It is not bad necessarily. It works. Yet it makes you parse the entire thing in your head to understand it.
An alternative to writing CSS code without worrying too much about structure is to sort the properties alphabetically. Let’s see how the example above would look like if we did that.
.awesome-component {
background-color: crimson;
border-radius: 4px;
border: 1px solid gray;
height: 142px;
margin-bottom: 1rem;
margin: 0 auto;
overflow: hidden;
padding: 20px;
position: relative;
transition: height 0.3s ease-in-out;
width: 100%;
}
It feels slightly better to read and we can find properties more easily by simply following their alphabetical order. Now let’s put them side-by-side.
/* organically composed */
.awesome-component {
width: 100%;
padding: 20px;
border: 1px solid gray;
border-radius: 4px;
margin-bottom: 1rem;
overflow: hidden;
height: 142px;
position: relative;
transition: height 0.3s ease-in-out;
margin: 0 auto;
background-color: crimson;
}
/* alphabetically sorted */
.awesome-component {
background-color: crimson;
border-radius: 4px;
border: 1px solid gray;
height: 142px;
margin-bottom: 1rem;
margin: 0 auto;
overflow: hidden;
padding: 20px;
position: relative;
transition: height 0.3s ease-in-out;
width: 100%;
}
Neat! That’s some improvement. One could even think about a plugin or a linter process that makes sorting alphabetically automatic whenever you save the file. Still, I think we could do better.
I strongly believe that code is mainly for humans to read and interpret. There are exceptions, of course. Sometimes code needs to be in a certain shape to assert performance or due to technical requirements. Nevertheless, that is very rarely the case when writing CSS.
In one way or another, while reading CSS, we group declarations into our heads to understand their purpose and relations. We slot and store them as we read the code to make sense of the expected (or not) output that it yields.
Because of that, I like to take the overhead off my brain and put it into writing. Let’s take the same example as before and apply this concept.
.awesome-component {
position: relative;
overflow: hidden;
width: 100%;
height: 142px;
margin-bottom: 1rem;
margin: 0 auto;
padding: 20px;
border: 1px solid gray;
border-radius: 4px;
background-color: crimson;
transition: height 0.3s ease-in-out;
}
What do you think? Can you feel it? Now related properties are following each other. The width
and height
are both related to the size of the component. Just like margin
and padding
are related to spacing and border
and border-radius
to the shape. They sit together and keep each other company helping us interpret the code.
“White space is not your enemy. It is an essential component of effective writing, providing the much-needed breathing room for clarity, emphasis, and comprehension.” ― Ellen Lupton
Sometimes I think we developers become a little afraid of whitespace. We are so used to minifying and compressing our code that we forget that whitespace can be a very powerful tool. It can help us emphasize and separate things in a way that words alone can’t. Facilitating the flow of reading and aiding understanding.
Let’s take a look once again at the same example, but now emphasizing the groups and relationships by using whitespace.
I think this reads much better in comparison with our previous samples. Now it is a lot easier to scan and understand the relationships between the properties.
There is more thought behind that though. Groups are also sorted by their “impact”. Now, that bit is slightly more subjective. One could say that the background color or the transition properties are more important than the overflow.
My take on this is that you have to figure that out and follow what makes sense to you. I like to see it as a ranking of impact. The more impactful the property is, the higher it goes.
Alright, finally Let’s put everything side-by-side.
/* grouped and white-spaced */
.awesome-component {
position: relative;
overflow: hidden;
width: 100%;
height: 142px;
margin-bottom: 1rem;
margin: 0 auto;
padding: 20px;
border: 1px solid gray;
border-radius: 4px;
background-color: crimson;
transition: height 0.3s ease-in-out;
}
/* alphabetically sorted */
.awesome-component {
background-color: crimson;
border-radius: 4px;
border: 1px solid gray;
height: 142px;
margin-bottom: 1rem;
margin: 0 auto;
overflow: hidden;
padding: 20px;
position: relative;
transition: height 0.3s ease-in-out;
width: 100%;
}
/* organically composed */
.awesome-component {
width: 100%;
padding: 20px;
border: 1px solid gray;
border-radius: 4px;
margin-bottom: 1rem;
overflow: hidden;
height: 142px;
position: relative;
transition: height 0.3s ease-in-out;
margin: 0 auto;
background-color: crimson;
}
There is no definitive solution for organizing and maintaining CSS code. The approach I rely on in my projects involves grouping and utilizing white spacing. While it is not flawless, it effectively serves my needs.
However, I strongly believe that it is better to choose a specific approach in CSS rather than not having one at all, as things can easily become chaotic. Having a system in place that suits both you and your team is crucial, and maintaining consistency is equally important. Most importantly, you need to start somewhere, and it’s always possible to iterate and improve upon your initial approach.
I hope this article was helpful to you and that took something from it.