Jens Oliver Meiert

How to Order CSS Selectors

Post from January 30, 2013 (↻ November 8, 2014), reflecting Jens the .

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 style 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.

I’m writing for inspiration; please share your thoughts. (I might be slow but will be sure to respond.)

Index

  1. Specificity Has the Right of Way
  2. Part I: General Sorting
    1. By Purpose
    2. By Importance
    3. From Generic to Specific
  3. Part II: Element Sorting
    1. Universal
    2. Document
    3. Meta data
    4. Sectioning and structuring
    5. Headings
    6. Lists
    7. Media
    8. Forms
    9. Tables
    10. Phrasing
    11. Misc
    12. Attributes
  4. Examples
    1. High Level Sorting
    2. Example Style Sheet
  5. Working with this Sorting
  6. Update (February 7, 2014)

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. 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 exactly. 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):

@import url(//fonts.googleapis.com/css?family=Droid+Sans:400,700);

@media screen, projection {

  * {
    margin: 0;
    padding: 0;
  }

  html {
    background: #000;
    color: #ccc;
    font: 87.5%/1.7 'droid sans', optima, arial, sans-serif;
    text-align: center;
  }

  body {
    margin: 1em 0;
  }

  h1,
  h2 {
    font-size: 1em;
    font-weight: normal;
  }

  h1 {
    background: url(../../media/logo.jpg) no-repeat;
    height: 366px;
    text-indent: -999em;
    width: 620px;
  }

  h2,
  p {
    margin: 0 .5em;
  }

  p + p {
    text-indent: 1em;
  }

  p#ref {
    background: url(../../media/end.jpg) no-repeat bottom center;
    margin: 1.5em 0 0;
    padding-bottom: 179px;
  }

  ul {
    margin: .5em 0 .5em 1.5em;
  }

  ul#lang {
    list-style: none;
    margin: .5em 0 1em 1.5em;
  }

  ul#lang li {
    display: inline;
  }

  a,
  strong,
  em,
  kbd {
    color: #fff;
  }

  strong {
    font-size: 1.3em;
    line-height: 1.0;
  }

  em {
    font-style: normal;
  }

  kbd {
    font-family: 'droid sans', optima, arial, sans-serif;
  }

  #show {
    margin: auto;
    text-align: left;
    width: 619px;
  }

  #whws {
    background: url(../../media/tape.gif) repeat-y top center;
    font-size: 100cm;
    height: 4734em;
    line-height: 1.0;
    margin: 42px 0;
  }

  #whws + div {
    position: relative;
  }

}

/* Print rules omitted */

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.

Thanks Tony Ruscoe for reviewing and helping to improve this article.

Update (February 7, 2014)

This order did not so far cover RTL selectors. Until I get to update the article I suggest a “local” placement as with

#example {
  text-align: left;
}

[dir=rtl] #example {
  text-align: right;
}

Comments (Closed)

  1. On January 30, 2013, 16:18 CET, Jean-Philippe Martin said:

    Very helpful. Let’s hope a common “standard” emerge.

  2. On February 4, 2013, 14:33 CET, Are Nybakk said:

    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.

  3. On July 29, 2013, 18:44 CEST, Cesidio DiBenedetto said:

    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.

  4. On August 14, 2014, 15:04 CEST, Jens O. Meiert said:

    This post is also available in German.

Read More

Have a look at the most popular posts, eventually including:

Or maybe say hi on Google+, Twitter, or LinkedIn?

Found a mistake? Reward! Email me, jens@meiert.com.

You are here: meiert.comArchive for 2013 → How to Order CSS Selectors

Last update: November 8, 2014.