Rethinking CSS

Go Atomic for Scaling, Performance and Simplicity

A slide deck by John Polacek

Follow @johnpolacek

...or just scroll

Open-Mindedness Required

The following content flies in the face of traditional CSS

If you love the way you write CSS
and don’t want to change...

then don’t.

( Obligatory disclaimer )

What is Atomic CSS?

Why use Atomic CSS?

Why is this so controversial?

Where is Atomic CSS in use?

How do I get started with Atomic CSS?

What is Atomic CSS?

( also known as Functional CSS )

You probably already write
Helper / Utility Classes

.clearfix
.grid-*
.hidden

Why Do Helper Classes Help?

Easy to understand + Easy to add/remove

How many times do you
declare the same properties?

margin
padding
width
color
font-size
font-weight
...etc.
font-style
text-align
border
4... 9... 42... 167... ?
It could be
1

Utility Classes All* The Things!

* Most of
Cartoon Image of Excited Guy Playing Guitar

Atomic CSS is the approach to CSS architecture that favors small, single-purpose classes with names based on visual function.

Source: Let’s Define Exactly What Atomic CSS is (CSS Tricks)

What does it look like?

!!! Hot Drama Alert !!!

The following code may provoke strong reactions in some people.
You have been warned.
For example, to do this...
Sign In
Join

Signing up for an account is quick and easy.

You might do this...
<div class="box-640 flex pad-3 bgr-white shadow rounded">
  <div class="col-6 s-col-12 pad-3-right s-pad-1-right s-border-bottom s-pad-3-bottom s-marg-3-bottom">
    <h5 class="text-light text-blue-lt pad-2-bottom">Sign In</h5>
    <form id="loginForm" class="pad-1-right">
      <input class="marg-1-bottom" type="text" placeholder="User Name" required="required">
      <input class="marg-3-bottom" type="text" placeholder="Password" required="required">
      <input type="submit" class="btn float-right marg-1-top" value="Log In">
    </form>
  </div>
  <div class="col-6 s-col-12 pad-3-left border-left s-border-0 s-pad-0">
    <h5 class="text-light text-blue-lt pad-2-bottom pad-1-left s-pad-0-left">Join</h5>
    <p class="pad-3-bottom pad-1-left s-pad-0-left">Signing up for an account is quick and easy.</p>
    <div class="wide pad-3-top pad-1-left">
      <button id="createAccount" class="float-right">Create Account</button>
    </div>
  </div>
</div>
"box-640 flex pad-3 bgr-white shadow rounded"
.box-640 {
  width:100%;
  max-width: 640px;
}
.flex {
  display: flex;
  flex-wrap: wrap;
}
.shadow {
  box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.1);
}
.bgr-white {
  background-color: #fff;
}
.rounded {
  border-radius: 4px;
}
.pad-3 {
  padding: 3.2rem;
}

“Functional CSS is just shifting complexity out of stylesheets and into templates.”

Vince Speelman
Front End Engineer at
TED
Traditional CSS

Write HTML

Write CSS

Atomic CSS

Write HTML

Atomic CSS Class Names

Shorthand

Favors brevity

.f1 { font-size: 3rem; }
.ma0 { margin: 0; }
Longhand

Favors Readability

.fontsize-xxl { font-size: 3rem; }
.marg-0 { margin: 0; }
.margin-0 { margin: 0; }

Atomic CSS Architectures

Static

Familiar way to write CSS
Use a preprocessor
Unit-based design system
Easily understood
Enforceable style rules

Programmatic

No more writing CSS
Use a build tool
Automatic CSS generation
Fully optimized
No unused styles

Why use Atomic CSS?

As heard on the
Front End Happy Hour Podcast

“Unfortunately you have to use CSS.”

Front End Engineer at Netflix

“I’m really bad at CSS.”

Front End Engineer at Evernote

“You try to write something clean, but then it turns into something shitty.”

Front End Engineer at LinkedIn

“At LinkedIn we have a massive CSS file that is 3.5MB.”

Front End Engineer at LinkedIn
(Alternate title for this talk)

Atomic CSS

Your Life Could Be Easier

