I find it very illogical that the selector for an element
inside an #id
has precedence over the #id
of that element
.
Disclaimer: I am aware there are many similar questions floating around. I have also read up on CSS precedence and specificity documentation. However none of these questions and documentation seem to cover this specific problem I have, not to mention explaining why. Maybe I'm just bad at searching; in that case, please guide me. But I digress.
For example, take the following HTML:
<style>
#top button {
padding: 0;
}
#myButton {
padding: 2em;
}
</style>
<header id="top">
<button type="button" id="myButton">Button</button>
</header>
For some reason, the button comes out with no padding. Inspect element shows that the style of #myButton
is overridden.
Isn't #myButton
, which always selects a unique element, more specific than #top button
, which selects multiple buttons under a unique element?
Is this a bug or an intended feature? How standard is this behavior across browsers? And if a feature, why?
Tested with Chrome 78 and Edge 44 (EdgeHTML 18) on Windows 10.
Basically #id1 element
is more specific than #id2
on it's own.
Specificity is additive, the more you add (in general) the more specific the selector gets.
In your example #top
and #button
have the same specificty, as soon as you add more information to one of those selectors it becomes more specific. Therefore #top button
is more specific than #button
on it's own.
Here is a great article on specificity complete with great cheat sheet.
As an example, lets say you have and article
where you want the color to be blue. But for all buttons
in the article you want the color to be red.
#article1 {color:blue;}
#article1 button {color:red;}
<article id="article1">
<p>The quick brown fox jumps over the lazy dog</p>
<button>Button</button>
</article>
One option in your instance is to use the element itself
#top button {
padding: 0;
color:red;
}
button#myButton {
padding: 2em;
color:blue;
}
<header id="top">
<button type="button" id="myButton">Button</button>
</header>
In this example #top button
and button#myButton
have the same specificity. However because button#myButton
is declared last, it is applied.
You have also inadvertently stumbled upon one of the reasons why a lot of developers recommend you don't use ids for styling and should basically be using classes instead.