How browsers resolve competing CSS styles

We style our websites using CSS, which stands for Cascading Style Sheets.

But what does Cascading really mean?

The CSS Cascade is one of the most powerful parts of CSS. But it can also be very frustrating, if not well understood. Anyone who’s worked on a large enough website has complained "Why won’t this CSS property work?!" And we’ve all been tempted to throw an !important to strong-arm things into place.

To save ourselves from future angst, let’s take a step back and learn this thing for real.

The CSS Cascade is the way our browsers resolve competing CSS declarations.

Every time we write a CSS declaration (or rule), it will enter the CSS Cascade, which will determine whether or not it will end up as the final style. The further down the cascade a declaration falls, the less likely it will end up as the final style.

Let’s take a look at the different tiers of the Cascade.

1. Importance

The first tier of the Cascade looks at the type of rule we’re looking at.

There are four basic types of rules:

  1. transition
  • Rules that apply to an active transition take the utmost importance

2. !important

  • When we add !important to the end of our declaration, it jumps to this level of the Cascade. Ideally, you reserve this level for Hail Marys, which are needed to override styles from third-party libraries.

3. animation

  • Rules that apply to an active animation jump up a level in the Cascade

4. normal

  • This level is where the bulk of rules live

As you can see, this top tier is mostly reserved to ensure our elements animate properly, and to help out desperate developers (!important).

Let’s look at how this rule plays out:

Which of these two rules would win?

Ap {

color: sandybrown;

}

Bp {

color: orchid !important;

}

vs

Answer

Rule B wins!

Remember that !important declarations fall on the second level, while normal declarations fall on the fourth level.

If two rules are tied on one tier of the Cascade, the fight goes on to another round, looking for a difference on the next tier.

2. Origin

The second tier of the Cascade looks at where the rule was defined.

There are three places where a rule can be defined:

  1. website
  • This is the only level that you have control over, as a web developer.

2. user

3. browser

  • Each browser has its own set of styles, which is why things like <button>s have default styles.
  • This is your browser’s default button

Funky fact alert! The hierarchy here is actually reversed for !important rules, meaning that an !important browser default rule wins over an !important website rule (whereas a website rule normally wins over a browser default).

Fight time! Which of these two rules would win?

A website-stylesheet.css


p {

color: sandybrown;

}

B

Browser default


p {

color: orchid;

}

vs

Answer

Rule A wins!

Remember that website-specific declarations fall on the first level, while browser defaults fall on the third level.

3. Specificity

The third tier of the Cascade looks at the Specificity of a rule.

There are four levels of selectors:

1. inline

  • Styles declared within a style HTML property are the most specific

When we create a CSS declaration, we can target specific elements using selectors.

2. id

  • We can target elements based on their id, using the syntax #id

3. class | attribute | pseudo-class

  • We can target elements based on their class, using the syntax .class
  • This level also includes attribute selectors that target HTML attributes, like [checked] and []
  • This level also includes pseudo-selectors, like :hover and :first-of-type

4. type | pseudo-element

  • We can target elements based on their tag type, using the syntax type
  • This level also includes pseudo-elements, like :before and :selection

Fight time! Which of these two rules would win?

A

*.html


<p style="color: sandybrown">...</p>

B

*.css


p {

color: orchid;

}

vs

Answer

Rule A wins!

Remember that inline styles fall on the first level, while type rules fall on the fourth level.


What about these two rules?

A.paragraph {

color: sandybrown;

}

B#paragraph {

color: orchid;

}

vs

Answer

Rule B wins!

Remember that rules with a class selector fall on the third level, while rules with an id selector fall on the second level.


One thing to note about levels on this tier is that the number of hits on the highest-reached level matter.

A. paragraph:first-of-type {

color: sandybrown;

}

B. p.paragraph {

color: orchid;

}

vs

Answer

Rule A wins!

Rule A has two "hits" on the third level (1 class and 1 pseudo-class), whereas Rule B has only one "hit" on the third level - its "hit" on a lower (fourth) level doesn’t come into play.


Additionally, on this tier of the Cascade, ties can be broken within this tier. This means that, if two rules have the same number of hits on their highest level, one can win by having a hit on the next level down.

A. p#paragraph {

color: sandybrown;

}

B. #paragraph.paragraph {

color: orchid;

}

vs

Answer

Rule B wins!

Rules A and B both have 1 hit on the second level (1 id), but Rule B additionally has 1 hit on the third level (1 class), which beats Rule A's hit on the fourth level (1 tag).

4. Position

And lastly, we descend to the fourth, and final, tier of the Cascade, which looks at the order that the rules were defined in.

Rules that are defined later in linked stylesheets or <style> tags will win, given that everything else in the Cascade is the same.

A. p {

color: sandybrown;

color: orchid;

}

B. p {

color: sandybrown;

color: orchid;

}

vs

Answer

Rule B wins!


要查看或添加评论,请登录

Mark Coley的更多文章

社区洞察

其他会员也浏览了