14

HTML:

<ul>
    <li></li>
    <li></li>
    <li class="img"></li>        
    <li></li>
    <li class="img"></li>        
    <li class="img"></li>        
    <li></li>
</ul>

CSS:

ul {
 list-style-type: none;   
}

li {
    background-color: red;
    margin: 5px;
    width: 30px;
    height: 30px;
    float: left;
}

li.img:not(:first-child) {
    background-color: blue;
}

Result:

http://jsfiddle.net/benfosterdev/K3ZnA/

I want all but the first li.img to have a blue background.

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
Ben Foster
  • 34,340
  • 40
  • 176
  • 285

3 Answers3

29

You cannot do this with :not(:first-child) because all li.img elements except the first li (no matter if it's .img or not) are indeed not the first child of their parent. So that selector would exclude the first li.img only if it were the first li without qualification.

However, you can do it with the general sibling combinator ~:

li.img ~ li.img {
    background-color: blue;
}

This selector matches any li.img that is the sibling of any other li.img but appears after it in document order, or in other words every li.img but the first.

See it in action, and be aware that IE < 9 does not support this selector.

Pang
  • 9,564
  • 146
  • 81
  • 122
Jon
  • 428,835
  • 81
  • 738
  • 806
  • This does work for IE7 and 8. I've spaced some input fields using the selector. – Rakuen42 Oct 07 '13 at 18:57
  • Do you have any idea how to make a working selector similar to `.img:not(.img~.img)` (this doesn't work) to select only the first-of-class? https://jsfiddle.net/oriadam/27cfmbpp/ – oriadam May 02 '16 at 00:59
  • @oriadam off the top probably use the technique in my answer [here](http://stackoverflow.com/questions/12289853/css-notfirst-child-selector/12289888#12289888): `.img` to set the property value you want for the first-of-class, then `.img ~ .img` to reset it back to previous value for everything except first-of-class. – Jon May 02 '16 at 08:06
  • Thanks @Jon - I cannot use that technique because I'm selecting elements with `querySelectorAll`, not setting a css property. I need to select the first of each class, something like that: `#element1,.class1:first,class2:first,class3:first`. I can use JS to split the query with ',' and then combine several `querySelector` (not all) but it's ugly and slows down the code. – oriadam May 03 '16 at 14:33
10

If you want to select all other li.img and give them a different backgroundColor:

li.img ~ li.img {
   background-color: blue;
}
axel.michel
  • 5,764
  • 1
  • 15
  • 25
-2

May be, you could add a javascript like in case IE 8 (and older) or such browser does not support ~ selector as told by Jon above:

document.getElementsByClassName("img")[0].style.backgroundColor = "red";
Zelal
  • 114
  • 4