« resources

Smashing Workshop

Naming & Organizing Conventions

towards a cascade-aligned programming

workshops.oddbird.net/smashing24/conventions/

Cmd/Ctr-K for Controls

A poll… OOCSS, ITCSS,
SMACSS, BEM, CUBE,
Utility-First, other

What are you trying? Are you happy with it?

  • ✅ Love it
  • ⚠️ Could be improved
  • ❌ Needs to change
  • ‘Branded’ conventions
  • Built up over 20 years of CSS
  1. Writing Selectors

  2. Organizing Rules

  • Two primary concerns:
  • Writing selectors
  • (or naming the elements we select)
  • Organizing selector rules
  • Across an entire project

Hopefully… More Consistent Code

Hopefully… More Reliable Code

Hopefully… More Organized Code

Hopefully… More Maintainable Code

  1. Mental Model

  2. Writing Selectors

  3. Organizing Rules

  • But the rules we define
  • For naming and organizing selectors
  • Often reflect some mental model of the language
  • How it works, and how we interact with it

Branded… Conventions are Useful

(as a point of reference)

Understand… Their Concerns

Understand… Their Approaches

Understand… Their Mental Model

Different Project Needs

  • Important to remember
  • Different projects have different needs,
  • Different constraints…

Different Team Structures

  • Different team structures
  • Different budgets & priorities
  • And those differences matter…

Just… 🤷🏻‍♀️ Conventions

Your mileage will vary

  • All just conventions
  • A set of guidelines someone found useful
  • In their org, their team, their code
  • Your mileage will vary

Just because InstaSalesFace Did It

Doesn’t mean we all need to

  • Just because instaSalesFace did it
  • Doesn’t mean it will work for the rest of us
  • There’s not a single correct approach
  • That we’re all moving towards in unison
avatar

I think they are all pretty neat and I see the point…

— Chris Coyier, @chriscoyier

  • I tend to agree with Chris Coyier who says
  • They’re all pretty neat…
avatar

But I’m a bunch of years into this and still generally… write the selector I need and then style with that.

— Chris Coyier, @chriscoyier

There’s no Miracle Cure

Conventions won’t save us

  • Important to say up-front
  • There’s no miracle cure
  • To make CSS maintenance go away
  • (Except getting someone else to do it)
  • If you refuse to weed the garden
  • Then the garden will have weeds

Like design systems & a11y Living Documentation

  • Code maintenance
  • not a technical issue to ‘solve’ and move on
  • Code is communication
  • We spend more time reading it than writing it
  • And like all human communication
  • (design systems, UX, accessibility, etc)
  • It requires attention and nuance
  • People want a correct answer, it doesn’t exist

It’s a Process

Conventions can develop over time

  • Conventions are ‘documentation’ of the process
  • Conversations we’ve had, decisions we’ve made
  • Our vision, as it will be carried out
  • The conventions are not the solution,
  • Their the result of attention & communication

Prioritize Team Conversations

  • The conversation we have about conventions
  • More important than the details we land on

Close collaboration Design & Engineering

  • And that requires strong communication
  • Ideally ongoing communication
  • Between designers and engineers
  • We build our best products by working together
Headshot of Sophia Prater.

Sophia Prater Object Oriented UX

OddBird Article & Video on OOUX
  • We use a process based on Sophia Prater’s
  • Object-Oriented UX
  • It’s a design process,
  • But involves the entire team
  • So we know we’re all building the same thing
  • And using the same terms

If it’s not documented, It Doesn’t Exist

  • This documentation is essential
  • Communicate our priorities and goals and approaches
  • With new team members, or with ourselves next week
  • If a convention isn’t documented, it doesn’t exist
  • There’s no way to maintain it

Mockups are Sketches

  • It can be useful to draw pictures
  • On paper or on screen
  • With varying degrees of detail
  • But all static designs are sketches
  • A gesture towards a final website
  • (We remove colors/fonts for client presentation)

Writing HTML & CSS Is Design Engineering

  • The design process may start static
  • But it continues as we code
  • Writing HTML & CSS is part of a design process
  • Code is design, and design impacts code
  • Doesn’t matter who learns what skills, collaborate!
  • Ask questions at any handoff

Prototype Potential Issues

  • If something seems difficult
  • Or like a potential issue
  • We’ll create a codepen
  • Isolate the problem, and…

Stress-Test Potential Solutions

– Test potential solutions

  • What are the edge cases?
  • Where and how do they break?

