CSS Selectors & Specificity

CSS Selectors & Specificity

by Kenny Porterfield | Mon, Jul 12 2021

Category: HTML & CSS

The first part of writing CSS is specifying what you want to target with the styles you're about to write. It helps to know what all of the options are. In addition, being able to read, and write, good CSS depends on writing good selectors. However, it is very easy and common to not take the time to fully learn all of this stuff and go straight onto just writing CSS, and resort to hacky code to resolve conflicts when they inevitably arise. This is what makes style sheets unpleasant to work with as sites grow. You don't want to just start slapping !important all over the place. As style sheets grow, that just makes them more confusing and difficult to debug. You want to be as specific as it makes sense to be when it comes to writing your selectors, so that they are easy to read and clearly communicate what they target. You can go too far, be too specific, with selectors, and that can make your CSS more difficult to read and provides no additional value. In order to write selectors that make sense, clearly communicate what they're targeting, and avoid conflicts–you need to know selectors and specificity. So, in this blog post I set out to cover CSS selectors and specificity, in order to provide a solid foundation for writing better CSS. 

 

Selectors

CSS selectors can be divided into 5 categories:

  • Simple selectors (select elements based on name, id, class)
  • Combinator selectors (select elements based on a specific relationship between them)
  • Pseudo-class selectors (select elements based on state)
  • Pseudo-elements selectors (select and style part of an element)
  • Attribute selectors (select elements based on an attribute or attribute value)

Simple Selectors

All CSS Simple Selectors

Selector Example Example description
#id #firstname Selects the element with id="firstname"
.class .intro Selects all elements with class="intro"
element.class p.intro Selects only p elements with class="intro"
* * Selects all elements
element p Selects all p elements
element,element,.. div, p Selects all div elements and all p elements

Combinator Selectors

A CSS selector can contain more than one simple selector, this is what is referred to as a combinator selector. Between the simple selectors, we can include a combinator.

 

There are four different combinators in CSS:

 

descendant selector (space)

  • The descendant selector matches all elements that are descendants of a specified element. The following example selects all p elements inside div elements:
div p { background-color: yellow;}

 

child selector (>)

  • The child selector selects all elements that are the children of a specified element. The following example selects all p elements that are children of a div element:
div > p { background-color: yellow;}

 

adjacent sibling selector (+)

  • The adjacent sibling selector selects an element that is directly after another specific element. The following example selects the first p element that is placed immediately after div elements:
div + p { background-color: yellow;}

 

general sibling selector (~)

  • The general sibling selector selects all elements that are next siblings of a specified element. The following example selects all p elements that are next siblings of div elements:
div ~ p { background-color: yellow;}

 

Pseudo-Class Selectors

A pseudo-class is used to target the specific state of an element. For example, it can be used to style an element like a link or a button when a user mouses over it, or style visited and unvisited links differently, or style an element when it gets focus, etc.

 

The syntax of pseudo-classes is:

 

selector:pseudo-class { 
  property: value;
}

 

There are many pseudo classes, a full list can be referenced here: https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes

 

For simplicity, we'll just demonstrate some of the pseudo classes used on links, which are very common.

 

/* unvisited link */  
a:link { color: #FF0000;}  
  
/* visited link */  
a:visited { color: #00FF00;}  
  
/* mouse over link */  
a:hover { color: #FF00FF;}  
  
/* selected link */  
a:active { color: #0000FF;}

 

Pseudo-Element Selectors

CSS pseudo-element selectors are used to style specific parts of an element. For example, they can be used to:

  • Style the first letter, or line, of an element
  • Insert content before or after an element

The syntax of a pseudo-element selector is similar to a pseudo-class selector, but has 2 colons (::):

 

selector::pseudo-element { 
  property: value;
}

 

Multiple pseudo-elements can be combined. To show a simple example, the following code will set these styles on the first letter and first line of each element, but everything after the specified pseudo-elements will not be targeted by these rules.

 

p::first-letter {
  color: blue;
  font-size: 2em;
}

p::first-line {
  color: green;
  font-variant: small-caps;
}

 

A full list of pseudo-elements with specifications can be found here: https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements

 

Attribute Selectors

Attribute selectors make it possible for you to target HTML elements that have specific attributes or attribute values. The [attribute] selector is used to select elements with a specified attribute. The following example selects all a elements with a target attribute:

 

a[target] { text-decoration: underline; }

 

The [attribute="value"] selector is used to select elements with a specified attribute and value. The following example selects all a elements with a target="_blank" attribute:

 

a[target="_blank"] { border: 1px solid yellow; }

 

The [attribute~="value"] selector is used to select elements with an attribute value containing a specified word. The following example selects all elements with a title attribute that contains a space-separated list of words, one of which is "header":

 

[title~="header"] { border-bottom: 5px solid yellow; }

 

In addtion, you have the following attribute selectors:

  • [attribute|="value"] - Select elements with the specified attribute starting with the specified word.
    • Note: The value has to be a whole word, either alone, like class="top", or followed by a hyphen( - ), like class="top-text"!
  • [attribute^="value"] - Select elements whose attribute value begins with a specified value.
  • [attribute$="value"] - Select elements whose attribute value ends with a specified value.
  • [attribute*="value"] - Select elements whose attribute value contains a specified value.

Attribute selectors can be particularly helpful for styling forms without using classes or IDs.

 

Specificity

If there are two or more conflicting CSS rules that point to the same element, the browser follows some rules to determine which one is most specific and therefore wins out. This is what is called specificity. Specificity is a common culprit behind why your CSS doesn't apply to some elements at times when you think they should. CSS Specificity goes in this general order (from most to least specific):

 

Inline styles -> IDs -> Classes, attributes and pseudo-classes -> Elements and pseudo-elements

 

At a high level, it's important to remember that any inline styles will win out over any other styles. ID selectors will win out over class or element selectors. Class selectors will win out over element selectors.

 

You can calculate specificity using the following method.

  • If the element has inline styling, that automatically wins (1,0,0,0 points)
  • For each ID value, apply 0,1,0,0 points
  • For each class value (or pseudo-class or attribute selector), apply 0,0,1,0 points
  • For each element reference, apply 0,0,0,1 point

You can generally read the values as if they were just a number, like 1,0,0,0 is “1000”, and so clearly wins over a specificity of 0,1,0,0 or “100”. The commas are there to remind us that this isn’t really a “base 10” system. You could technically have a specificity value of like 0,1,13,4 – and that “13” doesn’t spill over like a base 10 system would. The universal selector and inherited values have a specificity of 0.

 

If 2 rules have the exact same specificity, or are the same rules, in the external style sheet, then the lower rule in the style sheet is closer to the element to be styled, and will be applied.



Check out other HTML & CSS blogs.

Comments

Login or create an account to leave a comment.

Recent Blog Posts

Get in touch

Kenny Porterfield
kjport3@gmail.com
LinkedIn

Or, send me a message from here: