Theming basics you need to know Vol.1 - Specificity

25 March 2017

You may be a beginner and just starting to learn to style your HTML or have been a web dev for while and haven’t quite mastered the art, in that case, then these articles are for you.

Through my experience, I’ve noticed a few key principles, of CSS, that has massively helped me to become a far better themer with cleaner code and faster delivery. Benefits all round for the team. I've used this post to outline one principle further. 

Enjoy!!!

Specificity

So what is specificity? Specificity is one of the fundamentals of CSS, it’s the value(weight) that allows certain styles to have precedence over another. For example:

/**
 * Assuming the code blocks selected the same element.
 *
 * This code block will have precedence over the one below it. Because is has a
 * greater specificity regardless of where I place the code block in the file. 
 * element background will be red.
 */
 #id .class div {
  background: red; 
}

.class div {
  background: green;
}

 

By applying more selectors to your code block will add together for a greater specificity. Simple enough, right? Well, yes and no. It’s sometimes easier to look as specificity like this:

Although the above illustration looks and feels right and will probably work out for you 99.99% of the time it still isn't correct. For example:

/**
 * Assuming the code blocks selected the same element.
 *
 * The blue background will take precedence over red background but green 
 * background would overriding both. Example;
 * - blue: 32
 * - red: 22
 * - green: 101
 */
/* 3 class(10) + 2 element(1) = 32 */
.class .another-class .and-another-class  ul li {
  background: blue;
}
/* 2 class(10) + 2 element(1) = 22 */
.class .another-class ul li {
  background: red;
}
/* 1 id(100) + 1 element(1) = 101 */
#id li {
  background: green;
}


/**
 * Assuming the code blocks selected the same element.
 *
 * If the illustration above where true the blue background would persist over
 * both because it would have a higher value:
 * - blue = 12
 * - green = 11
 * - red = 10
 *
 * However this is not the case. Red precedence blue and green would have persist 
 * over both.
 */
/* 1 class(10) = 10 */
.class {
  background: red;
}
/* 1 class(10) + 1 element(1) = 11 */
.class span {
  background: green;
}
/* 12 elements(1) = 12 */
html body div div div div div div ul li a span {
  background: blue;
}

 

A correct illustration would be this:

 

So 10 or more Elements can not override a Class, 10 or more can not override an ID and 10 or more ID’s can not override a Style Attribute.

If you have 2 code blocks with the same value the code block that is executed last will take precedent over the first:

/**
 * Assuming the code blocks selected the same element.
 *
 * The value in each of these sections are both equal but the anchor element 
 * will display the color green because that block of code was called last.
 */
/* 1 ID = 1 > 1 class + 1 attribute + 1 pseudo-class = 3 >  1 element = 1 */
#id[data-type="blue"] .class a:visited {
  color: blue;
}
/* 1 ID = 1 > 2 classes + 1 pseudo-class = 3 >  1 element = 1 */
.class.another-class:nth-child(2n) a#some-id {
  color: green;
}

Selectors with no values

The wildcard selector (*) and the not pseudo-class selector (:not) have no values. However, the selector passed through the parenthesis of the not pseudo-class will be added to its respective selectors.

/**
 * Assuming the code blocks selected the same element.
 *
 * The color pink persist of red because the wildcard(*) selector has no value and
 * the pink was called last.
 */
/* 1 class = 1 >  1 element = 1 */
li.class * {
  color: red;
}
/* 1 class = 1 >  1 element = 1 */
.class a {
  color: pink;
}


/**
 * Assuming the code blocks selected the same element.
 *
 * The purple would override the yellow because of the class parenthesis and not
 * the (:not) pseudo-class.
 */
/* 1 ID = 1 > 2 classes  = 2 */
.class:not(.another-class) #id {
  color: purple;
}
/* 1 ID = 1 > 1 class  = 1 */
.class #id {
  color: yellow;
}

The significance of specificity

Why does knowing about specificity have so much significance apart from the obvious, to implement CSS styles? The significance is how and when to use specificity. There are good and bad ways to do this.

The good way to do this is to keep specificity low! You want to do enough to get your style across but no more. You want your styles to be able to be easily overridden with minimal effort (specificity). So for good coding practice:

  • Avoid using !important on properties like the plague.
  • Don’t use Style attributes in your templates, have some self-respect.
  • Use id’s only if necessary.
  • Try to restrict nesting selectors to about 3.

What the advantages of good practices:

  • Easier overriding a general styles.
  • Ability to implement more intricate selectors with minimal effort.
  • Cleaner and more understandable code.
  • Saves time.
  • Works great when implementing Atomic Design(Something I’ll dive into another day).

Notes

I'll be writing more about other principles in future posts so keep an eye out.