Loading...

Specificity, it's a game changer!

Now that multiple pages of an entire website may be sharing the same rules, you will need to be more precise with your selectors. In some cases, it makes sense to use generic selectors for things like setting the font family, font sizes, font colors, margins, padding, and anything else that you want to be consistent throughout your website. These are generally referred to as "global styles."

video game concecept illustration

Anything that is not a global style should use ids, classes, and pseudo selectors to target elements on your page for styling. We can divide CSS selectors into five categories:

  1. Simple selectors (select elements based on name, id, class)
  2. Combinator selectors (select elements based on a specific relationship between them)
  3. Pseudo-class selectors (select elements based on a certain state)
  4. Pseudo-elements selectors (select and style a part of an element)
  5. Attribute selectors (select elements based on an attribute or attribute value)

Below is an activity to help you practice specificity in your styling. In this activity, you'll think of CSS in terms of a video game. The highest point values are awarded to the styling closest to the content and with the most specificity. Click through the tabs below to see the point system and then try determining which types of CSS have the most specificity.

Four categories define the specificity level of a selector and its ranking:

  1. Inline styles: 1000 points - Example: <h1 style="color: pink;">
  2. IDs: 100 points - Example: #navbar
  3. Classes, pseudo-classes, attribute selectors: 10 points - Example: .test, :hover, [href]
  4. Elements and pseudo-elements: 1 point - Example: h1, ::before

Let's see some basic selector/selector combinations to understand how the point values work.

Selector Specificity Value Calculation
p 1 1
.test 10 10
p.test 11 1 + 10
p.test1 .test2 21 1 + 10 + 10
#demo 100 100
p#demo 101 1 + 100
#navbar p#demo 201 100 + 1 + 100
<p style="color: pink;"></p> 1000 1000

You want to target the first image in your page and float it to the right. Which method of CSS would provide the highest specificity?

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Example Page</title>
  </head>
  <body>
    <img src="/image1.jpg" alt="example1" class="float"/>
    <p>Lorem ipsum dolor ...</p>
    <img src="/image2.jpg" alt="example2"/>
    <p>Duis aute irure ...</p>
    <p>Ut enim ad ...</p>
  </body>
</html>

Option 1

<style>
  img.float {
     float: right;
     margin: 0px 0px 10px 10px;
  }
</style>

Option 2

<style>
  body img:first-child {
     float: right;
     margin: 0px 0px 10px 10px;
  }
</style>
character 1 vs character 2

11 points vs 12 points

This one was close! In this scenario, Option 2 has the higher specificity with 12 points, which takes priority over Option 1, with 11 points.

You have an ordered list that you are trying to adjust. You want the margin increased below each line item for better readability. Which selection method would have the highest level of specificity?

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Example Page</title>
    <!--CSS File-->
    <link rel="stylesheet" type="text/css" href="MainStyling.css"/>
    <link rel="stylesheet" type="text/css" href="SpecialFeatures.css"/>
  </head>
  <body>
    <h2>Lorem Ipsum</h2>
    <ol id="alpha-list">
      <li>...</li>
      <li>...</li>
      <li>...</li>
    </ol>
  </body>
</html>

Option 1

/*SpecialFeatures CSS File*/

ol#alpha-list li {
  margin-bottom: 5px;
}

Option 2

/*MainStyling CSS File*/

ol#alpha-list li {
  margin-bottom: 10px;
}
character 1 vs character 2

102 points vs 102 points

In this case, we have the exact same selection method but two conflicting style declarations. So, which one takes priority? In this case, Option 1 takes priority because it was the second style sheet linked to the HTML document. Browsers parse from the top down, and since the second style sheet is closer to the actual page content, it overrides the styling of the same selectors in the first style sheet linked.

You have a table you would like to style. You want make every other row pink with the text bolded and set to a serif font. Which styling method has the highest level of specificity and will take priority?

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Example Page</title>
    <link rel="stylesheet" type="text/css" href="MainStyling.css"/>
  </head>
  <body>
    <section class="side-by-side">
     <div>
       <img src="/image.jpg" alt="example"/>
       <p>Duis aute irure ...</p>
     </div>
     <div>
      <p>Lorem Ipsum...</p>
      <table>
        <tbody>
          <tr> <!--Row 1-->
            ...
          </tr>
          <tr><!--Row 2-->
            ...
          </tr>
          <!--Row 3-->
          <!--Row 4-->
          <!--Row 5-->
        </tbody>
      </table>
     </div>
    </section>
  </body>
</html>

Option 1

<style>
  section div table tbody tr:nth-child(even) {
    background-color: pink;
    font-family: 'Times New Roman', serif;
  }
</style>

Option 2

/*MainStyling CSS File*/

section.side-by-side div:last-child table tr:nth-child(odd) {
  background-color: pink;
  font-family: Georgia, serif;
}
character 1 vs character 2

15 points vs 34 points

Typically, the closer a style declaration is to its targeted element, the higher the chance it will take priority. In this case, though, the style declaration in the linked style sheet has higher specificity and will overrule the internal style-tag, even though the style-tag is imbedded in the HTML document, making Option 2 the winner.

You may come across situations like this while you're designing a page, where no matter what you do, the style sheet still takes priority. This is where you can add things like !important and place inline styling if you need your in-document to take priority. Just note, inline styling and the !important command should be a last resort and used sparingly.