home | blog | slides

CSS whyyyyyy whyyy whyyyyyyyyy

Posted by Jason Rhodes on December 29th, 2014

Note: this is a stream of conscious style dump of some thoughts that have been in my head for over a year now about CSS. It was originally posted on BBS and in that spirit it's going to stay long, rambly, unfocused, and incomplete. Now that I've gotten you excited...

Alternate titles considered for this post:

Cant-even Style Sheets, or

CSS is Suffering, or

Spooky Selectors at a Distance, or

Some Random, Negative, and Not Necessarily Ground-Breaking Thoughts On CSS

Whenever I say that I really hate CSS, people seem to make one of several assumptions about me. Either I don't understand it very well, or I come from back-end development/computer science and I'm being disparaging or patronizing toward it.

Which is funny, because I don't come from a back-end/computer science background or from a design and art background. I come to the web from a nothing background, kind of. A "Religious Studies and Sociology double major" background, if you will. Never mind. I stumbled onto "web stuff" in a Barnes and Noble where I'd discovered Jeffrey Zeldman's Designing with Web Standards, which I read/skimmed while sitting on the floor for about an hour that day and then went back to revisit several times after that.

I just realized I probably should have bought the book at some point--sorry Zeldman, B&N, etc.

I wrote a ton of HTML and CSS back then and cobbled together some PHP and built shitty websites for people, the way you do. I wasn't a great designer and I knew fuck-all about programming, but I really loved making things out of HTML and CSS. I read A List Apart and had a Google Reader list full of Meyer and Shea and Zeldman and Cederholm etc. In 2009 I paid for my own flight to San Francisco and a not-cheap ticket to go to An Event Apart where I met Ethan Marcotte and saw Nicole Sullivan talk about Object Oriented CSS. I rode the wave of CSS3. I supported IE6. I memorized float hacks and quirks mode and all the rest.


I say all of that kind of annoying shit to make it clear that I know CSS and I appreciate its power and complexity and usefulness.

But then I discovered this talk by Rich Hickey called Simple Made Easy and I watch it a few times a year now. Hickey created a language called Clojure which I know almost nothing about, and which I have no plans to learn. But this talk, ohhhh this talk. A few of the things that stood out to me:

Simplicity is a prerequisite to reliability
--Edsger Dijkstra

Simple is different than easy and better than complex: infoq.com/resource/presentations/Simple-Made-Easy/en/slides/sl3.jpg

Simple is one braid:

Four truths:

Limits!

"complect" -> to interleave, intertwine
"compose" -> to place together

Programming ... boils down to no more and no less than very effective thinking so as to avoid unmastered complexity, to very vigorous separation of your many different concerns
--Edsger Dijkstra


CSS is complected by design. The cascade is complection by definition. Complected Style Sheets, pretty much. Consider this CSS:

section.container div {
  background-color: red;
}

body section div {
  background-color: green;
}

What background color is that div?

Imagine if collisions like this were a compile-time syntax error...

If you said 'red' because the class selector is more specific than the element selector, you might be right. But the best answer is probably "no idea" because you don't know if there's another matching selector further down the page, or a slightly more specific one anywhere else, or inline styles in the HTML, or a matching !important declaration anywhere...

The fact is that you can't look at a decent-sized set of stylesheet selectors and confidently figure out what the effect is until you see it in the browser. That should terrify you, I think.

[A bunch of hands in the room go up.]

This isn't just a side-effect of bad CSS, either.

[Hands go down.]

The cascade is designed to tempt you to override all the things, ie overload and complect. You could have defined a whole set of carefully set CSS properties and one of them can be so easily over-ridden by any other matching selector somewhere else in your stylesheet system. In programming we borrowed a term for this from Einstein, called "spooky action at a distance". It's not a good thing.

This article from Technology Review explains a little about spooky action using the term "entanglement". A couple of good quotes:

Entanglement occurs when two particles are so deeply linked that they share the same existence.

.

Entangled particles can become widely separated in space. But even so, the mathematics implies that a measurement on one immediately influences the other, regardless of the distance between them.

This is generally a bad thing and makes it hard for you to reason about what's happening in your code. Which makes it harder to change and harder to debug and harder to maintain as it grows.

So we have a language that's built on the idea that complection, or cascade, is fundamentally good when in traditional programming we try to avoid it if we can. You have selector specificity that relies on a formula that's nearly impossible to remember, and pretty much any CSS loaded anywhere is "global" and can affect any other CSS loaded in a 'spooky at a distance' kind of way. So what did we do with that system?

We built another level of complection right on top of it, of course! Enter: media queries. Now depending on the state of the browser, which you can't replicate outside of the browser, different sections of global cascading CSS selectors will apply and override other global cascading CSS selectors. Perfect! Now you can have this situation:

@media (max-width: 600px) {
  .container a {
    color: green;
  }
}

li a {
  color: red;
}

.nav a {
  color: black;
}

What color is the link? Now it's dependent on the cascade, the HTML structure it's within and the width of the browser, which I understand is by design for very good reasons but wow does it make it hard to think about anything!

You could argue that CSS good practices and general programming good practices are opposites in some regard. Embracing the cascade and leveraging it, like mobile-first responsive design encourages you to do, is opposite to the advice that you should keep code simple and de-coupled from other parts of your code.

So I get it, there's no better solution that I know of besides CSS and media queries. We have to use them, it's the only visual design solution we have and when we use them intelligently they can do some powerful, awesome things. But they're difficult and susceptible to inflexibility and strange frustrating bugs and other common problems because the system is built on the idea that complecting is good and should be leveraged. That's hard to overcome.

I think that's why we're seeing so many new CSS strategies designed to avoid and ignore the cascade altogether. BEM, for instance, SMACSS to some extent, OOCSS (not very new) -- and a bunch of other even newer CSS abstractions and strategies aimed at adding descriptive classes to nested elements and sidestepping the cascade to create a more reliable, simple system.

Simplifying, decomplecting. Good things, in my opinion, for how to deal with what we're dealt. Because CSS isn't going anywhere and we sure as hell need it.

::still thinking through more ways to overcome this problem::

Note: check out Caleb's BBS post for thoughts on one possible, experimental solution to some of these cascade problems.

Warning: Comments ahead. Never read them.