Consistent CSS Class Naming Convention

A follow on from where I discuss my BEM approach, here are some thoughts on how I name classes using consistent naming conventions.

Something that I think gets overlooked with class names is having consistent naming conventions for elements. For example, let's say we have a list:

1
2
3
4
<ul>
<li>List Item</li>
<li>List Item</li>
</ul>

Someone might come along and add classes such as:

1
2
3
4
<ul class="list">
<li class="list_item">List Item</li>
<li class="list_item">List Item</li>
</ul>

Someone else might name them as so:

1
2
3
4
<ul class="ul">
<li class="ul_li">List Item</li>
<li class="ul_li">List Item</li>
</ul>

Or, possibly:

1
2
3
4
<ul class="unorderedList">
<li class="unorderedList_unorderedListItem">List Item</li>
<li class="unorderedList_unorderedListItem">List Item</li>
</ul>

The list is endless! Over time if you're working on a project yourself, or especially so on a larger project with multiple people, these different naming conventions can become confusing over time.

To combat this, I'll document naming convention logic for the project. If the project has a Style Guide / Component Library, perfect! I'll add in comments alongside. If not, then README.md, or on a Wiki page for the project. If there is no documentation at all, then the first thing I'll do is create some. Documentation is paramount!

The documentation might look something like this:

1
2
3
4
5
6
7
8
9
10
// Any element in a component that is, or likely to be repeatable should be named 'item'
<ul class="list">
<li class="list_item">List Item</li>
<li class="list_item">List Item</li>
</ul>

<div class="myComponent">
<div class="myComponent_item">Item One</div>
<div class="myComponent_item">Item Two</div>
</div>

That's one example and you might thinking, "Ok, but why, what's the point?".

Let's dive into an example with more elements, I'd do something like:

1
2
3
4
5
6
<div class="hero">
<h1 class="hero_title">Hero Title</h1>
<h2 class="hero_subTitle">Hero Subtitle</h2>
<p class="hero_text">Hero Text</p>
<img class="hero_image" src="/hero_image.jpg" alt="Hero Image">
</div>

Someone else might come along and do something like:

1
2
3
4
5
6
<div class="hero">
<h1 class="hero_header">Hero Title</h1>
<h2 class="hero_headerOther">Hero Subtitle</h2>
<p class="hero_description">Hero Text</p>
<img class="hero_background" src="/hero_image.jpg" alt="Hero Image">
</div>

Multiply that example by 10+, or 100+ components and things can get widely out of hand with all manner of different names.

By setting a predefined set of logic and rules for naming consistency. And now, with each component structure following the same patterns I find helps with a number of issues.

Firstly, rather than having to think of a what an element should be called, you have documentation to guide you.

Secondly, when you become familiar with the naming conventions, there's less mental load trying to think of what it should be named, you already know and it becomes zen-auto-pilot like:

Ok, component, let's go. My New Component, ok, now what have we got here, a header, no, title, or is it? erm… yeah, header, ok what's next some more text, subtitle? second header, erm… ok a link, but is it a call to action, or? hmmm… time for a brew… ok where was I?, yeah clickable thingy… link, think that's sorted.

vs

My New Component, title, subtitle, text, link. Boom done!

Thirdly, I find that debugging becomes easier. If there's an issue with hero_title and the same issue lies with myOtherComponent_title, or I'd want to check against other similar code, doing a search for _title I'd quickly be able to compare title elements on other components.

Fourthly, something I haven't done yet, but I'd love to experiment with is automation.

Perhaps a node script that would help build out a component, for example something like:

1
2
// nc would be an alias for a 'New Component' script
nc hero header subTitle text image-big

The command, would take the first string, this would be the component name. Then the following strings would be elements. If we needed a modifier we could add a dash.

The command would then output the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// html
<div class="hero">
<h1 class="hero_title">Hero Title</h1>
<h2 class="hero_subTitle">Hero Subtitle</h2>
<p class="hero_text">Hero Text</p>
<img class="hero_image-big" src="/hero_image.jpg" alt="Hero Image">
</div>

// Sass
.hero {

}

.hero_title {

}

.hero_subTitle {

}

.hero_text {

}

.hero_image-big {

}

It could even create the files and output to a specified path for you. Then we have all the class names ready to add our styles, with a build step for production to minify the CSS and remove any that weren't used.

Taking this even further! Maybe there was also a .newComponent config file that looked something like:

1
2
3
{
"framework": "react"
}

With this specified, the output could add in requirements for a specific framework:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// jsx
import React from 'react';

const Hero = ({
title, subtitle, text, image, alt
}) => (
<div className="hero">
<h1 className="hero_title">{title}</h1>
<h2 className="hero_subTitle">{subtitle}</h2>
<p className="hero_text">{text}</p>
<img className="hero_image" src={`/images/${image}`} alt={alt} />
</div>
);

export default Hero;

Taking this even further, we could even then grab all of the names and turn them into emojis!

1
2
// nc would be an alias for a 'New Component' script
nc hero header subTitle text image-big --emoji
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// html
<div class="🦄">
<h1 class="🦄_🐠">Hero Title</h1>
<h2 class="🦄_🐡">Hero Subtitle</h2>
<p class="🦄_🐣">Hero Text</p>
<img class="🦄_🌈-☀️" src="/hero_image.jpg" alt="Hero Image">
</div>

// Sass
.🦄 {

}

.🦄_🐠 {

}

.🦄_🐡 {

}

.🦄_🐣 {

}

.🦄_🌈-☀️ {

}

Too far? 🤣


Like this post? Hire Me!