DEV Community

Cover image for Beyond the Basics: The Ultimate Guide to CSS Precedence
Jaimal Dullat
Jaimal Dullat

Posted on • Edited on • Originally published at Medium

Beyond the Basics: The Ultimate Guide to CSS Precedence

Introduction

Welcome to the fascinating world of web design! If you’ve ever wondered how websites transform from plain code into visually stunning pages, the answer lies in the power of CSS (Cascading Style Sheets). CSS controls everything from colors and fonts to layouts, making websites visually appealing and engaging.

Have you ever wondered why some styles override others? Or why a particular style isn’t reflecting on your page even when it seems correctly coded? The answer often lies in the subtle dance of CSS precedence. When multiple style rules conflict, a hidden hierarchy decides the winner.

But fear not! In this guide, we’ll simplify these concepts for you. We’ll delve deep into the mysteries of specificity, breaking them down step by step. By the end, you’ll be navigating the world of CSS with renewed confidence and clarity. So, buckle up and let’s embark on this enlightening journey together!


What is CSS Precedence?

Certainly! CSS Precedence refers to the set of rules that determines which styles take priority when multiple styles are applied to the same element in a web page.

Imagine you have a web page with different CSS styles applied to various elements like headings, paragraphs, and buttons. But what happens when there are conflicting styles? For example, if one style says the heading should be red, but another style says it should be blue, which color will actually be displayed?

CSS precedence helps us answer that question. It establishes an order of importance for styles and decides which one will be applied when there are conflicts. It ensures that the styles you want to take priority are properly considered by the web browser.


Types of Selectors and Their Weights

Universal Selector

The universal selector (*) has the lowest specificity weight. It targets all elements on the page.

Example:

/* Targets all elements on the page */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
Enter fullscreen mode Exit fullscreen mode

Type/Tag Selectors

Type or tag selectors (e.g., p, h1, div) have a higher specificity weight than the universal selector. They target specific HTML elements.

Example:

/* Targets specific HTML elements */
p {
  color: blue;
}

h1 {
  color: red;
}

div {
  color: green;
}
Enter fullscreen mode Exit fullscreen mode

Class Selectors

Class selectors (e.g., .example-class) have a higher specificity weight than type selectors. They target elements with a specific class attribute. The same class can be used on multiple elements.

Example.

<style>
  /* Targets elements with a specific class attribute */
  .example-class {
    color: red;
  }

  .another-class {
    font-weight: bold;
  }
</style>

<p class="example-class">
  This paragraph will have red text color.
</p>
<div class="another-class">
  This div will have bold font weight.
</div>
<div class="example-class">
  This div will also have red text color.
</div>
Enter fullscreen mode Exit fullscreen mode

ID Selectors

ID selectors (e.g., #example-id) have a higher specificity weight than class selectors. They target elements with a specific ID attribute.

Example:

<style>
  /* Targets elements with a specific ID attribute */
  #example-id {
    background-color: yellow;
  }

  #another-id {
    border: 1px solid black;
  }
</style>

<div id="example-id">
  This div will have a yellow background color.
</div>
<p id="another-id">
  This paragraph will have a black solid border.
</p>
Enter fullscreen mode Exit fullscreen mode

Attribute Selectors:

Attribute selectors (e.g., [type=”text”]) have a higher specificity weight than ID selectors. They target elements with a specific attribute value.

Example:

<style>
  /* Targets elements with a specific attribute value */
  [type="text"] {
    border: 1px solid gray;
  }

  [href^="https://"] {
    color: blue;
  }
</style>

<input type="text" value="Example Input">
<a href="https://www.example.com">Example Link</a>
Enter fullscreen mode Exit fullscreen mode

Pseudo-class and Pseudo-element Selectors

Pseudo-class and pseudo-element selectors (e.g., :hover, ::after) have a higher specificity weight than attribute selectors. They target elements based on their state or position.

Example:

<style>
  /* Targets elements based on their state or position */
  a:hover {
    color: red;
  }

  p::after {
    content: " (after)";
    font-style: italic;
  }
</style>

<a href="#">Hover over me</a>
<p>Lorem ipsum dolor sit amet.</p>
Enter fullscreen mode Exit fullscreen mode

The Role of !important in CSS Precedence

Imagine you’re at a costume party, and everyone’s vying for the title of ‘Best Dressed’. CSS specificity determines who’s likely to win. But suddenly, someone walks in wearing a costume with flashing lights, loud music, and a sign that says “LOOK AT ME!”. That’s !important for you.

In technical terms, when you add !important to a style declaration, it's like giving it the ultimate trump card. No matter what other styles are applied to that element, and regardless of their specificity, the one with !important will dominate.

Example:

Let’s say you have the following two style rules:

#some-id {
  color: blue;
}

.text-color {
  color: red !important;
}
Enter fullscreen mode Exit fullscreen mode

