Gleb Kemarsky
Gleb Kemarsky

Reputation: 10408

Why does parent's !important lose?

The color property of the parent block has an !important declaration. Why does the child's property take precedence? How to explain it?

I see explanations of specificity, but I don't understand how to apply them to this particular case.

Perhaps I missed some basic position in the documentation ...

div {
  color: purple !important;
  font-family: 'Open Sans', serif;
  font-size: 30px;
  font-weight: bold;
}
span {
  color: red; /* Why does parent's `!important` lose? */
}
<div>
  Parent
  <span>Child</span>
</div>

Upvotes: 1

Views: 1100

Answers (2)

Gleb Kemarsky
Gleb Kemarsky

Reputation: 10408

@Alohci cited in the comments a link to the documentation:

W3C CSS 2.1 Specification. 6.1.1 Specified values

User agents must first assign a specified value to each property based on the following mechanisms (in order of precedence):

  1. If the cascade results in a value, use it.
  2. Otherwise, if the property is inherited and the element is not the root of the document tree, use the computed value of the parent element.
  3. Otherwise use the property's initial value. The initial value of each property is indicated in the property's definition.

So now I understand the situation as follows:

Parent properties do not directly affect the child, but the browser uses them:

  1. when the child requires it (inherit);
  2. when the desired property is not specified anywhere (neither by the child, nor by the user, nor by the browser itself) and is defined as inherited.

Therefore, the specificity and importance of the parent does not compete with the specificity of the child. There is a winner at the level of the parent and a winner at the level of the child, but they do not know about each other. Only when the browser uses the parent property for the child element, it becomes important who won at the parent level.

In short, the parent element does not affect, but specifies an example. The child does not obey, but imitates when he sees fit.

Upvotes: 1

Andrew Li
Andrew Li

Reputation: 57964

Per the MDN documentation:

Styles for a directly targeted element will always take precedence over inherited styles, regardless of the specificity of the inherited rule.

In your example, the span selector directly targets the child element, and thus takes precedence over the inherited style of the parent div selector. Now to explain why !important doesn't change this.

The reason why the !important is disregarded here is that !important takes precedence over all other declarations only if it's the same type of element being selected. It doesn't matter here because the child is a span which is a different element, not another div. If the child were to be a div, then the !important, then !important would apply:

div {
  color: purple !important;
  font-family: 'Open Sans', serif;
  font-size: 30px;
  font-weight: bold;
}
div > div {
  color: red; 
}
<div>
  Parent
  <div>Child</div>
</div>

In the example above, the div > div rule should, in theory, make the child red because of specificity, but since the !important is under a div selector, thus selecting the same element type, it will override the more specific rule.

Upvotes: 5

Related Questions