How To Develop Scalable And Maintainable CSS

Last weekend I came across more ideas about our changing css best practices, specifically a presentation by Andy Hume and an article from Nicolas Gallagher, both of which offer additional thoughts to what I’ve been talking about these last few weeks.

I wanted to discuss each a little and more importantly point you to both in case you haven’t seen them. Some of you have also provided even more for me to take in on the subject and I promise I’ll get to those links as soon as I can.

Andy’s presentation, CSS For Grownups: Maturing Best Practices, (found via Jeremy Keith) builds on the work of Nicole Sullivan with OOCSS and Jonathan Snook with SMACSS.

His talk mainly looks at moving from current descendent selector practice toward a more modular class based approach. The presentation is a 50 minutes long and I recommend listening while following along with the slides, which I’ve also included at the bottom of this post.

Nicolas’ article, About HTML semantics and front-end architecture, is more focused on html semantics and dispels the notion that all these class names are unsemantic. If you’re struggling a little to move toward classes due to worries about making your html less semantic I think his post will convince you that you don’t need to be worried.

The word Think spelled out in boards attached to a gate, with the K about to fall down

Why Rethink CSS Best Practices?

It’s relatively simple to learn the syntax and basic use of css. What’s not so simple is to create scalable and maintainable css systems. Many of the best practices we’ve developed over the years aren’t helping. If anything they’re leading us to develop less scalable and maintainable stylesheets.

This gets masked at times if you only work on smaller sites. With fewer instances of difficult to maintain code, you can usually overcome the maintenance problems with a little extra effort, but the issues are still there.

Even if you don’t currently work on large sites or plan to, you should still rethink best practices and improve your systems. Small sites grow larger. Personal goals change. New technologies and techniques spring up all the time and we should be prepared.

The main ideas behind all this rethinking of best practices is

  • To create us more maintainable css
  • To help our css coding practices scale

Let’s consider a couple of ways toward these goals, decoupling our html and css, and better choice of class names.

Slide showing selector as .social li:nth-child(1)

Decoupling HTML and CSS

Andy’s talk was in part about how we can uncouple css from html so our styles are less dependent on our structure. Less coupling leads to a more maintainable site. I mentioned this concept in my posts about OOCSS and SMACSS.

At first glance it seems like adding classes to html increases coupling due to the added markup, but the opposite is actually true. Coupling is increased the more dependent we are on a specific html structure. Jonathan Snook referred to this as the depth of applicability. The greater this depth, the greater our html and css are coupled.

Unfortunately our best practices the last few years have been increasing coupling even as we thought we were decreasing it.

Compare the images from Andy’s slides above this section and just below. In both the css is simple. It’s adding a background image to each of three different social buttons. In the slide above the selectors take the form .social li:nth-child(x).

When this nth-child selector is used, structure and style are highly coupled. Changing the order of the html so the Facebook button comes before the Twitter button requires a similar change in the css.

On the other hand the slide below shows similar css, except the nth-child selector has been replaced by a class in the form .social .twitter. This requires that extra code (the new class) be added to the html, but now you can rearrange the order of the buttons in the html without having to make any changes to the css. There’s less dependence on the specific html structure.

Slide showing selector as .social .twitter

Later in the presentation Andy talks about different layers of css. He offers 4 in his example without suggesting these are the only 4.

  • Document
  • Base
  • Module
  • Layout

The concept should be familiar if you’ve looked through the SMACSS documentation. Andy’s idea is that a block of css should only affect one of these layers. He shows a variety of css styles and which layers they affect. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
.promo-box {
  color:red;
  background: black;
} /*  module only */

.promo-box h3 {
  font-size:1.2em;
  text-transform: uppercase
} /* module and document collide */

.promo-box h3,
.promo-box h4 {
  font-size:1.2em;
  text-transform: uppercase
} /* continuing to add more document collisions */

.promo-box .promo-box-h {
  font-size:1.2em;
  text-transform: uppercase
} /* module only with the second class expanding on the first */

The two blocks in the middle tie things to the html structure by including the hx tags. You can imagine how this can quickly get out of hand as you add more headings or other elements. The combination of the first and last blocks of css above are best. Each affects only one layer of the css, in this case the module layer, and it makes the resulting css much more manageable.

Andy continues with an example of headings alone. I’ll let you check the presentation and slides for the details, but the gist is he transforms the typical hx styling we do to a class based approach.

1
2
3
h1 { font-size: 3.0em; } /* initial hx selector */
.h1 { font-size: 3.0em; } /* changed to a class named after the hx tag */
.h-headline { font-size: 3.0em; } /* changed to a class name that better describes it's purpose in the design */

