Specificity issue in CSS
Asked Answered
D

3

6

So I have a list of items inside a div with the class book-select and one of the li's in my unordered list has the class selected. According to the CSS rules I've defined, the li's in the div has the background color skyblue and the one li with the class selected would be steelblue.

The problem is that the book-select class is overwriting the selected class, which I don't understand. Wouldn't the div class be less specific than the li with the class selected? The li is in a ul which is in the div.

Here's the relevant CSS and HTML:

.book-select li {
    font-size: 0.75em;
    text-align: center;
    list-style: none;
    background: skyblue;
    width: 25%;
    margin: auto;
}

.selected {
    background: steelblue;
}

<div class="book-select">
    <h2>Pick a book:</h2>
    <ul>
        <li>Set A Volume 1, Course Foundation</li>
        <li>Set A Volume 2, Expeditionary Airman</li>
        <li>Set A Volume 3, Professional Airman</li>
        <li>Set B Volume 1, Supervisory Communicator</li>
        <li>Set B Volume 2, Supervisor of Airmen</li>
        <li class="selected">All</li>
    </ul>
</div>

This is part of a quiz and the idea is that the user clicks on a book and jQuery will change the class of the selected item to whatever is clicked on, with the last li with the text "All" being the default selected book. I could use a different jQuery method to change the background color, but the fact that CSS is giving me this specificity error is bothering me.

I know .book-select li is overwriting .select because the console is showing the background: steelblue; as crossed off.

Shouldn't it be the other way around? Isn't .selected the more specific class, as it only contains one element, which is itself?

Daffie answered 9/6, 2017 at 15:16 Comment(0)
B
10

Use this selector to increase the specifity of that CSS rule:

.book-select li.selected {
   background: steelblue;
}

About "specifity": Simply said, one class plus one tag (.book-select li) has more "weight" concerning specifity than just one class (.selected), so a rule with one class plus one tag will overwritea rule with just one class. And the selector shown above will overrule that again, since it consists of two classes and one tag.

Busy answered 9/6, 2017 at 15:18 Comment(2)
Ah I see. That worked. I thought specificity worked as you got deeper into the DOM tree. The further into the tree you get, I thought, the more specific it was. Like a div that contains a bunch of elements would be less specific than a single element within that div. Are you saying that it has more to do with what is specified in the rule itself?Daffie
The whole thing works according to a system that kind of gives "weight units" to the different elements which are added up. The higher that value, the higher the specifity. There is an article here, which is old but still useful: css-tricks.com/specifics-on-css-specificity And there is also this website: cssspecificity.comBusy
C
0

Even Something as simple as

li.selected
{
background: steelblue;
}

Should overide the background for you :)

Carthusian answered 15/12, 2017 at 7:8 Comment(0)
A
-1

for a possible solution, you can do this:

.selected {
    background: steelblue !important;
}

important will avoid this style from being override

Amarelle answered 9/6, 2017 at 15:19 Comment(2)
This solution should only used, if you want to overwrite everywhere the background.Luben
Like anything, there are times when Important makes sense, but in my experience they are few and there's usually a better way. Importants tend to jump out and bite you later when you least expect itMungo

© 2022 - 2024 — McMap. All rights reserved.