Pothibo

Restrict use of ids and classes

The last time I wrote about CSS, I talked about a way of writing that I thought was different than what others would write. Some people got it, some didn't. Reading my post again, I feel that what I wrote was all over the place because my mind was still not set on how I wanted my CSS to look like. This made me think that maybe I should start writing rough thoughts here and refine my ideas publicly as I experiment with them. So, here it is.

Today, I want to talk about CSS classes and ids. I think we're using them too much. There's so many selectors out there, to me, it's like if I was using only addition and subtraction in maths.

Most of the time, CSS is broke down into three pieces:

  1. Blocks;
  2. Elements;
  3. Modifiers.

This is BEM and I believe this is a great approach. However, BEM is often focus on CSS classes exclusively. For example, if you look at the demo, the CSS looks like this:

main.css
.button { display: inline-block; border-radius: 3px; padding: 7px 12px; border: 1px solid #D5D5D5; background-image: linear-gradient(#EEE, #DDD); font: 700 13px/18px Helvetica, arial; } .button--state-success { color: #FFF; background: #569E3D linear-gradient(#79D858, #569E3D) repeat-x; border-color: #4A993E; } .button--state-danger { color: #900; }

With the matching HTML:

index.html
<button class="button"> Normal button </button> <button class="button button--state-success"> Success button </button> <button class="button button--state-danger"> Danger button </button>

There are a lot of repeating button keyword in that HTML and I can assume that button won't look the same throughout the application. So what I have here is something highly specific.

So how could I change that code to do the very same thing while increasing readability?

A real example

Let's create a simple HTML page with three different buttons:

  • A sign in button in the application's header;
  • A read more button at the end of each excerpt;
  • A subscribe button in the body.
index.html
<html> <body> <header id='HomeHeader'> <h1>Welcome</h1> <a class='Button'>Sign in</a> </header> <main> <ol> <li class='PostExcerpt'> <p>Lorem ipsum dolor...</p> <a class='Button'>Read more</a> </li> <li class='PostExcerpt'> <p>Lorem ipsum dolor...</p> <a class='Button'>Read more</a> </li> <li class='PostExcerpt'> <p>Lorem ipsum dolor...</p> <a class='Button'>Read more</a> </li> </ol> </main> <footer> <div id='Subscribe'> <h2>Join our mailing list</h2> <a class='Button'>Subscribe</a> </div> </footer> </body> </html>

Before I start with the CSS, here's one thing that you might have noticed: it seems like I arbitrarily change between ids an classes. Also, both ids and classes uses CamelCase.

It's not as arbitrarily as it seems, though. The idea is that unless you are certain that a block you define on a page occurs only once, you should use classes. What I'm going to try to do in the next projects is to default to ids and fallback to classes when a block occurs more than once on a page.

This means that I'll probably refactor my CSS from time to time as the DOM change. But to me, refactoring is a healthy process. So no worry there for me.

Now, here's the CSS that styles the three different buttons:

.Button {
  border-radius: 4px;
  display: block;
  text-align: center;
  text-decoration: none;
}

#HomeHeader > a {
  border: 1px solid #12d837;
  color: #12d837;
}

.PostExcerpt > a {
  background: blue;
  color: white;
  font-size: 0.8em;
  text-transform: uppercase;
}

#Subscribe > a {
  letter-spacing: 3px;
  background: #12d837;
  font-weight: bold;
}

With CSS, I want to use tag name as much as possible. This way, I can easily leverage CSS specificities. I also think, and I will have to test it more thoroughly, that it makes the whole CSS much easier to understand.

But sometimes, tag selector inside a block might not be enough. I might need a CSS class somewhere so the selector can select just a subset of the available elements inside a block. When that occurs, I will use a CSS class but won't be using CamelCase. This way, I'll be able to tell easily if a CSS class is meant as a block or just a filter.

Always start with a block

Even if sometimes it's easy to just go and write a CSS selector that starts with a filter class, I won't be doing that. Instead, I'll always start with a CamelCase selector (whether it's an id or a class). I think by doing that I'll have a greater chance to understand the meaning of the CSS I'm writing.

Use tag as much as I can

I know this one will rub people the wrong way. Tag selector in CSS is slow! But I don't care. I've used tag extensively and I have found that the speed difference was negligible. My JavaScript code is much more susceptible to slow my application down than CSS will ever be. So I rather write CSS code that I enjoy writing and also that I can understand and debug easily.

I'm starting this week with this process and, hopefully, I'll write more about it as I experiment and see what goes well and what doesn't.

Stay posted!

Get more ideas like this to your inbox

You will never receive spam, ever.