He walks through lists in a similar fashion moving the css from ul.product-list li to .product-list li to .product-item.

Imaginary board game Semantopoly: The semantic and open web themed game that will get you sued by Hasbro

Semantics and Class Names

One of the best practices the industry is trying to change is to avoid classitis at all costs. We’ve been taught that classes are unsemantic and we should add as few as we have to. This isn’t true.

Nicolas’ article focuses on class semantics. He says there are different types of semantics. We tend to think content driven semantics when talk about the subject, but there are also agreed upon global semantics such as microdata.

He makes 4 points about semantics.

  • Content-layer semantics are served by html elements and attributes
  • Class names impart little semantic information outside of agreed upon standards
  • The primary purpose of a class name is a hook for css or javascript
  • Class names should communicate useful information to developers

He tells us that class names (other than the agreed upon) offer no semantic information to machines by default, however when chosen well they do communicate useful information to developers and so have semantic value. Because of this class names are always semantic since they always carry some meaning with them.

1
2
3
4
<div class="news">
  <h2>News</h2>
  news content
</div>

The above class name is a bad choice because it adds no additional meaning we couldn’t get from the content itself. It also ties the class name to the content and so can’t change easily. For example it wouldn’t make sense to present recent comments inside of a div with a class name of news.

Once again coupling has been increased, reducing scale and maintainability.

Our goal should be to develop reusable components that can contain a range of content types. The most reusable components are those with class names independent of the content they hold. Nicolas talks further about how we can make css components more reusable and combinable.

  • Javascript specific class names — (js- prefix) can help reduce the risk that changes break Javascript
  • Single-class css pattern — styles get defined on multiple classes so only one class needs to be added to the html
  • Multi-class css pattern — styles kept more modular and multiple classes are applied to the html (preferred approach)
  • Structured class names — naming patterns to make presentational relationships more understandable

I’m only pointing out a few highlights here and skipping much of the detail. If you’ve been hesitant to use more classes thinking they’ll make your html less semantic, I think the article will convince you otherwise as well as offering some good advice for how to go about naming your classes.

It’s definitely worth a read.

A rusty lock securing a rusty green gate

Summary

Most of us have been following the same set of best practices for years. I certainly have. Unfortunately many of those practices were based on incorrect assumptions about coupling and semantics.

We’ve been making our html, css, and even javascript less maintainable for years. We’re used to it and have found ways to work around the problem or we work mainly on sites small enough to hide some of the issues, but those issues are there nonetheless.

It’s time we question these flawed practices and those questions are leading us to ideas like OOCSS, SMACSS, and css preprocessors.

One last time let me encourage you to listen to Andy’s presentation and follow along with the slides as well as to read Nicolas’ article. I’ll get to the presentations and articles some of you have pointed me to as soon as I can.

Download a free sample from my book, Design Fundamentals.

