14

li > ul > li selects all li elements which are deeper than the first level of a ul.

li selects all li elements

li:not(li > ul > li) should select all li elements which are no deeper than the first level of a ul--that is, only first level elements--but it doesn't. Why?

Thanks!

Mr_Green
  • 40,727
  • 45
  • 159
  • 271
Matthew James Davis
  • 12,134
  • 7
  • 61
  • 90
  • 3
    `:not` only accepts [simple selectors](http://www.w3.org/TR/css3-selectors/#simple-selectors-dfn). – Felix Kling Mar 29 '13 at 14:18
  • @Lotuse: I added a link to the spec... – Felix Kling Mar 29 '13 at 14:19
  • @Lotus: According to the spec, `:nth-child` is a pseudo class and therefore should be a simple selector. – Felix Kling Mar 29 '13 at 14:21
  • Take a look at [this question][1]. See if it helps. [1]: http://stackoverflow.com/questions/977883/selecting-only-first-level-elements-in-jquery – Jon Harding Mar 29 '13 at 14:25
  • @Lotus nth-child is a pseudo-class, hence a simple selector. http://www.w3.org/wiki/CSS/Selectors/pseudo-classes/:nth-child – Michael Mar 29 '13 at 14:30
  • Your link or comment doesn't explain anything .. `nth-child` is a class selector not a simple selector – user2129623 Mar 29 '13 at 14:31
  • From @FelixKling link: "A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class." Pseudo-classes = simple selectors, nth-child = pseudo-class = simple selector. – Michael Mar 29 '13 at 14:33
  • And even to that extent, despite you being wrong, if you were right that nth-child is a class selector, class selectors are also simple selectors, so if it were true, nth-child would still be a simple selector. ;) So to answer your secondary question above... Yes, nth-child is a simple-selector. – Michael Mar 29 '13 at 14:35

1 Answers1

11

The reason li:not(li > ul > li) does not work is because the li > ul > li is not a simple selector (as Felix Kling noted in the comments to your question).

The easiest way to get the top level is to give a class or id to the outer most ul and then do:

.ulClassNameOrID > li {}

However, the following gets what you desire also (see fiddle) as it does not select any ul that is a direct child of a previous li (so is not a sublist of the outer list):

:not(li) > ul > li {}
ScottS
  • 71,703
  • 13
  • 126
  • 146
  • He want's to select the first level elements, not the top-most level. – Michael Mar 29 '13 at 14:27
  • @Michael: I understand "first-level" to be the list elements that are under the initial `ul` element and no deeper, which would be the "top-most level". If that is incorrect, then I need the OP to clarify the question. – ScottS Mar 29 '13 at 14:38
  • 2
    @Michael: And besides that, the title to the question mentions the "top level" while the question itself states "first level," so I think I have interpreted the OP correctly. – ScottS Mar 29 '13 at 14:41
  • @ScottS My comment was well before your edit ;). You indeed have. – Michael Mar 29 '13 at 15:13
  • @Michael: My edit didn't change anything about the essence of my answer, it just offered a second (more generic, without class or id) solution. But I'm glad we have come to a consensus on what we believe the OP is asking (though he has not made a statement himself). – ScottS Mar 29 '13 at 15:17
  • That’s a nice crafty solution. Re top vs first level: in any case to get the next level is easy enough once you’ve got the top. – Manngo Nov 02 '20 at 23:41