1072

I have a div tag containing several ul tags.

I'm able to set CSS properties for the first ul tag only:

div ul:first-child {
    background-color: #900;
}

However, my following attempts to set CSS properties for each other ul tag except the first one don't work:

div ul:not:first-child {
    background-color: #900;
}

div ul:not(:first-child) {
    background-color: #900;
}

div ul:first-child:after {
    background-color: #900;
}

How can I write in CSS: "each element, except the first"?

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
Oto Shavadze
  • 40,603
  • 55
  • 152
  • 236

13 Answers13

1875

One of the versions you posted actually works for all modern browsers (where CSS selectors level 3 are supported):

div ul:not(:first-child) {
    background-color: #900;
}

If you need to support legacy browsers, or if you are hindered by the :not selector's limitation (it only accepts a simple selector as an argument) then you can use another technique:

Define a rule that has greater scope than what you intend and then "revoke" it conditionally, limiting its scope to what you do intend:

div ul {
    background-color: #900;  /* applies to every ul */
}

div ul:first-child {
    background-color: transparent; /* limits the scope of the previous rule */
}

When limiting the scope use the default value for each CSS attribute that you are setting.

Tieme
  • 62,602
  • 20
  • 102
  • 156
Jon
  • 428,835
  • 81
  • 738
  • 806
  • do you know exactly which versions this isn't supported on? – Simon_Weaver Jul 27 '14 at 19:48
  • 12
    @Simon_Weaver: In practice everything but IE < 9 supports it. A great resource to get this kind of information is http://caniuse.com. – Jon Jul 29 '14 at 09:15
  • 2
    Hmm.. watch out for the the restrictions of the first solution: https://caniuse.com/#feat=css-not-sel-list The second one sounded more reasonable for me. Thanks! – biker856 Jun 22 '18 at 13:17
  • 1
    @iorrah your caniuse link is for a list of selectors, and yes, support is very limited still. The OP is not using a list of selectors. So I think [https://caniuse.com/#feat=css-sel3](https://caniuse.com/#feat=css-sel3) is more appropriate with great support beyond the days of IE8. – secretwep Jan 13 '20 at 17:48
  • This works even without the div element at the start in chrome. – Achraf JEDAY Jan 22 '20 at 13:12
  • I used this idea to do some CSS gymnastics and make the first value on a select box the "Placeholder" if you will. `select:invalid { color: #cacaca; } select:invalid :not(:first-child){ color: initial; } ` – Ervin Šabić Dec 03 '20 at 05:12
  • @Jon it's not working in my case, .booking_child > div:not(:first-child) { width: 33.33%; } – vishal May 24 '22 at 05:33
179

This CSS2 solution ("any ul after another ul") works, too, and is supported by more browsers.

div ul + ul {
  background-color: #900;
}

Unlike :not and :nth-sibling, the adjacent sibling selector is supported by IE7+.

If you have JavaScript changes these properties after the page loads, you should look at some known bugs in the IE7 and IE8 implementations of this. See this link.

For any static web page, this should work perfectly.

Alex Quinn
  • 4,033
  • 3
  • 18
  • 18
  • 4
    @Leven: That [quirksmode link](http://www.quirksmode.org/css/selectors/) says it should work in IE7, but only statically. If your JS places another element in front of it, it might not be updated correctly. Is that the issue you saw? – Alex Quinn Sep 18 '13 at 02:18
  • might be worth noting that in a sequence of elements like: `ul ul div ul` (where these elements are siblings), only the second ul will be selected, since the last one does not have a `ul` previous to itself – Brian H. Dec 13 '16 at 12:08
96

Since :not is not accepted by IE6-8, I would suggest you this:

div ul:nth-child(n+2) {
    background-color: #900;
}

So you pick every ul in its parent element except the first one.

Refer to Chris Coyer's "Useful :nth-child Recipes" article for more nth-child examples.

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
ed1nh0
  • 1,532
  • 13
  • 17
46

You can use "first-child" pseudo-class inside the "not()" pseudo-class.

div ul:not(:first-child){
    background-color: #900;
}
<html>
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Pseudo Classes</title>
</head>
<body>
  <div>
    <ul>
       <li><a href="#">Home</a></li>
       <li><a href="#">Products</a></li>
    </ul>
    <ul>
       <li><a href="#">About</a></li>
       <li><a href="#">Contact</a></li>
    </ul>
    <ul>
       <li><a href="#">Services</a></li>
       <li><a href="#">Downloads</a></li>
    </ul>
    <ul>
       <li><a href="#">Facebook</a></li>
       <li><a href="#">Instagram</a></li>
    </ul>
  </div>
</body>
</html>

Alternative ways,

  1. With "nth-child()", It will select nth number of child.

div ul:not(:nth-child(1)){
    background-color: #900;
}
<html>
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Pseudo Classes</title>
</head>
<body>
  <div>
    <ul>
       <li><a href="#">Home</a></li>
       <li><a href="#">Products</a></li>
    </ul>
    <ul>
       <li><a href="#">About</a></li>
       <li><a href="#">Contact</a></li>
    </ul>
    <ul>
       <li><a href="#">Services</a></li>
       <li><a href="#">Downloads</a></li>
    </ul>
    <ul>
       <li><a href="#">Facebook</a></li>
       <li><a href="#">Instagram</a></li>
    </ul>
  </div>
</body>
</html>
  1. With "nth-of-type()", It will select nth number of element of its parent.

    div ul:not(:nth-of-type(1)){
        background-color: #900;
    }
    <html>
      <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Pseudo Classes</title>
    </head>
    <body>
      <div>
        <ul>
           <li><a href="#">Home</a></li>
           <li><a href="#">Products</a></li>
        </ul>
        <ul>
           <li><a href="#">About</a></li>
           <li><a href="#">Contact</a></li>
        </ul>
        <ul>
           <li><a href="#">Services</a></li>
           <li><a href="#">Downloads</a></li>
        </ul>
        <ul>
           <li><a href="#">Facebook</a></li>
           <li><a href="#">Instagram</a></li>
        </ul>
      </div>
    </body>
    </html>
  2. With "nth-last-child()", It will select nth number of child counting from the last child. If you have 4 "ul" tags, you can write like this.

div ul:not(:nth-last-child(4)){
    background-color: #900;
}
<html>
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Pseudo Classes</title>
</head>
<body>
  <div>
    <ul>
       <li><a href="#">Home</a></li>
       <li><a href="#">Products</a></li>
    </ul>
    <ul>
       <li><a href="#">About</a></li>
       <li><a href="#">Contact</a></li>
    </ul>
    <ul>
       <li><a href="#">Services</a></li>
       <li><a href="#">Downloads</a></li>
    </ul>
    <ul>
       <li><a href="#">Facebook</a></li>
       <li><a href="#">Instagram</a></li>
    </ul>
  </div>
</body>
</html>
  1. With "nth-last-of-type()", It will select nth number of element of its parent counting from the last child. If you have 4 "ul" tags, you can write like this.

div ul:not(:nth-last-of-type(4)){
    background-color: #900;
}
<html>
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Pseudo Classes</title>
</head>
<body>
  <div>
    <ul>
       <li><a href="#">Home</a></li>
       <li><a href="#">Products</a></li>
    </ul>
    <ul>
       <li><a href="#">About</a></li>
       <li><a href="#">Contact</a></li>
    </ul>
    <ul>
       <li><a href="#">Services</a></li>
       <li><a href="#">Downloads</a></li>
    </ul>
    <ul>
       <li><a href="#">Facebook</a></li>
       <li><a href="#">Instagram</a></li>
    </ul>
  </div>
</body>
</html>

These are some of the best ways to handle these kind of situations.

wahsandaruwan
  • 587
  • 5
  • 7
27

not(:first-child) does not seem to work anymore. At least with the more recent versions of Chrome and Firefox.

Instead, try this:

ul:not(:first-of-type) {}
Scott Summers
  • 617
  • 1
  • 9
  • 13
  • 9
    They both work, but they have different meaning. `ul:not(:first-child)` means literally "any `ul` element that is not first child of its parent", so it won't match even the 1st `ul` if it's preceded by another element (`p`, heading etc.). On the contrary, `ul:not(:first-of-type)` means "any `ul` element except the 1st `ul` in the container". You are right that OP probably needed the latter behavior, but your explanation is rather misleading. – Ilya Streltsyn Aug 21 '17 at 16:44
22
div li~li {
    color: red;
}

Supports IE7

zloctb
  • 10,592
  • 8
  • 70
  • 89
16

You can use any selector with not

p:not(:first-child){}
p:not(:first-of-type){}
p:not(:checked){}
p:not(:last-child){}
p:not(:last-of-type){}
p:not(:first-of-type){}
p:not(:nth-last-of-type(2)){}
p:not(nth-last-child(2)){}
p:not(:nth-child(2)){}
Nasser Ali Karimi
  • 4,462
  • 6
  • 34
  • 77
8

You can use your selector with :not like bellow you can use any selector inside the :not()

any_CSS_selector:not(any_other_CSS_selector):not(any_other_CSS_selector){
    /*YOUR STYLE*/
}

you can use :not without parent selector as well.

   :not(:nth-child(2)){
        /*YOUR STYLE*/
   }

More examples

any_CSS_selector:not(:first-child){
    /*YOUR STYLE*/
}
any_CSS_selector:not(:first-of-type){
    /*YOUR STYLE*/
}
any_CSS_selector:not(:checked){
    /*YOUR STYLE*/
}
any_CSS_selector:not(:last-child){
    /*YOUR STYLE*/
}
any_CSS_selector:not(:last-of-type){
    /*YOUR STYLE*/
}
any_CSS_selector:not(:first-of-type){
    /*YOUR STYLE*/
}
any_CSS_selector:not(:nth-last-of-type(2)){
    /*YOUR STYLE*/
}
any_CSS_selector:not(:nth-last-child(2)){
    /*YOUR STYLE*/
}
any_CSS_selector:not(:nth-child(2)){
    /*YOUR STYLE*/
}
Nasser Ali Karimi
  • 4,462
  • 6
  • 34
  • 77
4

I didn't have luck with some of the above,

This was the only one that actually worked for me

ul:not(:first-of-type) {}

This worked for me when I was trying to have the first button displayed on the page not be effected by a margin-left option.

this was the option I tried first but it didn't work

ul:not(:first-child)

newtron54
  • 141
  • 1
  • 4
2

As I used ul:not(:first-child) is a perfect solution.

div ul:not(:first-child) {
    background-color: #900;
}

Why is this a perfect because by using ul:not(:first-child), we can apply CSS on inner elements. Like li, img, span, a tags etc.

But when used others solutions:

div ul + ul {
  background-color: #900;
}

and

div li~li {
    color: red;
}

and

ul:not(:first-of-type) {}

and

div ul:nth-child(n+2) {
    background-color: #900;
}

These restrict only ul level CSS. Suppose we cannot apply CSS on li as `div ul + ul li'.

For inner level elements the first Solution works perfectly.

div ul:not(:first-child) li{
        background-color: #900;
    }

and so on ...

Gufran Hasan
  • 8,910
  • 7
  • 38
  • 51
1
li + li {
    background-color: red;
}
Roberto Caboni
  • 7,252
  • 10
  • 25
  • 39
7usien
  • 83
  • 7
0

This is a simple way to change the background color of the element placed AFTER your basic "ul" - elements, except the first one:

See :nth-child() documentation for more details on how this works.

div ul:nth-child(n+2)::after {
    background-color: #900;
}
Federico Fusco
  • 545
  • 1
  • 5
  • 18
-2
div ul::nth-child(n+2){
    background-color: #900;
}

Is working too