“Naming CSS Stuff Is Really Hard”

Ethan Muller
Front End Developer at Sparkbox
Naming CSS Stuff Is Really Hard

At-A-Glance Understandability

<div class="inner">
<div class="pad-2">

We Have a Weight Problem

Chart showing the very large page weights of various popular websites

“15kb of CSS is all you’ll ever need.”

Philip Ardeljan
15kb of CSS is all you’ll ever need.

Too Much C in CSS

Every time you write a style declaration,
you create an exception to a default behavior.
Less cascade leads to flatter, simpler CSS.
Traditional CSS
The older your codebase is
More levels of cascade.
Selectors get longer.
File sizes get bigger.
More complexity.
You will never stop writing CSS.
Atomic CSS
The older your codebase is
The less CSS you will write.
Possibly none at all.

Maintainability

How do you know you have maintainable CSS?
When you no longer need to write any.

Immutability is Essential

Never Do This
.text-black { color:navy; }
Instead Do This
.text-navy { color:navy; }
Global Find and Replace text-black with text-navy
Or This
.text-primary { color:navy; }

Infinite Re-Usability

Single purpose, immutable classes
lead to...
conflict-free, reliable composability.

“Simple, obvious styles are quicker to internalize,
easier to use, and more widely adopted.”

Brent Jackson
Basscss Design Principles

Design Consistency

Force limitation on variations of spacing, typography, colors, etc.
Making a styleguide is helpful!
.bgr-blue
.bgr-blue-dk
.bgr-green
.bgr-green-dk
.bgr-pink
.bgr-purple
.bgr-grey
.bgr-red
.pad-0
.pad-1
.pad-2
.pad-3
h1, .text-120
h2, .text-96
h3, .text-64
h4, .text-48
h5, .text-36
h6, .text-24
body, .text-18
small, .text-14

Experimentation

Apply and remove styles on a web page like a painter working on a canvas
Animation of applying and removing Functional CSS classes

Productivity Boost

“Working with functional CSS, you’re spending 99% of your time in HTML. Your productivity is incredibly high because your brain doesn’t need to context switch between markup and stylesheet.”

Simon Vrachliotis
Full re-write in 10 days with tachyons and functional CSS: A case study

“Small tweaks like margin can be adjusted with a single class change in your HTML. It allows you to fix bugs without writing any additional CSS. I can’t even tell you how amazing this feels.”

Marcelo Somers
Rationalizing Functional CSS

I think of it like this...

Writing CSS is...

Planning
to build things

Writing HTML is...

Building
the things

Portability

Set custom spacing, typography, colors
and breakpoints for each new project.

Case In Point

Zero new classes* were written in the making of this preso
CSS generated via SASS config**

* Except for that pulsing button at the top. That was pretty cool.

** Built with the Expressive CSS Starter Kit and Simple Flex Grid

Not Just About File Size

It’s about file size over time.
It’s about CSS complexity at scale

My Experience

The evolution of my company’s CSS architecture

A few days before I started

2013–07–23
# of Commits
575
Test Suite
702
Repo Size
444MB
CSS Size
109.4k
(41 CSS files)

My first task: implement responsive web design

2013–09–03
# of Commits
925
Test Suite
743
Repo Size
465MB
CSS Size
123.1k
(41 CSS files)

Next task: Combine 41 stylesheets into 1

2013–09–07
# of Commits
1500
Test Suite
813
Repo Size
467MB
CSS Size
105.6k
(1 CSS file)

One year later...

2014–09–15
# of Commits
4812
Test Suite
1088
Repo Size
481MB
CSS Size
151.2k
(1 CSS file)

Using Traditional CSS

43%
growth of CSS size
3%
growth of repo size

Continued growth...

2015–05–06
# of Commits
7,726
Test Suite
1,373
Repo Size
485MB
CSS Size
183.2k

First optimization attempt
(removed unused styles, separate admin stylesheet)

2015–10–09
# of Commits
9,692
Test Suite
1,505
Repo Size
487MB
CSS Size
116.8k

Refactor to Functional CSS

2015–10–18
# of Commits
9,830
Test Suite
1,508
Repo Size
491MB
CSS Size
81.3k

