As web developers, we marvel at technology. We enjoy the many tools that help with our work: multipurpose editors, frameworks, libraries, polyfills and shims, content management systems, preprocessors, build and deployment tools, development consoles, production monitors—the list goes on.

Article Continues Below

Our delight in these tools is so strong that no one questions whether a small website actually requires any of them. Tool obesity is the new WYSIWYG—the web developers who can’t do without their frameworks and preprocessors are no better than our peers from the 1990s who couldn’t do without FrontPage or Dreamweaver. It is true that these tools have improved our lives as developers in many ways. At the same time, they have perhaps also prevented us from improving our basic skills.

I want to talk about one of those skills: the craft of writing CSS. Not of using CSS preprocessors or postprocessors, but of writing CSS itself. Why? Because CSS is second in importance only to HTML in web development, and because no one needs processors to build a site or app.

Most of all, I want to talk about this because when it comes to writing CSS, it often seems that we have learned nothing since the 1990s. We still write CSS the natural way, with no advances in sorting declarations or selectors and no improvements in writing DRY CSS.

Instead, many developers argue fiercely about each of these topics. Others simply dig in their heels and refuse to change. And a third cohort protests even the discussion of these topics.

I don’t care that developers do this. But I do care about our craft. And I care that we, as a profession, are ignoring simple ways to improve our work.

Let’s talk about this more after the code break.

Here’s unsorted, unoptimized CSS from Amazon in 2003.

.serif { font-family: times, serif; font-size: small; } .sans { font-family: verdana, arial, helvetica, sans-serif; font-size: small; } .small { font-family: verdana, arial, helvetica, sans-serif; font-size: x-small; } .h1 { font-family: verdana, arial, helvetica, sans-serif; color: #CC6600; font-size: small; } .h3color { font-family: verdana, arial, helvetica, sans-serif; color: #CC6600; font-size: x-small; } .tiny { font-family: verdana, arial, helvetica, sans-serif; font-size: xx-small; } .listprice { font-family: arial, verdana, sans-serif; text-decoration: line-through; font-size: x-small; } .price { font-family: verdana, arial, helvetica, sans-serif; color: #990000; font-size: x-small; } .attention { background-color: #FFFFD5; }

And here’s CSS from contemporary Amazon:

.a-box { display: block; border-radius: 4px; border: 1px #ddd solid; background-color: #fff; } .a-box .a-box-inner { border-radius: 4px; position: relative; padding: 14px 18px; } .a-box-thumbnail { display: inline-block; } .a-box-thumbnail .a-box-inner { padding: 0 !important; } .a-box-thumbnail .a-box-inner img { border-radius: 4px; } .a-box-title { overflow: hidden; } .a-box-title .a-box-inner { overflow: hidden; padding: 12px 18px 11px; background: #f0f0f0; }

Just as in 2003, the CSS is unsorted and unoptimized. Did we learn anything over the past 15 years? Is this really the best CSS we can write?

Let’s look at three areas where I believe we can easily improve the way we do our work: declaration sorting, selector sorting, and declaration repetition.

Declaration sorting#section2

The 90s web developer, if he or she wrote CSS, wrote CSS as it occurred to them. Without sense or order—with no direction whatsoever. The same was true of last decade’s developer. The same is true of today’s developer, whether novice or expert.

.foo { font: arial, sans-serif; background: #abc; margin: 1em; text-align: center; letter-spacing: 1px; -x-yaddayadda: yes; }

The only difference between now and then: today’s expert developer uses eight variables, because “that’s how you do it” (even with one-pagers) and because at some point in their life they may need them. In twenty-something years of web development we have somehow not managed to make our CSS consistent and easier to work on by establishing the (or even a) common sense standard to sort declarations.

(If this sounds harsh, it’s because it’s true. Developers condemn selectors, shorthands, !important , and other useful aspects of CSS rather than concede that they don’t even know how to sort their declarations.)

In reality, the issue is dead simple: Declarations should be sorted alphabetically. Period.

Why?

For one, sorting makes collaborating easier.

Untrained developers can do it. Non-English speakers (such as this author) can do it. I wouldn’t be surprised to learn that even houseplants can do it.

For another reason, alphabetical sorting can be automated. What’s that? Yes, one can use or write little scripts (such as CSS Declaration Sorter) to sort declarations.

Given the ease of sorting, and its benefits, the current state of affairs borders on the ridiculous, making it tempting to ignore our peers who don’t sort declarations, and to ban from our lives those who argue that it’s easier—or even logical—not to sort alphabetically but instead to sort based on 1) box dimensions, 2) colors, 3) grid- or flexbox-iness, 4) mood, 5) what they ate for breakfast, or some equally random basis.

