CSS Organizing Conventions

@ Smashing Online

~2007 Major Grid Frameworks

Blueprint, 960gs, etc…

an element on a 12-column grid

column col6of12 last

👍 Provide Consistent Patterns

👍 Handle Float Hacks

👎 Framework Override Hell

Headshot of Natalie Downe

@natbat Natalie Downe

2008 CSS Systems

Writing Maintainable CSS by Natalie Downe | Barcamp London 5
28th September 2008


Consulting Agency

  • High quality code
  • On tight deadlines
  • For handover to client

CSS frameworks decrease the maintainability of code.

– Natalie Downe

CSS Systems Conventions > Frameworks

  • Shared Vocabulary
  • Reusable Patterns
  • Personalized Styles

CSS Ordering Based on Specificity

  1. Elements grouped by Type
  2. Classes grouped by Effect
  3. IDs grouped by Component

1… General Styles

  • body styles
  • reset
  • links
  • headings
  • other elements, tags

2… Helper Styles

  • forms
  • notifications
  • errors
  • consistant items with normally just one class

3… Page Structure

  • header
  • footer
  • generic layout blocks
  • skeleton including page furniture

4… Page Components

“most of your styles will be in here”

5… Overrides

avoid as much as possible

Layouts with Fluid Internals

#container {
width: /* em values preferred */;
max-width: 100%;
.any-internal { /* % values only */ }

Don’t Overly Sandbox Focus on What Not Where

Up & Down Font Size Constantly

Dont Re-engineer Seperate Solutions

For individual browsers

  1. Define it
  2. Develop it
  3. Maintain it
  4. Communicate it
Headshot of Nicole Sullivan

@stubbornella Nicole Sullivan

2009 Object Oriented CSS

A CSS “object” is a repeating visual pattern, that can be abstracted into an independent snippet of HTML, CSS, and possibly JavaScript.

– Nicole Sullivan, OOCSS

Component Driven

1. Separate Structure & Skin

Object Structure Minimal & Reusable

Object Skin Multiple Theme Options

Separate Container & Content

“Rarely use location-dependent styles”

Also from OOCSS Media Object

2009-Present Systems/Objects Repackaged

SMACSS, BEM, Atomic Design, ITCSS, etc…

All are Useful Combine What Works

Fundamental Priciples of CSS

CSS is Object-Oriented

wireframe of a site

Object Composition

.person class contains .name & .address classes

CSS can be


Composed result of p, .alert, & .error functions

But CSS Is Fundamentally Different

Resilient, Declarative, Contextual

Cascade Aligned Programming

The Cascade Is About Balancing Concerns

Balancing Branding with Preferences

Balancing Systems with Details

Balancing Context with Modularity

Balancing Control with Resilience

We Provide… Hints & Suggestions

We Define… Minimal Constraints

We Communicate… Relationships & Intent

CSS Provides… Relative Units

CSS Provides… Intrinsic Sizing

CSS Provides… Normal Flow

Express What We Mean

Clear Semantics Help the Browsers

Make informed decisions

Help the Browsers Help the Users

Help other Developers

Read & understand & maintain the code

Several Organizing Conventions

CSS Systems Based on Specificity

  1. Elements
  2. Classes
  3. IDs

OOCSS Not Explicit, But…

Atomic Design Based on Complexity

  1. Atoms (element type)
  2. Molecules
  3. Organisms
  4. Templates
  5. Pages
label, input, and button atoms
search form molecule, with label, input, and button
banner organism, with logo, navigation, and search
wireframe of a full page

SMACSS Based on Category

  1. Base (element type)
  2. Layout (use #id)
  3. Module (use .classes)
  4. State (use !important)
  5. Theme (i.e. “skin”)

ITCSS Based on Reach

Narrow/Broad Reach How Many Elements?

Low/High Specificity What Selector Weight?

Generic to Explicit What Desired Impact?

From p {} through .text-center {}

CSS Systems + OOCSS Updated with Pictures

OddBird Based on Reach & Complexity

  1. Tools
  2. Config
  3. Initial
  4. Patterns
  5. Layouts
  6. Components

CSS Systems + OOCSS + ITCSS + Atomic Design + …

Tools Used Across Projects

Sass, Accoutrement, Herman, Cascading Colors…

Config Design Tokens
Tool Configuration

Tokens by Purpose

_colors.scss | _sizes.scss | _fonts.scss

Not by Sass Feature

_variables.scss | _functions.scss | _mixins.scss

Combined as a Single Sass Module

With no CSS output

Initial Global & Element Defaults

Including resets & custom properties

Patterns Reusable Objects & Skins

The majority of our code base…

Layouts Specific Templates

Often composed of existing patterns

Components Specific Functionality

Often composed of existing patterns

Layer Folders With Sass Partials

  • sass/
    • tools/
    • config/
      • _colors.scss
      • _fonts.scss
      • _sizes.scss
      • _index.scss
    • initial/
    • patterns/
    • layouts/
    • components/
    • style.scss

With Vue Single File Components

With Vue Component Styles Scoped

Scope Is About Ownership

See the Pen Isolation Donut by @mirisuzanne on CodePen.


<sub-component />

<article-component data-scope='article'>
<h2 data-scope='article'>...</h2>

<sub-component data-scope='article' data-scope='sub'>
<!-- internals of sub only have scope='sub' -->

<footer data-scope='article'>...</footer>
<style scoped>
article { ... }
h2 { ... }
footer { ... }
article[data-scope=article] { ... }
h2[data-scope=article] { ... }
footer[data-scope=article] { ... }
<article data-scope="article instance-id">
h2[data-scope~=article] { 
/* all instances */
h2[data-scope~=instance-id] {
/* unique instance */

Naming Conventions

Not explicit in most…

BEM Block Element Modifier

Block Standalone Entity

Meaningful on its own

Element Always Part Of A Block

No standalone meaning

Modifier Change Appearance Or Behavior

A flag on a block or element

Not Size or Complexity Self-Sufficiency & Belonging

Selector Naming

.block » .block__element » .block__element--modifier

👍 Clarity Of Relationship Structure

👎 Flattening Of Selector Structure

Everything is equal specificity

Combine Selectors To Match Scope & Specificity

In meaningful ways

SMACSS Layer Prefixes

.l-<layout> | .is-<state>

State Types

.is-collapsed,, .is-hidden


[aria-expanded] & [aria-pressed]

Namespace Related Selectors

.is-success | .is-error [data-msg="success | error"]

Base Attribute


Attribute Variations


  • [data-attr]Presence (even if empty)
  • [data-attr="..."]Exact match
  • [data-attr*="..."]Any match
  • [data-attr~="..."]Space-delimited (like classes)
  • [data-attr|="..."]Hyphen-delimited
  • [data-attr^="..."]Starts with…
  • [data-attr$="..."]Ends with…
  • [data-attr="..." i|s]Case sensativity

Use Built-In Attributes When Available


[aria-hidden] & [hidden] & ??

[aria-hidden] Visual Only

[hidden] Hidden Everywhere

??? Screen Reader Only


??? Screen Reader Only

[data-hidden='screen'] | [data-hidden='small-screen']

Use Utility Classes For Meaningful Utilities

.sr-only | .clearfix | .elide-text

And then… There’s Tailwind

All explicit, all the time

👎 Framework Override Hell

DRY Code Don’t Repeat Yourself

.warning { border-color: red; }

DSfP Don’t Stretch for Patterns

.bc-r { border-color: red; }