There are a number of ways to write style sheets. The domain of style guides, many of them go into some detail. What I, despite my work on a number of guides, including the Google HTML and CSS style guide, have so far missed, is a conclusive reference to sort selectors and rules. I’ve mostly operated with a rough sketch, but that sketch is rough as it’s far from being comprehensive.

In this document I’m proposing an order for selector and rule sorting, for anyone who has a need for more structure. A firm believer in the usefulness of alphabetical sorting of declarations, I don’t deem alphabetical sorting particularly useful for selectors. Unfortunately that suggests a slightly more complicated set of rules.

Specificity Has the Right of Way

Before we begin, note that the location of a rule can make a difference: If two declarations have the same weight, origin, and specificity, the latter specified wins. Always keep this in mind when ordering style sheets, especially when moving a rule from one end of a style sheet to the other. Rare as they are, surprisingly, sometimes you will need to make exceptions.

Part I: General Sorting

The following are high level sorting ideas. They may overlap. This sorting applies to selectors for any given rule, rules themselves, and also sections, that is, groups of rules (consider using comments to mark sections).

1. By Purpose

First, group conceptually: What are rules and sections about? All the general site styling should be in one section or module. Grid styling in another. Navigation handling in yet another.

If a rule conceptually belongs to two or more groups, consider going by the first selector, or spawning a “General” or “Misc” section.

2. By Importance

Then, sort by importance. More important rules and sections should come before less important ones.

3. From Generic to Specific

Next, sort by impact: What affects the higher number of elements, and higher level elements, should come before the more specific selectors. Although you could have the same number of elements on which either selector matches, this applies to the different types of selectors, too: Go from type selectors over class selectors over attribute selectors (that are not targeting @class or @id) to ID selectors.

For sequences of simple selectors, or “complex” selectors like p em or .error strong, sort by the first simple selector, then the next, &c.

❧ When sorting rules, use the first selector of each rule to determine the rule’s location, both within a section and within the style sheet. Do this after all the rules’ selectors have been sorted. That also means that when writing something like section.warning instead of .warning, the position of the rule within the style sheet could change, as you’d end up sorting by the element (section) and not the class (.warning).

Part II: Element Sorting

This is a suggestion how to sort specific selectors precisely. Similar to the high level sorting, it applies to all selectors, per rule, and per section.

The list features type selectors for elements from HTML 5—on recurring request I would add all the other elements. In parentheses: elements that are normally hidden and not normally styled. In square brackets: non-HTML elements.

1. Universal

* (only when used explicitly)

2. Document

html

3. Meta Data

(head)

(title)

(base)

(link)

(meta)

(style)

(script)

(noscript)

4. Sectioning and Structuring

body

header

footer

nav

main

article

aside

section

p

pre

blockquote

figure

figcaption

address

summary

details

div

5. Headings

hgroup

h1

h2

h3

h4

h5

h6

6. Lists

ul

ol

li

dl

dt

dd

menu

menuitem

7. Media

canvas

object

embed

img

audio

video

(param)

(source)

track

map

area

[svg]

[math]

iframe

8. Forms

form

fieldset

legend

label

input

button

select

optgroup

option

datalist

textarea

output

9. Tables

table

caption

colgroup

col

thead

tfoot

tbody

tr

th

td

10. Phrasing

a

strong

em

b

i

u

s

sup

sub

small

abbr

dfn

mark

del

ins

q

cite

data

progress

time

meter

code

var

samp

kbd

keygen

bdi

bdo

ruby

rt

rp

span

11. Misc

hr

(br)

(wbr)

dialog

12. Attributes

.class

#id

The suggestion is based on experience and well some common sense, yet it’s indeed a little arbitrary. We had to start somewhere.

Examples

High Level Sorting

Very brief, the following demonstrates high level sorting with a few random rules that we transform from

#bio {}
#bio, p {}
.authors {}
html {}
#gallery, .authors {}

into

/* Comes first because of purpose: */
html {}
/* Reversed order to go from generic to specific; also more important: */
p, #bio {}
/* Reversed order to go from generic to specific; moved to allow grouping with other .authors rule: */
.authors, #gallery {}
/* Grouped with .authors/#gallery rule, and following after because more specific: */
.authors {}
/* Comes last because it’s most specific: */
#bio {}

Example Style Sheet

Last, a complete example using World’s Highest Website’s default style sheet (following the rules of this document as well as the Google HTML and CSS style guide):

Working with this Sorting

Independent of the examples, I’m still thinking how to best demonstrate work with this rule set. First, it’s not trivial, and second, it really depends on your preferences. You could use it to determine the location of each rule while writing your style sheets. You could take care of sorting by sections first to then sort the rest. You could sort once you’re done with everything. You could also just use the selector order as proposed in part II. I welcome thoughts on whether any how-to on this would be useful, and on how to make that how-to itself most useful.

Update (February 7, 2014)

About the Author

Jens Oliver Meiert is an author and developer (O’Reilly, W3C, ex-Google). He plays with philosophy, art, and adventure. Here on meiert.com he shares and generalizes and exaggerates some of his thoughts and experiences.

Comments (Closed)

Good to see that others are seeing this problem. I have countless times had to deal with terrible CSS messes being left by others.

I agree with your general sorting rules. There are times the answer isn’t quite clear, though, but that’s fine if you at least organize the rules in a modular manner. I personally prefer dividing all my CSS rules into separate style sheets and combine them in the production environment.

Even though looseness is a good thing in general, it presents problems. CSS is a bad technology, plain and simple, just like HTML, but that’s another discussion.

At the moment, I am encountering this same problem while trying to fix/re-factor a custom library. I have been thinking along the same lines as you and hope that some general consensus can be reached that allow for a “standard” to be arrived at, as Jean-Philippe Martin commented.