CSS Architecture

Strategies for writing meaningful, robust, flexible and scalable CSS

by Nathan Rambeck

Sparkbox

Twitter @nrambeck

Rambeck Family
Sparkbox Lunch
Better Web Shirt

Why CSS Architecture?

Can't we just style our pages?

Shack
Bradley Swenson
We’re not designing pages, we’re designing systems of components. —Stephen Hay

Complexity requires planning and organization

Complex Architecture
Alexandre Perotto

Scalability Issues

  • Scaling number of pages/templates
  • Scaling complexity (responsive)
  • Scaling dev team

Building Design Systems

Tiny Bootstraps for every client —Dave Rupert

Thinking in terms of modules and components

Modules and Components

Pattern Libraries

Where these ideas came from

Types of CSS Rules

  • Base
  • Objects
  • Components
  • State
  • Javascript
  • Themes
  • Utilities
  • Base
  • Objects
  • Components
  • State
  • Javascript
  • Themes
  • Utilities

Base CSS

Styles applied globally to bare elements


  body {
    margin: 0;
    padding: 0;
  }
  a {
    color: Orange;
  }
  img {
    max-width: 100%;
  }
            

Base CSS Considerations

  • Use a project like normalize.css
  • These are global defaults
  • Don't be too heavy-handed
  • Base
  • Objects
  • Components
  • State
  • Javascript
  • Themes
  • Utilities

What are objects?

Re-usable CSS classes for layout and structure

Recognize layout and structure patterns

Recognizing Patterns

  .promo {
    max-width: 1000px;
    height: 300px;
    padding: 20px;
    margin: 0 auto;
    position: relative;
    overflow: hidden;
  }
            

  .o-container-wide {
    max-width: 1000px;
    margin: 0 auto;
    overflow: hidden;
  }
  .promo {
    height: 300px;
    padding: 20px;
  }
            

  <div class="promo o-container-wide"></div>
            

Examples

  • Grid systems
  • Layout containers
  • Structural patterns
  • Base
  • Objects
  • Components
  • State
  • Javascript
  • Themes
  • Utilities

Components are discrete, self-contained pieces of UI

Examples

  • Buttons
  • Carousels
  • Pullquotes
  • Header
  • Navigation

Components make up the bulk of your CSS rules

Independent and self-contained

You should be able to drop a component anywhere on any page and it will maintain it's structure and design.

Components can be small


  <button class="btn">My Button</button>
            

Components can be big


  <footer class="c-footer">
    <div class="o-container-wide">
      <a class="c-footer__logo icon-a-assist" href="/">The Assist</a>
      <div class="c-social c-social--follow">
        <div class="c-social__label">Join the conversation</div>
        <ul class="c-social__list">
          <li class="c-social__item"></li>
          <li class="c-social__item"></li>
          <li class="c-social__item"></li>
        </ul>
      </div>
      <p class="c-footer__credit"></p>
    </div>
  </footer>
            

  <footer class="c-footer">
    <div class="o-container-wide">
      <a class="c-footer__logo icon-a-assist" href="/">The Assist</a>
      <div class="c-social c-social--follow">
        <div class="c-social__label">Join the conversation</div>
        <ul class="c-social__list">
          <li class="c-social__item"></li>
          <li class="c-social__item"></li>
          <li class="c-social__item"></li>
        </ul>
      </div>
      <p class="c-footer__credit"></p>
    </div>
  </footer>
            

Naming Components

BEM

(Block, Element, Modifier)

http://getbem.com/

[block]__[element]--[modifier]


  <div class="alert alert--warning">
    <h1 class="alert__title">
      <span class="alert__icon"></span>
      Alert Title
    </h1>
    <p class="alert__description">The password you entered is invalid.</p>
  </div>
            

  <div class="alert alert--warning">
    <h1 class="alert__title">
      <span class="alert__icon icon-warning"></span>
      Alert Title
    </h1>
    <p class="alert__description">The password you entered is invalid.</p>
  </div>
            

  <div class="alert alert--warning">
    <h1 class="alert__title">
      <span class="alert__icon icon-warning"></span>
      Alert Title
    </h1>
    <p class="alert__description">The password you entered is invalid.</p>
  </div>
            

  <div class="alert alert--warning">
    <h1 class="alert__title">
      <span class="alert__icon icon-warning"></span>
      Alert Title
    </h1>
    <p class="alert__description">The password you entered is invalid.</p>
  </div>
            