Not a Formal Process

pen.new

  • Not a long formal process, but pen.new
  • 10-15 minutes, a reduced case
  • Resizing the window, zooming in and out
  • Use the keyboard
  • Check in a couple browsers
  • Learn to use a screen reader (VO on mac?)

Later… Feature Review

  • We’ll repeat some of the tests
  • When it’s time for code review
  • This is essential to our process
  • Not about gate-keeping, having more eyes
  • Everyone gets review, gives reviews
  • Even reviewing your own code is helpful
  • Not just the code, but the functionality

Review is… Mostly Asking Questions

  • Sometimes review catches a bug, problem
  • Mostly we’re asking asking questions
  • Why did you make this choice?
  • What’s that number stand for?
  • Can we make it more consistent/readable?
  • This is where conventions develop

Often… Functionality Before Style

  • Make sure the feature is functional
  • Before we get too far with styling
  • Sometimes rough wireframe styles help visualize
  • But we need function to test states
  • How things move and change
  • (The CSS details…)

Start with… Semantic HTML

  • Converting a static design to code
  • Starts with semantic HTML
  • This is essential
css…
#header {}
#nav {}
#main {}
#footer {}
See Eric Meyer’s Structural Naming
  • In the early days of CSS
  • This was a shorter list, and conventions developed
  • There were blog posts and articles
  • Naming conventions for page structure
  • With consistent IDs
  • Header, nav, main, footer, etc
css…
header {}
nav {}
main {}
footer {}
  • Now these are elements in the language
  • Along with many more
  • Aside, figure & fig-caption, summary & details, dialog, etc
avatar

Building with accessible semantics from the get-go can give you expressive, meaningful style hooks for free.

— Ben Myers, Style with Stateful, Semantic Selectors

Built-in Functionality

  • HTML gives us so much for free!
  • Interactive links, buttons, form controls, disclosure
  • But also…

Built-in Naming Conventions

  • Before we start adding any classes
  • We get built-in naming
  • From meaningful HTML elements and attributes
css…
/* expressive semantics */
form:has(:invalid) [type="submit"] {}

/* some name we came up with? */
.form__btn--submit--invalid {}
  • We can reference els & attrs in selectors
  • Extended with ARIA attributes as needed
  • Also have access to pseudo-classes & pseudo-elements
css…
a[href*="://"] { /* external links */ }
a[href^="https:"] { /* secure links */ }
a[href$=".pdf"] { /* pdf links */ }

button[aria-pressed=true] { /* pressed buttons */ }
img:not([alt]) { /* images without alt text */ }
  • There’s so much we can do
  • Without ever coming up with our own names
css…
.flow > * + * {
  margin-top: var(--flow-space, 1em);
}
  • Selector combinators let us expand on that
  • Defining relationships
css…
@container (inline-size > 60ch) {}
  • And conditional at-rules let us respond to context

Intelligent” Selectors

No “intervention by the author”

Semantic CSS With Intelligent Selectors by Heydon Pickering

~2006-2010… Major CSS Libraries

YUI, Blueprint, 960gs, etc…

Central Class Library

<div class=" column col6of12 last " >

Frameworks like… Bootstrap Today

Headshot of Natalie Downe.

2008, Natalie Downe CSS Systems

avatar

CSS frameworks decrease the maintainability of code.

— Natalie Downe, CSS Systems

  • Our experience as well
  • Designed for general use, quick-start
  • More than you need, but never exactly what you need
  • Often get removed (painfully)

A CSS System

  • Glossary of shared vocabulary for developers
  • Reusable set of markup patterns & CSS
  • Personalized for an individual site

A CSS System Overall Structure & Individual Components

  • Involves both
  • Overall structure
  • Individual components
  • Approached separately!

Internals should be 100% Fluid

(this was before RWD & Media Queries)

Fit inside Any Container

(which may provide sizing)

Afraid Of Heights

(the variable axis for blocks)

  • But usually don’t set the height
  • The variable axis for block elements (containers)
  • So some vertigo is good
  • Be afraid of height, cautious about setting it
Headshot of Nicole Sullivan.

2009, Nicole Sullivan Object Oriented CSS

  • Nicole Sullivan’s OOCSS
  • (came out around the same time)
  • Highlights similar ideas
avatar

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

Beyond Reusable Components

  • A reminder
  • Not just components are reusable…

Components Share Patterns