Initial Results

30% reduction in CSS

Could have reduced further, but kept some legacy styles

A year and a half later...

2017–05–29
# of Commits
20,257
Test Suite
2,046
Repo Size
593MB
CSS Size
72.7k

10% smaller yet

(as we phase out legacy CSS)

For example...

New Feature
New View
New UI
Zero New CSS
Video clip of seating management tool

A Year and a Half with Atomic CSS

Gesture CSS File Size Over Time

To Open Source,
or Not to Open Source?

I abstracted the work into a library called Expressive CSS.

Then I sat on it for weeks.

Then I read this.

Building and Shipping Functional CSS Article
Building and Shipping Functional CSS Article

So I shipped this.

Expressive CSS Github Project Page
Expressive CSS Project Page

Then people said this.

Mattia says: What's this shit. You write CSS like 5 years ago.
Comment from
Content & Display Patterns with Expressive CSS

Why is Atomic CSS controversial?

Ugly HTML?

Glauber Ramos says: I am worried as well if this approach wont pollute too much the HTML, every div will have like 7 or more classes with unreadable names. Philip Ardeljan replies: It’s funny because since using functional CSS, my code has never been more readable. Before I would struggle to remember what styles .card-primary would have. So I’d have to load up the stylesheet/inspect the element in dev tools and read through the styles. Now I don’t have that problem.

HTML Bloat?

Chris Ferdinandi I’m not sure I see how having 10 different classes on a single element in your markup is any different than having just one and being overly specific in you CSS. You're simply moving the bloat from one place (your stylesheet) to another (your markup).

“If we put Gzip into the picture, things look better. That’s because a lot of repetitions means a better compression ratio.”

Atomic CSS FAQ

“HTML is much less difficult to reason about than layers of CSS inheritance.”

Sean Washington
CSS is hard — Thoughts on managing the cascade

A Trade-Off

Less classes in stylesheets.
More classes in HTML.

How is this different
from inline styles?

Joey D. Smith says: why not just use a style attribute if you're going to do this? Phil Wolstenholme replies: For one thing, inline CSS has a huge specificity whereas utility classes don't.

Excerpts from
How is tachyons different from inline styles?

“The most important difference is specificity.
Inline styles trump classes.”

Mark Otto
Creator of Bootstrap

“Inline styles do not support media queries or pseudo elements.”

“Inline styles are 1 to 1 for the browser.
While a class has a 1 to many relationship.”

“In the world of inline styles,
I have to memorize padding and margin values.
A codified system can have named sizes like S, M, L.

Adam Morse
Creator of Tachyons CSS

“If you’re using class names instead of inline styles, you won’t ever have a situation where one headline has 16px padding and another has 17px. You’re using your design system!”

“Using your already established conventions through class names gives you a beneficial constraint.”

Dan Mall
Founder and Director of SuperFriendly
Creative Director at Studio Zeldman

What about a redesign?

Dan Jones says: The problem with this approach, as I see it, comes when you decide to redesign your site. You've got all these CSS references that refer to particular styles that may no longer be relevant at all. So, now you have to go into your markup, and change all your classes to work with your new design.

“The theory that an entire site can or should be redesigned by just changing the CSS isn’t practical and doesn’t reflect how real designers and developers approach new projects.”

Philip Walton
“Defending Presentational Class Names”

( e.g., There are 4 versions of Bootstrap )

Bye Bye Cascade

Jack says: Fascinating thoughts on functional CSS although not sure I 100% agree with rejecting the cascade

Another trade off.

More cascade means more complexity.
Atomic CSS favors simplicity.

How about Accessibility?

Mike Donahue says: I’ve always considered how someone that can't view my site will hear it. Class names like .address or .name or .date (overly simplified for illustration purposes) will mean more to someone using a screen reader than .span-6 or most other presentational classes.
Assistive devices ignore class names.
Browsers do not care what your classes are named.
Users do not care what your classes are named.
The only people who do care are...
other developers!

What about Semantics?

Jeffrey Zeldman Vector Portrait

“SORRY. I disagree.
Nonsemantic classnames that refer to
visual styles will always be a bad idea.”