If an element has both the ID some-id and the class text-color, it will display in red, not blue, because of the !important declaration.

But here’s the thing: Using !important is like using a magic spell; it's powerful but can create chaos if overused. It can make your stylesheets harder to understand, maintain, and debug. Plus, if you use !important everywhere, it loses its power (just like if everyone at the party had flashing costumes).

Some friendly advice: Use !important sparingly. It's best reserved for situations where you need to override styles that you can't easily access or change, or for temporary fixes (though try to come back and find a better solution later).

So, in a nutshell, !important is your emergency override button in CSS. Use it wisely, and may your web pages always look fabulous!


Factors Determine Which Rule Takes Precedence

Source Order

  • When multiple rules target the same element with the same specificity, the rule that comes later in the source order will override earlier rules.

  • For example, if you have two identical selectors, and one is placed at the beginning of the stylesheet and the other at the end, the styles specified in the latter rule will take precedence.

Inheritance

  • Inheritance refers to how properties get passed from parent elements to their descendants. If a certain style property isn’t defined for an element, it might inherit that property from its parent element.

  • For instance, if you specify a font-family for the

    element, all child elements inside the body will inherit that font family, unless they have a specific font-family value defined for them.

Importance

  • CSS allows for the use of the !important declaration, which can override other styles, regardless of source order or specificity.

  • For example, if one rule says p { color: red; } and another says p { color: blue !important; }, paragraphs will be blue because of the !important directive, even if the red color rule comes after the blue one in the source.

  • However, it’s generally recommended to use !important sparingly as it can make stylesheets harder to maintain and debug.


Handling Conflicts in Rules

When there are conflicting CSS rules, the browser has to determine which rule to apply. The decision is based on the following criteria, in order:

  1. Importance: Styles with !important will take precedence over those without.

  2. Specificity: If two selectors apply to the same element, the one with higher specificity will take precedence. Specificity is calculated based on the types of selectors used (e.g., IDs are more specific than classes, which are more specific than element selectors).

  3. Source Order: If two rules have the same importance and specificity, the one that comes later in the source will be applied.


Practical Scenarios: Understanding Precedence in Action

Case Study 1: Overriding Styles in a Complex Website

Scenario: You’ve been handed an e-commerce site with styles like:

/* legacy.css */
#product .description {
  color: blue;
}
Enter fullscreen mode Exit fullscreen mode

You want to change the description color to green without modifying the existing HTML or using !important.

Solution: Use a higher specificity selector:

/* new-theme.css */
body #product .description {
  color: green;
}
Enter fullscreen mode Exit fullscreen mode

Here, by just adding the body tag, the specificity increases, ensuring the description color becomes green.

Case Study 2: Modular CSS and Specificity Issues

Scenario: You’re building a site using components. Two components, Button and Alert, have similar class names:

/* Button.css */
.btn {
  background-color: blue;
}

/* Alert.css */
.btn {
  background-color: red;
}
Enter fullscreen mode Exit fullscreen mode

The issue is when both components are used on the same page, the background color gets mixed up.

Solution: Use CSS Modules or another naming convention:

/* Button.css */
.Button_btn {
  background-color: blue;
}

/* Alert.css */
.Alert_btn {
  background-color: red;
}
Enter fullscreen mode Exit fullscreen mode

Tips to Remember Specificity Values

  1. IDs are King: They’re at the top, so they have the highest weight.

  2. Classes and Attributes are BFFs: They hang out in the middle tier together.

  3. Tags are Commoners: Important, but not as heavy-hitting as the others.

  4. Universal is the Chill One: It’s the most relaxed, with almost no weight.

  5. Remember that !important can be used to override any specificity value and force a style to take precedence. However, it should be used as a last resort, as it can make styles harder to manage and maintain.

Remember, understanding CSS specificity is important for creating well-organized and maintainable stylesheets. By knowing the specificity hierarchy and choosing selectors wisely, you can ensure that your styles are applied correctly to your HTML elements.


Conclusion

In conclusion, “Beyond the Basics: The Ultimate Guide to CSS Precedence” has equipped you with a comprehensive understanding of CSS precedence. By going beyond the fundamentals, you now possess the knowledge and techniques to confidently navigate complex styling scenarios. With this newfound expertise, you can create visually captivating and well-structured web designs that stand out from the crowd. Take your CSS skills to the next level and unlock the full potential of CSS precedence in your projects.

🔗 Connect with me on:

Thank you for joining me on this journey through my blog!

  • Follow: Stay updated with the latest posts by hitting that follow button.

  • React: Show your appreciation with a like/other reactions if you enjoyed the article.

  • Comment: Engage in the conversation by leaving your thoughts, feedback, and questions.

  • Share: Spread the word by sharing the blog post on your social media platforms or with friends and colleagues.

Top comments (0)