Why You Need to Refactor Your CSS

If you're doing it right, anything you build on the web is constantly evolving. No matter how much planning you do, you're going to need to refactor your CSS.

As Ethan pointed out in his popular Foundry post, naming your CSS classes can be hard. One of the things that can add to the difficulty is not having a clear view of the entire project when you get started. Even projects with copious amounts of planning will inevitably add new features or make changes as the project progresses.

An Example

To demonstrate this problem of naming things as our projects grow, let’s say our in-progress site has an articles section. We decide to create a simple “articles” CSS module (SMACSS) for our listing page using BEM naming conventions. Each article has a title, byline, image, and body text.

<article class="article">

 <h2 class="article__title"></h2>

 <div class="article__byline"></div>

 <img class="article__img">

 <div class="article__body"></div>

</article>
.article {}

.article__title {}

.article__byline {}

.article__img {}

.article__body {}   

Our CSS is very readable, and it’s clear how it relates to the content in our HTML. For small and simple websites, this is a perfect setup. However, as projects grow in both size and complexity, things can start to get a little messy.

Let’s say our client comes to us with a new request: they want to add a blog to their site. Blog post listings will have content fields and styling that is the same or similar to articles. We’ve already done a fair amount of work styling our articles, and since blog posts will look the same or similar, we don’t want to start our styling from scratch but instead want to re-use the styles we’ve already written.

What We Usually Do

When Blog Posts are the Same as Articles

If our blog posts are exactly the same as articles, we might simply re-use the article classes exactly as-is so that our blog posts’ HTML uses all our article module classes.

<article class="article">

 <!-- Article goes here -->

</article>
<article class="article">

 <!-- Blog post goes here -->

</article>

This is great in that it reduces the amount of CSS we need to maintain, however, now we’ve added some confusion to our names. Our names are now lying to us. We expect our CSS classes to be styling articles, but now they style blog posts as well. Our CSS cannot be trusted, and when new team members joins this project, they won’t have much confidence in knowing how styles are being used.

When Blog Posts are Similar to Articles

If our blog posts are not exactly the same as articles, but are similar, we might go down the path of copying our article CSS rules, renaming them with a base of .blog-post and then tweaking the styles as needed. This a fast way to get the job done, but we’ve just unnecessarily bloated our stylesheet with duplicate rules that do mostly the same thing.

/* Articles */

.article {}

.article__title {}

.article__byline {}

.article__img {}

.article__body {}



/* Blog Posts */

.blog-post {}

.blog-post__title {}

.blog-post__byline {}   

.blog-post__img {}

.blog-post__body {}

Face Your Fears

I think the primary reason we choose one of the two options above, besides just saving time, is that we are afraid to change any of our existing CSS.

CSS is brittle. There are things we can do to make our styles less brittle, but the nature of CSS and the current state of browser standards means that our styles are much more likely to break than than other kinds of code. So even if we might be very comfortable refactoring our Ruby, Javascript, or PHP code, we hesitate when doing the same with our CSS.

That’s not a good excuse. We need to get over our fear of breaking things and write clear, concise, and maintainable styles. And that means that as our projects grow, we sometimes need to refactor.

In fact, our fear of refactoring our styles is not only going to make a mess of our current project, but it’s going to prevent us from becoming better developers and writing more robust styles in the future.

What We Should Do

Revisiting our example with a mindset to refactor, let’s look at our 2 options again.

When Blog Posts are the Same as Articles

If the styling of blog posts is exactly the same as articles, then, instead of reusing the article class names, let’s reuse the styles by simply changing the base name to something more generic. In this case, the term “post” might be a good option. This involves renaming our styling rules and updating the HTML for articles. Done and done. Pretty simple. Low risk. No big deal.

/* Articles and Blog Posts */

.post {}

.post__title {}

.post__byline {}    

.post__img {}

.post__body {}  

When Blog Posts are Similar to Articles

If the styling of blog posts is similar to articles but has some variation, then we might consider refactoring with an additional variant class.

Using BEM naming conventions we could create a base module called .post for both articles and blog posts. Then for articles, we would add a variant called .post—article, which would allow us to tweak our base module as needed for that variant.

<article class="post post--article">

  <h2 class="post__title"></h2>

  <div class="post__byline"></div>

  <img class="post__img">

  <div class="post__body"></div>

</article>
/* Base styles for all posts */

.post {}

.post__title {}

.post__byline {}    

.post__img {}

.post__body {}  


/* Article post variant tweaks */   

.post--article .post__title {}

Sass 3.4 Makes Refactoring Easier

The latest version of Sass can make this kind of refactoring even easier with changes to how the parent selector symbol now works when nesting styles.

.article {

   &__title {}

   &__byline {}

   &__img {}   

  &__body {}  

}

This use of the & symbol would have generated an error in Sass 3.3, but now you get styles that look like this:

.article {}

.article__title {}

.article__byline {}

.article__img {}    

.article__body {}  

If you make use of this new feature, renaming the base name of any module means changing just a single line in your stylesheet. Bam!

Become Comfortable Refactoring Your CSS

Modifying our existing styles can be a bit scary, but in order to keep our projects maintainable over the long run (and make ourselves better developers), we need to face our fears and learn to become comfortable regularly refactoring our CSS.