Why "Build Shit in CSS"?

A few years back, I gave a short talk on CSS to a group of programmers at a Giant Tech Company. The audience: a small group of pretty smart (but junior) developers who built web apps every day.

The first section was a quick overview of how specificity works. 10 seconds into explaining how each type of selector trumped the rest, the room filled with a murmur of aha moments from dev who'd been struggling for months to hack their way around Bootstrap with no idea why their code didn't work.

It makes sense how this happens. Computer Science programs don't teach pool of domain knowledge behind implementing difficult UI's. That's not a bad thing - it's just outside the scope of their goals.

But if you're a junior developer, where do you go to acquire The Knowledge? It's spread across blog posts, talks and books, but I can't point to a single "start here" resource the way I can for Python or Javascript.

At the request of people (aka @rebeccaestes) who wanted to learn, I wrote Build Shit in CSS to cover weird but important topics like how to work with floats, the practical difference between display properties, and other pieces of an intellectual toolkit that you use to make UI (including "when in doubt, check MDN.").

An aside

Programming land has a problem: our documentation tends to be really good as a reference, but terrible at explaining ideas to people who don't understand them already.

To be fair, writing about a topic in a way that makes sense to a person who knows nothing about it is an art form.

On Architecture

To keep the scope under control, Build Shit had to be focused on specifics. What it doesn't go into is how to create maintainable CSS. And I've heard developers and big, high power companies discuss their struggles with this.

Some people have gone so far to decide they shouldn’t use any of CSS’s features at all, and write stuff like <button class="button u-marginTop10 u-xs-marginTop20">...</button>. This is insane, and seems to be popular with a certain crowd that believes CSS is fundamentally broken.

They’re wrong. A hammer is also a perfectly good and hitting your thumb with it doesn’t make it otherwise.

Here’s a better approach:

Create minimal base styles that cover standard typography and raw elements. These should be unopinionated and never change, unless you're changing your workhorse fonts and colors.

/* This should be boring and never change */
body {
  font-family: "Helvetica Nueue", Helvetica, Arial, sans-serif;
  font-size: 16px;
  color: black;
  background: white;
}

h1, h2, h3, h4, h5 {
  margin: 0.5em 0;
}

/**
 * But definitely don't do this. You should avoid base styles
 * that you'll often need to override.
 */
button {
  background: red;
}

Everything else should be a namespaced component.

/**
 * You can see this code only affects elements constained inside 
 * the site-nav. A component is one discrete thing. It can be very detailed,
 * but the goal is to be able to work on it without surprising
 * side effects.
 */
.site-nav {...}
.site-nav li {...}
.site-nav a {...}
.site-nav .subnav {...}
.site-nav .social {...}

You can safely edit this code and know it only affects one thing, which you can look at as you make changes, and be confident that your changes won't have side effects elsewhere.

Here's what happens when you don't namespace your styles:

h2 {color: red; font-size: 15px; margin: 0;}
/* Now you have to override this everywhere you don't want h2's to be red. */

/* In some other file */
.blog-post h2 {color: black;}

/* In another file */
.contact-form h2 {...}  // I actually want this to be red

Now, if you decide h2's shouldn't be red anymore, you have no idea where that base style is being depended on, and can't be sure your change is safe without checking the entire site.

This is especially useful when building responsive sites. Then you can implement the components behavior at different breakpoints in the same spot, and all knowledge of this particular UI element lives in one place.

This next example is written in SASS.1

// Keep all the CSS behavior of a selector
// together, so you can see the whole picture
// while you're working on it.
.site-nav li {
    float: none;
    width: 100%;
    @media (min-width: 640px){
        float: left;
        width: 25%;
    }
}

Will all the CSS be perfect? No. But this way if you wander into a file to change or fix something, you can be sure that you'll only affect the components that you're looking at right now, and the changes won't trickle into other tightly bound code.

BEM is a style of naming classes that uses strategy, just with very verbose class names. You don’t need it to write sustainable CSS, as long as you’re thoughtful about what your components are and keeping them namespaced.2

To Be Continued

I'm looking to expand Build Shit in CSS, so if there's another exercise you think I should cover, open an issue on Github.


  1. Sass is great and totally worth learning. 

  2. I have mixed thoughts on BEM, semantic classes, and the dozen or so other naming schemes big companies are actively promoting. Some of their ideas are good. None of them, taken wholesale, are “industry standard.” If a coding style speaks to you, that’s great, but the developers of a given project should always make their own decisions.