With this issue settled (if somewhat provocatively), on to our second problem from the 90s.

Selector sorting#section3

The situation concerning selectors is quite similar. Almost since 1994, developers have written selectors and rules as they occurred to them. Perhaps they’ve moved them around (“Oh, that belongs with the nav”). Perhaps they’ve refactored their style sheets (“Oh, strange that site styles appear amidst notification styles”). But standardizing the order—no.

Let’s take a step back and assume that order does matter, not just for aesthetics as one might think, but for collaboration. As an example, think of the letters below as selectors. Which list would be easiest to work with?

c, b · a · a, b · c, d · d, c, a · e · a c · b · a, b · a · c, d · a, c, d · a · e a, b · a, c, d · a · b, c · c, d · e

The fact that one selector (a) was a duplicate that only got discovered and merged in the last row perhaps gives away my preference. But then, if you wanted to add d, e to the list, wouldn’t the order of the third row make placing the new selector easier than placing it in either of the first two rows?

This example gets at the two issues caused by not sorting selectors:

No one knows where to add new selectors, creating a black hole in the workflow.

There’s a higher chance of both selector repetition and duplication of rules with the same selectors.

Both problems get compounded in larger projects and larger teams. Both problems have haunted us since the 90s. Both problems get fixed by standardizing—through coding guidelines—how selectors should be ordered.

The answer in this case is not as trivial as sorting alphabetically (although we could play with the idea—the cognitive ease of alphabetical selector sorting may make it worth trying). But we can take a path similar to how the HTML spec roughly groups elements, so that we first define sections, and then grouping elements, text elements, etc. (That’s also the approach of at least one draft, the author’s.)

The point is that ideal selector sorting doesn’t just occur naturally and automatically. We can benefit from putting more thought into this problem.

Declaration repetition#section4

Our third hangover from the 90s is that there is and has always been an insane amount of repetition in our style sheets. According to one analysis of more than 200 websites, a median of 66% of all declarations are redundant, and the repetition rate goes as high as 92%—meaning that, in this study at least, the typical website uses each declaration at least three times and some up to ten times.

As shown by a list of some sample sites I compiled, declaration repetition has indeed been bad from the start and has even increased slightly over the years.

Yes, there are reasons for repetition: notably for different target media (we may repeat ourselves for screen , print , or different viewport sizes) and, occasionally, for the cascade. That is why a repetition rate of 10–20% seems to be acceptable. But the degree of repetition we observe right now is not acceptable—it’s an unoptimized mess that goes mostly unnoticed.

What’s the solution here? One possibility is to use declarations just once. We’ve seen with a sample optimization of Yandex’s large-scale site that this can lead to slightly more unwieldy style sheets, but we also know that in many other cases it does make them smaller and more compact.

This approach of using declarations just once has at least three benefits:

It reduces repetition to a more acceptable amount.

It reduces the pseudo need for variables.

Excluding outliers like Yandex, it reduces file size and payload (10–20% according to my own experience—we looked at the effects years ago at Google).

No matter what practice we as a field come up with—whether to use declarations just once or follow a different path—the current level of “natural repetition” we face on sample websites is too high. We shouldn’t need to remind ourselves not to repeat ourselves if we repeat code up to nine times, and it’s getting outright pathetic—again excuse the strong language—if then we’re also the ones to scream for constants and variables and other features only because we’ve never stopped to question this 90s-style coding.

The unnatural, more modern way of writing CSS#section5

Targeting these three areas would help us move to a more modern way of writing style sheets, one that has a straightforward but powerful way to sort declarations, includes a plan for ordering selectors, and minimizes declaration repetition.

In this article, we’ve outlined some options for us to adhere to this more modern way:

Sort declarations alphabetically.

Use an existing order system or standardize and follow a new selector order system.

Try to use declarations just once.

Get assistance through tools.

And yet there’s still great potential to improve in all of these areas. The potential, then, is what we should close with. While I’ve emphasized our “no changes since the 90s” way of writing CSS, and stressed the need for robust practices, we need more proposals, studies, and conversations around what practices are most beneficial. Beneficial in terms of writing better, more consistent CSS, but also in terms of balancing our sense of craft (our mastery of our profession) with a high degree of efficiency (automating when it’s appropriate). Striving to achieve this balance will help ensure that developers twenty years from now won’t have to write rants about hangovers from the 2010s.