Why?

  • Readability
  • Self-descriptive
  • Specificity

Specificity Problems


  <div class="alert warning">
    <h1>
      <span class="icon-warning"></span>
      Alert Title
    </h1>
    <p>The password you entered is invalid.</p>
  </div>
            

  .alert { }
  .alert.warning { }
  .alert h1 { }
  .alert span { }
  .alert p { }
            
  • Base
  • Objects
  • Components
  • State
  • Javascript
  • Themes
  • Utilities

State classes are helpers that modify the state of a component.


  <ul class="nav">
    <li class="nav__item">Home</li>
    <li class="nav__item">About</li>
    <li class="nav__item">Contact</li>
  </ul>
            

  <ul class="nav">
    <li class="nav__item">Home</li>
    <li class="nav__item is-active">About</li>
    <li class="nav__item">Contact</li>
  </ul>
            

  .nav__item {
    display: inline-block;
    padding: .5em;
  }
  .nav__item.is-active {
    font-weight: bold;
  }
            

It's common to add remove state classes with Javascript.

State classes begin with "is" or "has"

  • .is-active
  • .is-hidden
  • .is-selected
  • .has-focus
  • Base
  • Objects
  • Components
  • State
  • Javascript
  • Themes
  • Utilities

Theme classes alter components with unique colors, fonts or other decorations


  <blockquote class="c-pullquote t-light">
    <p>A great quote from someone special.</p>
  </blockquote>
            

  .c-pullquote {
    font-size: 2em;
    font-style: italic;
  }
  .t-light {
    background-color: Cream;
    color: Magenta;
  }
  .t-dark {
    background-color: Magenta;
    color: Cream;
  }
            
  • Base
  • Objects
  • Components
  • State
  • Javascript
  • Themes
  • Utilities

Utility classes are single purpose helpers that apply one specific styling rule.

Examples of Utilities


  .u-sp {
    margin-bottom: 1em !important;
  }
  .u-clearfix:after {
    content: " ";
    display: block; clear: both; visibility: hidden;
    height: 0; font-size: 0;
  }
  .u-txt-center {
    text-align: center !important;
  }
  .u-txt-larger {
    font-size: 130% !important;
  }
            

  <div class="promo u-sp"></div>
  <div class="promo u-sp"></div>
  <div class="promo"></div>
            

Tweak your layout

or

slightly modify a component...

without creating another variant

Don't Overdo It!


  <div class="
    border-top-width-1-dot-04em
    border-top-style-dotted
    border-top-color-lightgrey
    border-bottom-width-12px
    border-bottom-style-solid
    border-bottom-color-cornflowerblue
    border-top-right-radius-1-dot-60em
    padding-5px
    margin-left-10px
    background-color-fuchsia
  ">
  </div>
            

from universal.css a parody of Atomic CSS

Naming Your Classes

Naming Things is Hard

see Sparkbox Foundry post

  • All lowercase
  • Use dashes or underscores
  • Long enough to discern (.pullquote not .pq)
  • No longer than needs to be (.btn not .button)

Naming Methodologies

  • By Presentation
  • By Content
  • By Function

By Presentation


  .button--green { }
  .rounded-image { }
  .large-heading { }
            

By Content


  .button--submit { }
  .profile-image { }
  .article-heading { }
            

By Function


  .button--primary { }
  .decorative-image { }
  .content-heading { }
            

Namespacing

