3

I am trying to use css3's :not() selector to select certain elements that do not have a parent element with a certain class anywhere as its ancestor.

The mark up is simple:

<div><strong><em>Please select me!</em></strong></div>

<div><strong><p><em>Please don't select me!</em></p></strong></div>

<div><p><em>Please don't select me!</em></p></div>

And this is the selector I am using: div *:not(p) em.

And a fiddle: http://jsfiddle.net/cwxzH/

Why is the second div being selected if I am filtering out all children of the div that are paragraphs? Is there anyway to prevent this?

I have only tested in IE9 and FF13 so far.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
F21
  • 32,163
  • 26
  • 99
  • 170

2 Answers2

2

div * selects all descendants of div ie strong p em then the :not(p) removes the p so you're left with strong and em, now with the em only the strong has an em descendant(the em) resulting in the em getting selected on the second div

Musa
  • 96,336
  • 17
  • 118
  • 137
  • Thanks for the explaination. Is there anyway to work around this and only select the first `em` in the first `div`? – F21 Jul 02 '12 at 01:45
  • @phpdev: Not really, no. You cannot reliably use `:not()` for filtering ancestor elements - http://stackoverflow.com/questions/7084112/css-negation-pseudo-class-not-for-parent-ancestor-elements – BoltClock Jul 02 '12 at 03:26
0

Maybe this is what you're looking for? It selects all em elements that are not direct children of paragraphs:

div :not(p)>em

http://jsfiddle.net/cwxzH/1/

bfavaretto
  • 71,580
  • 16
  • 111
  • 150
  • Is there anyway to select ALL `em`s except ones where there they have a `p` ancestor or parent? – F21 Jul 02 '12 at 01:56
  • The code I posted selects all ems except ones that have a *parent* p. As for *ancestors* on any level, I don't think so, because `:not` would still select any element between the p and the em. – bfavaretto Jul 02 '12 at 02:02