Matt Hamlin

CSS Debate

If you aren't actively developing websites or web applications you might not know about the growing debate about one of my favorite web languages CSS. I want to dive into some of the history of how the debate originated, what exactly is being debated about and where we as web developers might be able to make some compromises as well.

If you don't fully know what CSS is or Javascript, I highly recommend learning more about both here first and then coming back here once you understand the basics of both.

History:

It is difficult to point to any one place where the fracture between both sides actually started, I have a feeling that minor fractures between each side started when componentization began to rise in the Javascript community.

With the rise of Javascript libraries and frameworks such as Backbone, then Ember, Angular, React and others many Javascript developers began separating their view logic from their business logic, this separation became known as the MVC paradigm and was and still is prevalent in different programming languages and entirely different environments than just on the web. This paradigm gave way to modern day componentization where developers wanted to compose their applications from a core library of patterns that they could reuse across different applications or websites to simplify development.

Componentization was the ultimate step towards keeping code DRY, meaning that developers didn't need to spend the time redeveloping the same dropdown every time a designer requests a dropdown. This drive lead to a group of engineers at Facebook to develop a very popular framework known as React. I don't have the time (or the effort) to dive into the background of React however React really made the fractures grow between developers who support CSS and those who don't.

The Great Debate really kicked off when an engineer at Facebook named Christopher Chedeau, gave a talk where he exposed some of the issues he and his team had seen with CSS while developing web applications and components at Facebook. The entire presentation can be summarized by the slide below but the entire slide deck is available here to read through.

The slide that started the great debate.

In the slide Christopher describes 7 issues with the way that CSS is currently spec'd out.

  1. Global Namespace
  2. Dependencies
  3. Dead Code Elimination
  4. Minification
  5. Sharing Constants
  6. Non-Deterministic Resolution
  7. Isolation

Now most of these issues only arise from having thousands of developers touching hundreds of thousands of lines of code all in a day, so for the most part the only issues that arise from CSS when adopting a React-like Javascript paradigm is the Cascade.

Core Issues:

Many of the points brought up by Christopher are indeed valid, but only valid from a javascript developer's mindset, and he even notes that in the following slides. So I will narrow down the core issues with CSS that almost everyone on the side arguing to eliminate the need for CSS can agree with.

  1. Global Namespace
  2. Inheritance, Source Order and Specificity
  3. Codebase Growth
  4. Static

Global Namespace:

CSS is, by nature, globally name-spaced. Every time a developer writes out the following they have declared a CSS "Global variable".

.myClass {
  ...;
}

Anytime this CSS is linked to a document with an element that has the class .myClass those styles will be applied to that element.

Inheritance, Source Order and Specificity:

This is a pretty tricky concept of CSS even for those who are used to programming in different languages. Inheritance means that a sibling element will inherit (some) styles from their parent node. If you want to inherit all styles from the parent you can simply style the child node and set every style you want inherited to be like the following: color: inherit;

Source order and Specificity are coupled together when considering CSS. Both are really tricky to understand as well, CSS, or rather CSS parsers, assign weights to selectors when parsing the CSS into an AST. The breakdown is as follows:

  • !important
  • Inline Styles via the style attribute
  • ID Selectors #foo { ... }
  • Class Selectors, Pseudo class selectors, attribute selectors
  • Element Selectors

These are commonly laid out as a comma separated list of numbers something like 0,0,0,0 (notice that there is no value assigned to !important). This is known as Specificity.

If you happen to have, in your CSS two selectors that target the same element the one with the highest specificity will win over no matter the order of your CSS. However if both selectors share the same specificity, then the one that was declared last will win out. Sometimes this convinces new CSS developers to naively move the styling they want to take effect to the bottom of their CSS document1

Codebase Growth:

This is something that is only highlighted when you have a codebase that has existed for any fairly long amount of time. This also isn't a concept that only happens in CSS, it happens to any codebase, it just becomes slightly more complicated because CSS is separated from the content that it is styling. This was solved in Javascript with the invention of JSX where React was able to move the content into the Javascript.

This issue doesn't only affect React applications though, at Wayfair I ran into this issue hundreds of times, where I was tasked with redesigning something and I need to decide whether to make a new file to style the stuff and add new classnames to everything or to spend the hours of time to search through the current styles and determine which need to stay and which need to remove. It gets even more complicated when you find out that the CSS you might be editing to fit your page/section is possibly in use somewhere else, so any edits you make will affect everyone else.

Static:

Prior to CSS4, every shared value in CSS had to be repeated when using it on a different element. So if you had defined your brand color across a few selectors or many selectors simply as the hexadecimal value you would have to do a search and replace on the code to change it if your brand colors changed.

This issue has mostly been addressed for us web developers, most organizations have solved this by introducing pre-processors into their workflow, at Wayfair we use SCSS and Grunt, on my personal projects I use PostCSS and Webpack. Even the CSS spec has added in ways to solve this with CSS Custom Attributes aka CSS Variables.

Resolving the Conflict:

CSS, as with every language for web development, is a growing standard with flaws. Some of these flaws are being addressed in newer editions, and some of these flaws are addressable by adapting your build processes. I intently believe that CSS has a ton of value in it's current form, and that as the people that write the spec add more and more value to the language.

I think build tools like CSS Modules can allow developers to build using the CSS standards and then in the background the build process handles the conversion of standard CSS to either inline styles or modules of scoped styles in the HTML.

I love web standards, and I love being able to use them but sometimes it feels like developers want to move towards using their own build process that takes this great new technology and converts it into old technology. Sure this is great for the end users but it also feels like a way to relieve the pressure put on browser vendors to add these new standards to their parsing engines.

So thats my take on the great CSS debate, feel free to reach out to me by tweeting to me, emailing me or texting me with your thoughts on whether CSS is good. I would also love to learn how you use CSS either at work or on your own projects!

Footnotes:


  1. Heck, even I did this when I was first getting interviewed for my current position at Wayfair because I didn't completely understand the concept yet 😄