Add prefixes to all of your classes to recognize the purpose of each one.

  • Objects: .o-
  • Components: .c-
  • State: .is- or .has-
  • Theme: .t-
  • Utility: .u-

  <footer class="c-footer">
    <div class="o-container-wide">
      <a class="c-footer__logo" href="/">The Assist</a>
      <div class="c-social c-social--follow">
        <div class="c-social__label u-txt-center">Join the conversation</div>
        <ul class="c-social__list">
          <li class="c-social__item"></li>
          <li class="c-social__item is-active"></li>
          <li class="c-social__item"></li>
        </ul>
      </div>
      <p class="c-footer__credit"></p>
    </div>
  </footer>
            

  <footer class="c-footer">
    <div class="o-container-wide">
      <a class="c-footer__logo" href="/">The Assist</a>
      <div class="c-social c-social--follow">
        <div class="c-social__label u-txt-center">Join the conversation</div>
        <ul class="c-social__list">
          <li class="c-social__item"></li>
          <li class="c-social__item is-active"></li>
          <li class="c-social__item"></li>
        </ul>
      </div>
      <p class="c-footer__credit"></p>
    </div>
  </footer>
            

  <footer class="c-footer">
    <div class="o-container-wide">
      <a class="c-footer__logo" href="/">The Assist</a>
      <div class="c-social c-social--follow">
        <div class="c-social__label u-txt-center">Join the conversation</div>
        <ul class="c-social__list">
          <li class="c-social__item"></li>
          <li class="c-social__item is-active"></li>
          <li class="c-social__item"></li>
        </ul>
      </div>
      <p class="c-footer__credit"></p>
    </div>
  </footer>
            

  <footer class="c-footer">
    <div class="o-container-wide">
      <a class="c-footer__logo" href="/">The Assist</a>
      <div class="c-social c-social--follow">
        <div class="c-social__label u-txt-center">Join the conversation</div>
        <ul class="c-social__list">
          <li class="c-social__item"></li>
          <li class="c-social__item is-active"></li>
          <li class="c-social__item"></li>
        </ul>
      </div>
      <p class="c-footer__credit"></p>
    </div>
  </footer>
            

  <footer class="c-footer">
    <div class="o-container-wide">
      <a class="c-footer__logo" href="/">The Assist</a>
      <div class="c-social c-social--follow">
        <div class="c-social__label u-txt-center">Join the conversation</div>
        <ul class="c-social__list">
          <li class="c-social__item"></li>
          <li class="c-social__item is-active"></li>
          <li class="c-social__item"></li>
        </ul>
      </div>
      <p class="c-footer__credit"></p>
    </div>
  </footer>
            

Code Organization

Use a preprocessor (Sass, Less, Stylus) to take advantage of:

  • Imports
  • Variables
  • Functions
  • Mixins
  • Nesting

Divide styles into meaningful files


  @import "variables";
  @import "mixins";
  @import "normalize";
  @import "typography";
  @import "headings";
  @import "buttons";
  @import "layout";
  @import "carousel";
            

Prefix your variable names


  // Colors
  $c-warning: Red;
  $c-primary: Blue;
  $c-background: White;
            
Variable Autocompletion

Scope your variables


  .alert {
    $background-color: Red;
    $foreground-color: Cream;
    background-color: $background-color;
    color: $foreground-color;
  }
            

Source Ordering

The Inverted Triangle Method

ITCSS is a method of ordering your CSS settings and rules to prevent namespace collisions, specificity wrestling, leaky styles and inadvertent regressions.

ITCSS Illustration 1
ITCSS Illustration 2

  @import "settings.global";
  @import "settings.colors";
  @import "tools.functions";
  @import "tools.mixins";
  @import "generic.box-sizing";
  @import "generic.normalize";
  @import "elements.headings";
  @import "elements.links";
  @import "objects.wrappers";
  @import "objects.grid";
  @import "components.nav";
  @import "components.buttons";
  @import "components.promos";
  @import "trumps.utilities";
  @import "trumps.ie8";
            

Questions?

Twitter @nrambeck

Sparkbox

https://nrambeck.github.io/css-architecture/