Jeffrey Zeldman
Web Pioneer
Kiss My Classname

“For individuals weaned on an ideology where ‘Semantic HTML’ means using content-derived class names, it usually requires you to work on a large application before you become aware of the impractical nature of that approach.”

“You have to be prepared to disgard old ideas, look at alternatives, and even revisit ways that you may have previously dismissed.”

Nicolas Gallagher
About HTML semantics and front-end architecture
March 15, 2012

“If you use templates, then giving a meaningful name to the file should be enough. In my opinion, limiting yourself to style things through semantic class names is counter-productive.”

Thierry Koblentz
Challenging CSS Best Practices
October 21, 2013

See also Opinions of Leaders Considered Harmful

“We have tags and attributes (ARIA, etc.) to describe content.”

“Our philosophy is that visual styling should be decoupled from content.”

John Polacek
Kiss My Classname: A Counterpoint

Some People Really Really Just Do Not Like It

The Problem With Atomic CSS

(Fun Fact: Medium is built with Atomic CSS)

Maybe try for yourself, then decide

Anthony Chilelli tweets: Reading about atomic made me apprehensive, using atomic made me wish I knew about it earlier.
Bonus points for writing about your experience!

Where is Atomic CSS
Used in the Real World?

Atomic CSS on Steroids
Developed at Yahoo
Configure with Atomizer
Very Popular
Extensive Components Library
Configure with PostCSS
Influential, Widely Used
Configure with PostCSS
From the Team
at Buzzfeed
Configure with SASS
From the Team
at TED
Configure with PostCSS
From the Team
at Gesture
Configure with SASS
Styleguide for Marvel App’s CSS
Extensive use of
Atomic-style
utility classes

How do I get started with Atomic CSS?

Starting a New Project

Pick a Framework

or...

Roll Your Own

(It’s not that hard)

Take a Framework Tour

Go Static

Get familiar with them, then make your own by adjusting the SASS, PostCSS, etc.

Go Programmatic

Don’t like shorthand?
Configure as you see fit.

Other Functional Flavors

For React
Getting Started with Tachyons and React

Read article

React Functional CSS Protips

Read article

CSS in JS
Styletron

View Project

Polished

View Project

Rolling Your Own

Configuration
  • Grid / Spacing / Layout
  • Typography
  • Colors
  • Utilities
  • Responsive Overrides

Managing Complexity

Template Organization is Key
Create Components with Partials/Fragments
Building a Library is Helpful

What about .btn?

“We should favor both approaches to achieve our goals. A ‘semantic’ name makes sense as a needed hook, not as a general rule.”

Thierry Koblentz
Challenging CSS Best Practices
October 21, 2013
<button class="btn bgr-red">

What about .card?

How about a template partial named card instead?

( Do what works for you )

What about Refactoring?

Analyze First
Get statistics on your CSS
See how much your site can benefit from Atomic CSS
Learn and compare your amongst 42 popular sites and frameworks

Decision Time

Go Gradual

or...

Bandaid Rip

Taking It Slow

Step 1

Find the most common style declarations in your CSS.

Step 2

Pick a theme
(e.g. typography, colors, spacing)

Replace with Atomic classes.

Go for big wins first.

Step 3

Repeat Step 2 until satisfied.

Rip That Bandaid

Step 1

Add Tachyons*
to the end of your CSS.

*or another Atomic library

Step 2

Do a first pass.

Methodically remove legacy classes, replace with Atomic classes.

Step 3

Kill all legacy CSS. Assess the damage.

Refactor to Tachyons, extend as needed.

Use other tools or restore legacy CSS only when necessary

Source

Full re-write in 10 days with Tachyons and Functional CSS: A case study
Read the full case study

The switch to Tachyons resulted in a 50% file size reduction and 75% fewer style declarations.

Exciting Times for the Front End

Always new things to try
Write about what you learn
Open Source your work

Questions?

Find me on Twitter @johnpolacek

Slides are at johnpolacek.com/rethinking

One more thing...

Built with
TweenDeck

Next level animation for web presentations

Go to TweenDeck on Github