Avoid even unique component styles

  • But the patterns that we use
  • across components

Combined into custom Object Libraries

  • Snippets combined into a custom
  • Library of reusable patterns

1. Separate Structure & Skin

Object Structure Minimal & Reusable

Object Skin Multiple Theme Options

Mix & Match Structures & Skins

(Unique components, without unique CSS)

New pages should Rarely Require New CSS

2. Separate Container & Content

e.g. “internals should be fluid”

Be Flexible

  • Container sets width
  • Content sets height
e.g. “be afraid of heights”

2009-Present Systems & Objects Repackaged

SMACSS, BEM, ITCSS, CUBE, etc…

  • I’m going to quote these two a lot
  • Nearly every convention since
  • Is built on the ideas they presented
  • 16 years ago
Headshot of Jeremy Keith.

2011, Jeremy Keith Pattern Primer

  • Jeremy Keith’s Pattern Primer in 2011
  • Provided a documentation & development tool
screenshot
[Pattern Primer ]
  • For building & viewing fluid objects
  • Outside their layout context
avatar

Truly effective responsive design must begin with the content first.

— Jeremy Keith, Responsive Enhancement Workshop

  • This helps ensure the content is responsive
  • Before we put it inside any structure
  • The same convention is used by…
Headshot of Andy Bell.

2020, Andy Bell CUBE CSS

  • Andy Bell’s 2020 CUBE CSS
  • ‘Compositions’ are structures
  • That provide layout distinct from content ‘Blocks’
  • This is a useful way
  • To ensure our content is modular
  • In a system that provides consistency
  • CUBE utilities similar to OOCSS objects
  • CUBE exceptions like OOCSS extensions
Media vs Container [live code, present, debug]
  • Container Queries can help!
  • Components define their own variations
  • Only reference provided container sizes
  • The container and content are separate
Style Queries Make Code Modular [present, debug]

CSS shines Building Systems

  • Part of what connects these conventions
  • An embracing of systems
  • Find what is consistent across components
  • Build abstractions
  • This is where CSS shines…

Rely on… Cascade and Inheritance

  • What the cascade & inheritance were designed for
  • Achieving broad consistency
  • With very little code
  • And the providing targeted overrides as needed

Built-in Organizing Conventions

  • Act as built-in organizing convention
  • We don’t need to come up with our own,
  • Just build on what the language asks for

Macro Before Micro

From CUBE CSS
avatar

Most of the work is already done for you with global and high-level styles.

— Andy Bell, CUBE CSS

Don’t Overly Sandbox

Styles should be reusable

From CSS Systems

Focus on What Not Where

From CSS Systems

Rarely use Location-Dependent Styles

From OOCSS

BEM often Gets This Backwards

  • On the surface this seems like a goal of BEM
  • But in practice it often ends up making the issue worse

The goal is… Portable Selectors

css…
/* .page header { … } */
.page__header {}
BEM Avoids Nesting
  • BEM syntax often avoids nesting
  • By combining context and content into a single selector
  • But that’s not more portable
  • It’s still tied to a specific context
css…
header.masthead {}
Prefer Modifiers
css…
/* Runs the risk of becoming out of date; not very maintainable. */
.blue { color: blue; }

/* Depends on location in order to be rendered properly. */
.header span { color: blue; }

/* Too specific; limits our ability to reuse. */
.header-color { color: blue; }

/* Nicely abstracted, very portable, doesn’t risk becoming out of date. */
.highlight-color { color: blue; }
Harry Roberts, CSS Guidelines
Upside-down headshot of Harry Roberts.

2014, Harry Roberts Inverted Triangle CSS

Inverted triangle with
range across the top,
and specificity/explicitness
down the sides
Inverted Triangle CSS by Harry Roberts

Narrow » Broad Reach How Many Elements?

Low » High Specificity What Selector Weight?

Generic » Explicit What Desired Impact?

From p {} through .text-center {}

Inverted triangle with
range across the top,
and specificity/explicitness
down the sides
Inverted Triangle CSS by Harry Roberts
A graph
with specificity on the vertical axis,
and code line numbers horizontal,
divided into layers,
and a line showing that
specificity should only increase
throughout the code base
Inverted Triangle CSS by Harry Roberts
Inverted triangle with layers,
wide top to narrow bottom:
settings, tools, generics, elements,
objects, components, overrides
Inverted Triangle CSS by Harry Roberts
  1. Elements grouped by Type
  2. Classes grouped by Effect
  3. IDs grouped by Component