19 comments

    • Thanks Nicolas. I really enjoyed your article and think more people should read it.

      My bad on spelling your name wrong. Looks like I started spelling it right and then somewhere along the way picked up an h. All fixed.

  1. Two things:

    1/ I agree with most of the example in the beginning of the article. I still detest the ‘OOCSS’ name not because of the ‘OO’ classification, but because it has everything to do with proper htmling and applying the css accordingly. Coming at it from a css angle makes little to no sense and emits the wrong ideas.

    2/ I strongly disagree with the section on semantics (the news example). Of course the class “news” adds semantical meaning that can’t be find in the content. It tells other languages that hook into the html code that that’s a news block. Sure enough, humans may understand (through the title and structure of the block) that it’s news, but programming languages sure won’t be able to make the difference. Even if you’d style components like news and events exactly the same way, they still need differentiating classes because _they are different_ from each other. As long as your html is build like that, you don’t need all that OOCSS hype to make sure your css is scalable and maintainable.

    • I’m not sure I understand your objection to the OOCSS name then. I get why people don’t like the OO part, but html and css work together so I don’t see why it should be an issue to come at things from the css side.

      I understand what you’re saying about semantics, however keep a few things in mind. Machines aren’t reading every class name in your html to gain information. Other than agreed upon stuff like microformats they aren’t paying attention to your class names. Given that you’re writing most class names for yourself and other developers. In that case adding class=”news” to what’s obviously a news section, doesn’t offer any additional information. It also ties you into always keeping that section filled with news.

      I don’t think a news and events section need unique class names for the purpose of styling them. It makes sense to give them unique IDs if you’re going to hook into them with javascript, but if the presentation is the same there’s no need to have unique identifiers, which makes things less scalable.

      You certainly don’t have to use OOCSS or agree with some of what’s being said about it and the greater use of classes in general, but I’d hardly call any of it hype. There are some legitimate questions being raised and some good ideas for new solutions. Calling it hype suggests your mind was made up prior to taking the time to look into any of these ideas.

    • I used class names like news and then I was either using this class for non-news blocks, or had to repeat code, which is not efficient.

      Even something like .foo, .bar{…} would not help as all the .foo related rules at top of css file and .bar related at bottom, so I had hard time memorizing which one is where. It’s tiresome.

  2. Part of future-proof coding is thinking of what your side might look like tomorrow. Even though news and events may be styled the same today, there is good reason to believe they’ll be styled differently tomorrow. They are two different things.

    Google might not be picking up my class=”news”, but other developers (css people, javascript people) will. I usually just write the html, so I make sure they (and everyone else) has all the correct hooks they need to do their job. Most of the times, I don’t even have a design when I’m writing html.

    See, html is the core of everything, the rest is just make-up. So no, coming from the css side is not good enough, focus on your html and the rest will follow. I agree that we need better ways to handle our css development, but hacking your way into html isn’t going to solve much.

    As for calling it a hype, that’s just because people are running with it without paying much attention to the other best practices (unrelated to html). The past has proven that people always come back from that, so yeah … hype. Not only that, but the concept is so horribly advertised that from the get-go people are misinterpreting the concept left and right (including me no doubt).

    • All fair points.

      In regards to future proofing I agree you want to future proof, but there’s no evidence that Google or anyone else will ever look for class=”news” If they indicated they would be looking for it then sure add it now, but at the moment it would just be a guess. I wouldn’t call that future proofing. It’s just as likely they’d look for headings of News.

      I agree that html is the core of everything when it comes to building websites, but everything works together. I think it’s more about looking at how html and css work together.

      I understand where you’re coming from with hype, but I still disagree. I think what’s happening is people are taking notice of the idea of using classes more and so you see it talked about a lot. I don’t think it’s people just jumping on the bandwagon. It’s people taking a look and deciding these are good practices.

      The name OOCSS probably wasn’t the best idea since OO is already well defined. I do understand why it’s called OOCSS though. The objects here are visual objects. Not the best name, but it’s only a name. It’s the concepts that are more important.

  3. You don’t need to add a class=”news” for Google or other search engines, we have microdata for that now. When I say future-proof, I mean redesigns (be it from scratch or incremental updates). Since news and events are two different things altogether, whoever comes after you (css, javascript, other scripting languages) should be able to differentiate between the two. Maybe not now, because the design and/or functionality is the same, but in the future, because elements that aren’t the same usually have their own set of peculiarities and being able to differentiate them can only work in your favor in the long run.

    You say that the objects here are visual objects, that’s exactly what I don’t like about oocss. html is not about visual objects, it’s about defining what a particular block “is” or “represents”. If you do it well, you can target every logical unit on a webpage, from there on you have all the flexibility you need for writing good css and javascript.

    If you want to streamline your css into repeatable blocks, languages like less/sass are on the right tracks with mixins. It does the same, but without hacking into your html, meaning that site updates will limit themselves to css updates rather than html and css updates. You save a lot of time that way.

    So either you litter your html with .moduleBlock for news, or you write:

    .moduleBlock {/* styles go here */}
    .news, .event {.moduleBlock;}

    I’d go for the second option.

    • As far as future proofing doesn’t it then make more sense to not use class=”news”? The name locks you into always using news in that block. Should you want to change the content it would mean changing the html. You could argue that no matter what you name the class, it’s possible you’ll want to change it in the future, which is true.

      However, it also means that calling it news isn’t any more future proof than any other name. In that case a name other than news is imparting more meaning since the heading already tells us the content will be news.

      html may not be about visual objects, but design is. There’s a lot that goes into a website. We can’t only look at one thing and make all our decisions based on that one thing, even if that thing is html. We have to look at how all these technologies work together and how we develop more maintainable websites, not more maintainable html.

      I’m leading up to css preprocessor with a lot of recent posts. I think they add a lot to this discussion. I don’t think they solve every problem though. Ideas like OOCSS and SMACSS offer a lot.

      Out of curiosity have you look in depth at either OOCSS or SMACSS? I know the use of the OO terminology turns you off, but have you looked at the underlying ideas? I’m not saying you have to use either. Just asking if you’ve given either a chance.

  4. If you want to substitute news for something else, you chose a different html component. You’re not just planning on inserting any content in a random div with a certain style? You write your html for logical components, then you apply these throughout your site where needed. It’s how most CMSes work too, especially when talking about structured content.

    It’s a very sold concept and when done well both css, javascript and whatever other scripting language you can come up with can handle everything it needs. If tomorrow the analytics guy tells you he wants to track how many people are clicking the news heading links, you can simply write a little js function and leave the html as is. You can’t do that when working with visual blocks, because there is no obvious connection to the content. You may have your block heading (News), but when that changes to “See the latest” you’re pretty much out of luck.

    I did look into OOCSS and found nothing there I couldn’t easily accomplish using mixins. It might be a tad (not much) more verbose, but that doesn’t weigh up to the html rape OOCSS requires.

    As for SMACSS, I looked into that a long time ago but I just don’t agree with the proposed structure. I group css based on logical (html) components and existing variants (which is the oocss principle but applied to html). All these components I group into larger logical groups (like base frame, headings, navigation elements, …). I’ve been doing that for years, all relevant css is nicely grouped together and very easy to find.

    It needs a little cleaning up as I just switched to responsive, but this is what my css files look like:
    http://www.onderhond.com/style/onderhond-responsive.less

  5. I just don’t get people who trying to save some KBs in html while it’s only fraction of traffic — most of traffic are images.

    And yes that was my problem too, before I realized how I was wrong.

    Overoptimizing HTML but I had to change my CSS constantly and adding redundant rules that overwrite or copy each other.

    • I think every little bit helps. I’d certainly optimize images and http requests before worrying about some extra space in my html, but you’d be surprised how much space you can save removing all that space.

      At this point removing the space is easy anyway. You can minify your files before uploading to the server. That way you have the unminified version to edit on your computer and the minified one on the server.

  6. Sass 3.2 has almost become a real programming language.

    Consider the following design pattern :

    // Placeholder primitives
    //————————————————————————————————-
    // Placeholder primitives allow for optimal code reuse while positively impacting code readability compared with native CSS code.

    // This sets a default border style without actually drawing the border
    %border-init {
    . . . . .border: 0 solid black;
    }

    // Draw the border
    %border-1px {
    . . . . .border-width: 1px;
    }

    // Change the border color to red

    %border-red {
    . . . . .border-color: red;
    }

    // Change the border color to green
    %border-green {
    . . . . .border-color: green;
    }

    // Float to the right
    %float-right {
    . . . . .float: right;
    }

    // Component placeholders
    //————————————————————————————————-

    // Sets default styles for the button element and changes the default behavior with modifiers. Each type of style is its own component placeholder and references primitive placeholders

    // Defines borders for buttons
    %button-borders {
    . . . . .@extend %border-init;
    . . . . .@extend %border-1px;

    . . . . .&.attention {
    . . . . .. . . . .@extend %border-red;
    . . . . .}

    . . . . .&.submit {
    . . . . .. . . . .@extend %border-red;
    . . . . .}

    . . . . ..sidebar }

    // Defines floats for buttons
    %button-floats {
    . . . . .&.submit {
    . . . . .. . . . .@extend %float-right;
    . . . . .}
    }

    // Button component
    //————————————————————————————————-
    // Combines different component placeholders for the button

    button {
    . . . . .@extend %button-borders;
    . . . . .@extend %button-floats;
    }

    Output :

    button {
    . . . .border: 0 solid black; }
    button {
    . . . .border-width: 1px; }
    button.attention, button.submit {
    . . . .border-color: red; }
    .sidebar button {
    . . . .border-color: green; }
    button.submit {
    . . . .float: right; }

    • Thanks John. That’s pretty impressive. I can’t say that I’ve explored all Sass has to offer, but I’m learning and liking what I do learn. It’s really made development easier for me.

      Every so often I need to work directly in a css file and I find I just don’t enjoy working in it as much. I reach for Sass things only to find I can’t use them directly in the css.

      I would like some of what’s in Sass or Less or whatever preprocessor to make it’s way into css directly. Mostly to be able to make changes via Javascript. I’ve found myself wanting to interact with a Sass variable in Javascript, but as far as I know you can’t do that.

    • Thanks Carlos. I’m still trying to work out the best way to handle classes and ids. I experiment on different projects, but I still haven’t settled on anything consistent.

      Thanks for the link. I do read Jens blog, but I think I started after that guide. I don’t remember seeing it before.

Leave a Reply

Your email address will not be published.

css.php