CSS structure & anti patterns (Part 2)

This Is Part 2, you may want to read Part 1 on CSS anti patterns first

How to structure your css.

This is not to say this is the perfect way to work. But it's the way I've been working for years and has really helped me. Inspired by others and by the book SMACSS.

Thinking in modules.

Modular design for me means to separate logical pieces of code for maintainability and reuse.

If everything you do is in one big file, no comments or anything separating parts, all code is very specific and cannot be easily re-used, then it'll be difficult to maintain.

Working in modules you'll find you work faster and more precisely: you'll become a ninja at making quick changes for the client and the client will love you, or at least you'll be happier with your own code.

Example time:

Here's some CSS maybe you've written before. Some text node colors, some buttons have a fancy style (I'll call that fancy-button for later), some text content areas with minor changes between them and a couple minor tweaks on a larger screen.

This will be a long code example but feel free to comment if you have any questions about it/

Original code / what not to do:

# File: site.css

h1 { color: #444444; }  
h2 { color: #444444; }  
h3 { color: #444444; }  
p { color: #000000; }

.header-search .button {
    background: orange;
    color: #FFF;
    padding: 1em;
}
.sidebar-filter #submit-button {
    background: orange;
    color: #FFF;
font-size: 20px;  
    padding: 1em;
}
#contact-form-button {
    padding: 1em;
}
.home-page-content {
  padding: 1em;
  *padding: 15px;
  border-top: 5px solid red;
}
.home-page-content h1 {
   color: red;
}
.about-page-content {
  padding: 1em;
  *padding: 15px;
 border-top: 5px solid blue;
}
.about-page-content h1{
color: blue;  
}

@media screen and (min-width: 35.5em) {
  h1, h2, h3 {
    border-bottom: 1px solid #CCC;
  }
  .home-page-content {
    margin: 0 1em;
  }
  .about-page-content {
    margin: 0 1em;
  }
}

To me, you can work with it, but it's not ideal, and as that grows it will get unmanageable. Lets separate it out to more modular files: (The following files would be included/imported into your site.css file)

I'll comment above each part with the file name, and then under it will be notes on what changed and why its better.

# File: base.css

/* ===== Base styles for site ===== */

/* --- main font colors --- */
h1,  
h2,  
h3 {  
    color: #444;
}
p {  
    color: #000;
}

/* --- default button style --- */
button,  
input[type="button"],  
input[type="submit"],  
.button {
    padding: 1em;
}

/* first breakpoint */
@media screen and (min-width: 35.5em) {
    h1,
    h2,
    h3 {
        /* add a clean border under headings */
        border-bottom: 1px solid #CCC;
    }
}

The above shows base styles for making the page, e.g. fonts, button styles etc..

Separating out the base styles like this helps you quickly find default style applied to all elements. It should be fairly simple, anything more complex should be it's own module or layout file.

# File: modules/fancy-button.css

/* ===== fancier designed buttons ===== */

.fancy-button {
    background: orange;
    color: #FFF;
}

/* --- fancy button mods --- */

/* larger text version (could be abstracted further) */
.fancy-button-large {
    font-size: 160%;
}

This module for the fancy-buttons assumes you have access to change the HTML, if that's not the case you could make the same module file, but instead of .fancy-button and .fancy-button-large you can comma separate the selectors like so:

/* ===== fancier designed buttons ===== */

.header-search .button,
#submit-button {
    background: orange;
    color: #FFF;
}

/* --- fancy button mods --- */

/* larger text version (could be abstracted further) */
#contact-form-button {
    font-size: 160%;
}

This keeps it modular in it's design, it's only the name of the selectors used that isn't as organised so that's still awesome.

Also notice .sidebar-filter #submit-button has been changed to #submit-button as an ID should be unique and the class prefix is therefore redundant.

# File: modules/page-content.css

/* ===== Page content areas styling ===== */

.page-content {
    border-top: 5px solid;
    padding: 1em;
    *padding: 15px; /* slight IE hack needed to account for a margin bug */
}

@media screen and (min-width: 35.5em) {
    .page-content {
        /* space out the content a bit when available */
        margin: 1em;
    }
}

This offers a generic module for page content, which could quickly be applied to all pages without need for copy and paste. As the design grows, this would be much more important.

# File: pages.css

/* ===== Specific page mods ===== */

/* --- home page (red theme) --- */

.home-page-content {
    border-top-color: red;
}
.home-page-content h1 {
    color: red;
}

/* --- about page (blue theme) --- */

.about-page-content {
    border-top-color: blue;
}
.about-page-content h1{
    color: blue;
}

This layout file for specific pages offers per page differences, which are now very minor and get down to exactly what is different, making maintaining and debugging much easier.

Once you've written your code like this, go back over and review it. Spending a little time re-reading, improving and re-factoring your own code is worth it. You'll learn more about the way you write code, patterns you could reuse.

Using dev tools, you can look over some of your code too, specifically you can inspect the elements you've been working on and view the style tab. Here if you see that code is being overridden a lot of the time with large amounts crossed out then you could probably re-write the code, or re-think the way that element works and the css modules you have selectors to it.

Check out these resources on truly making your css skills awesome!

Also I've previously wrote about a reading list for modern web design.

Some best practices to take away.

  • Think in modules.
  • Take pride in your code, format it well.
  • Understand what your code does and why and avoid magic.
  • Use comments and files to organise code and additional comments to explain why some things are needed.
  • Avoid specific browser hacks.

My closing comment is: invest in your knowledge now, your future self will thank you.

If you have any questions? Or found a bug ;), please leave me a comment and I'll try to reply as quick as I can.