From CSS Systems
  1. General Styles (resets, type, colors)
  2. Helper Styles (forms, errors, alerts)
  3. Page Structure
  4. Page Components
  5. Overrides (avoid when possible)
From CSS Systems
Inverted triangle with layers,
wide to narrow -
the top layers are sass-only, no output,
then global css layers,
and finally scoped components
Inverted Triangle CSS by Harry Roberts
css…
@layer settings {}
@layer tools {}
@layer generic {}
@layer elements {}
@layer objects {}
@layer components {}
@layer overrides {}

CSS Utilities Have One Job

  • The most popular and controversial trend
  • Is utility-first CSS
  • But utility classes have a long history
  • Going back to OOCSS, if not earlier
  • The job is to do one simple thing
  • (any simple thing)
css…
.wrapper {
  margin-inline: auto;
  padding-inline: 1rem;
  max-width: 60rem;
}
  • Useful!
  • For common & simple patterns
css…
hidden { display: none !important; }
visually-hidden:not(:focus-within) {
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}
  • Doesn’t have to be a class
  • I find these nicely parallel
css…
.bg-primary { background: #ff00ff; }
.bg-secondary { background: #ffbf81; }

[data-bg=primary] { background: #ff00ff; }
[data-bg=secondary] { background: #ffbf81; }
For stored values from data
  • This especially makes sense
  • When using them to pass info from a database or JS
  • We can provide tokens as utilities
  • And apply them in our markup if needed
css…
[data-bg] { background: var(--canvas-color); }
[data-bg=primary] { --canvas-color: #ff00ff; }
[data-bg=secondary] { --canvas-color: #ffbf81; }
css…
[data-layout] {
  display: grid;
}
  • We’ll often use attributes instead
  • I noticed that CUBE does too
css…
[style*='--canvas-color:'] {
  background: var(--canvas-color);
}
Flexible Grid Settings [present, debug]

What About… ?

(just, like, my opinion)

Mostly… 🤷🏻‍♀️ I Don’t Know

(not the issues I’m having)

I don’t trust CSS Abstinence Rules

  • Avoiding the core features of CSS
  • Doesn’t make it better,
  • It just makes us work harder
  • No wonder we think CSS is broken,
  • We’ve all collectively ‘agreed’
  • Not to use any of the features!

Block Element Modifier (BEM)?

https://en.bem.info/
css…
.block { }
.block--modifier { }
.block__element { }
.block__element--modifier { }

Always Flat Specificty

No .combined.selectors

Use @layer?

Or custom properties, or :where(), or…

css…
header button { /* inside-of */ }
.header__button { /* belongs-to */ }
Describing Scope

JS frameworks Single File Components

<style scoped>…</style>

  • Source order is unreliable
  • Useful!

Too many Component-Specific Styles?

Soon… Use @scope?

js…
render(
  <button css={css`
    padding: 32px;
    background-color: hotpink;
    font-size: 24px;
    border-radius: 4px;
    &:hover {
      color: ${color};
    }
  `} >...</button>
)

Tools should Let Us Use CSS Features

(otherwise ‘tools’ become obstacles)

Tools should Understand Design

Can it handle colors and lengths?

html…
<button class="css-1h3ivcl">...</button>

2015, Yahoo! Atomic CSS

No relation to Atomic Design
html…
<div class="Bgc(#0280ae.5) C(#fff) P(20px)">...</div>
html…
<body class="bg-green black-70 pa4">
  <h1 class="f1">...</h1>
</body>
html…
<div class="md:flex">
  <div class="md:flex-shrink-0">
    <img class="rounded-lg md:w-56" src="..." alt="">
  </div>
  <div class="mt-4 md:mt-0 md:ml-6">
    <div class="uppercase tracking-wide text-sm text-indigo-600 font-bold">...</div>
  </div>
</div>

I don’t Get It ¯\_(ツ)_/¯

Often called Functional CSS

CSS is All About Context

Design is All Side Effects

CSS can’t be Functionally “Pure

When you… reduce the amount of time you spend writing and editing CSS… you must instead spend more time changing HTML classes

— Nicolas Gallagher

About HTML semantics and front-end architecture
css…
.btn {
  @apply font-bold py-2 px-4 rounded;
}
.btn-blue {
  @apply bg-blue-500 text-white;
}
.btn-blue:hover {
  @apply bg-blue-600;
}
A woman in a suit kneels to pet cute ducklings while the mother duck removes a bill from her purse. The text underneath says colour.css / layout.css / typography.css photo: CSS Systems
Avoid Cute Duckling Scams

Paradigms… Object-Oriented or Functional

  • CSS is classes with properties, and inheritance
  • It’s clearly meant to be ‘object oriented’
  • These comparisons can be useful
  • But CSS isn’t a general-purpose language
  • It’s domain-specific, resilient, and contextual

Websites don’t need to cannot possibly look the same in every browser.

— The web, paraphrased

  • We’ve talked a lot about resilience
  • A web on everything, for everyone
  • It’s fundamentally impossible
  • For our website to look the same everywhere
  • In every browser

The fact we can control a paper page is really a limitation of that medium.

— John Allsopp, A Dao of Web Design

  • And that’s a feature of the medium
  • A design decision that’s been built-in
  • And so CSS is easiest to write & maintain
  • When we embrace the way it’s designed
  • (The Dao of web design)
avatar

Be the browser’s mentor, not its micromanager.

Andy Bell

  • And our role in the system
  • To quote Andy Bell
  • We want to be the browser’s mentor
  • And not it’s micromanager

Define some constraints. Let the language work out the details.

— Keith J Grant

Resilient, Declarative, Contextual
  • We want to
  • Design some constraints
  • Let the language work out the details

If I were to brand OddBird Conventions

  • If I were to brand our conventions at OddBird
  • (at a high level)
  • The way we approach and write CSS,
  • I would call it something like…

Poetic CSS

  • Poetic CSS

PoetiCSS

  • Or poetiCss
  • For any philosophy nerds

Use The Language

  • Paying attention not just to the output
  • But the flow of the language
  • The flow of different layout models

Trust The Flow

  • Trust document flow
  • (not just normal flow layout,
  • but the flow of each layout system)
  • The flow of value resolution,
  • Cascading and inheritance
  • The flow of browser/author/user collaboration

Think in Systems

  • Even when we’re working on details
  • We want to think in systems
  • Not just the individual components
  • But the patterns that they share
  • And how they combine to create new ideas
  • But those big ideas have to fit a small space…

Be Concise

  • We want to be concise
  • Only say what’s essential
  • To get our design across
  • (I don’t mean minimalist design always,
  • But minimal constraints to achieve it)

Rely on… Expressive SubText

  • Relying on the subtext implications
  • Like relative units and built-in keywords
  • Wherever we can, using implied or intrinsic
  • Rather than explicit constraints
  • To make sure we still…

Say What You Mean

  • Say what we mean
  • The goal isn’t brevity at all cost
  • But to convey as much information as possible
  • About our intentions
  • In syntax that the browser understands

Write CSS
Not too much
Mostly Reusable Patterns

We Mix & Match

CSS Systems, OOCSS, ITCSS, CUBE…

Work In Layers

(even before @layer)

Prefer Global Styles

A Wider 🌊 Cascade Allows More Nuance in Layering

Use Built-In Attributes When Available

(We ❤ “intelligent” selectors)

is-hidden

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

is-collapsed

[aria-expanded] & [aria-pressed]

Flow & flex content Should be Fluid

Grid & flex containers Provide Structure

Use utilities Where Meaningful & Common

visually-hidden | etc.

DRY Code Don’t Repeat Yourself

.warning { border-color: red; }

DSfP Don’t Stretch for Patterns

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

Combine Tokens Into Themes

css…
[data-theme] {
  background-color: var(--theme-bg, var(--global-bg, transparent));
  color: var(--theme-color, var(--global-color, inherit));
}
css…
[data-theme='light'] {
  --theme-bg: var(--neutral-light);
  --theme-color: var(--neutral-dark);
  --theme-link: var(--primary-dark);
}

[data-theme='dark'] {
  --theme-bg: var(--neutral-dark);
  --theme-color: var(--neutral-light);
  --theme-link: var(--primary-light);
}

Attribute-namespace For Related Classes

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

The Cascade is Useful

To guide our conventions

Design is Not About Purity

CSS is Not About Control

CSS is unlike anything else… designed for the realities of a flexible, multilingual, multi-device web.

— Rachel Andrew

The Way We Talk About CSS
« resources

Smashing Workshop

Naming & Organizing Conventions

Bring this workshop to your company.
Slide Controls

View:

Navigate slides using the arrow-keys.