0

I understand that having:

<div class="house big"></div>
<div class="house"></div>

I can select the second one like this:

.house:not(.big){}

But what exactly can I pass that :not() ? For example, having this:

<label>
    <span>Label</span>
    <input type="text">
</label>
<label>
    <p>Label</p>
    <input type="text">
</label>

I wanted to select all spans that are previous to inputs. As there is no previous sibling selector (I hope it will in the future), I tryed to do this without success:

span:not(span+input){}

But my Chrome doesn't seem to like it. Is my logic wrong here or simple this isn't the way :not() is supposed to work?

This is a question about the use of :not(), I know I can do label span:first-child{}

Vandervals
  • 5,774
  • 6
  • 48
  • 94
  • 3
    You can only use simple selectors inside `:not` if I'm not wrong. See [the documentation](http://www.w3.org/TR/css3-selectors/#negation). – Bram Vanroy Sep 09 '15 at 11:05
  • 1
    possible duplicate of [Is there a previous sibling selector?](http://stackoverflow.com/questions/1817792/is-there-a-previous-sibling-selector) – Bhojendra Rauniyar Sep 09 '15 at 11:10
  • 1
    What do you think of span+input is not simple selector? It is. But it's just selecting input not span. By the way there's no way to do in css as we know there's no previous element selector – Bhojendra Rauniyar Sep 09 '15 at 11:11
  • 1
    @BhojendraNepal I didn't say it isn't. I was answering to the question what he can pass to `not`. – Bram Vanroy Sep 09 '15 at 11:17
  • @BhojendraNepal `span+input` is not a simple selector - it's a combinator: http://www.w3.org/TR/css3-selectors/#simple-selectors-dfn – Pete Sep 09 '15 at 11:44
  • Though not is not accepting only a simple selector. :not() , is a functional pseudo-class taking a selector list [See selector list](https://drafts.csswg.org/selectors-4/#negation) – Bhojendra Rauniyar Sep 09 '15 at 11:53
  • @BhojendraNepal a selector list (a comma seperated list) of simple selectors, again it wouldn't accept `span+input` as that is not a simple selector (as you stated "It is" in your previous comment) – Pete Sep 09 '15 at 12:03
  • I agree it is not simple selector but :not accepts it. Just check selector list that I provided. – Bhojendra Rauniyar Sep 09 '15 at 12:55
  • Well, changing the markup can be a workaround, at the moment. – starikovs Sep 09 '15 at 13:19
  • If this is intended to be a generalized question about the limitations of `:not()` (the fact that you accepted Bram Vanroy's answer seems to suggest otherwise), I suggest leaving out the example as it seems to be misleading people into trying to close your question as a duplicate of a totally unrelated question. – BoltClock Sep 09 '15 at 19:41
  • @BoltClock it intends to be general, to better understand what I can pass and cannot, but also, specifically I'd like to know if the problem that lead me to that question comes from a bad logic or from an incorrect usage. Can't see the problem in that – Vandervals Sep 10 '15 at 07:20

2 Answers2

3

I interpreted your question as "I want to pass a selector to not() that selects a span preceding an input*. I will first consider that possibility. However, as @BoltClock notes in the comments, it might very well be that that's not what you meant. I'll consider that at the end.

You are trying to look back in the DOM tree, which isn't possible (yet). You simply can't in CSS3 or prior versions.

Your CSS code is valid, but it doesn't select what you think it does. It says:

Find me a [span that is [not [an input directly following a span]]].

Which doesn't really make sense. What I first thought you wanted is this:

Find me a [span that is [not [a span directly preceding an input]]].

And as you already said, there is no such selector. In CSS4 this behaviour will chance slightly with new selectors. For instance, you will be able to select parent elements that have a certain child.

But it's possible that you wanted this:

Find me a span that is a span directly preceding an input.

Unfortunately, this isn't available yet in current versions of CSS. CSS4 will introduce the :has selector which can finally look back.

Use one of the following which applies to what you want, because there's some confusion about that. Do you want to negate the has selector or not?

span:has(+input)
span:not(:has(+input))

Note that in CSS3 :not can only use a simple selector. In CSS4 it can take a selector list.

Bram Vanroy
  • 27,032
  • 24
  • 137
  • 239
  • The OP appears to want a selector for spans that *do* precede inputs, in which case I'm failing to understand why the OP thought of using `:not()` in the first place. The selectors-4 notation that does what the OP is looking for is `span:has(+input)`, which does not involve `:not()` in any way. All that aside, this is correct (though "valid" only applies to selectors-4 in this case, just in case anyone reading this is surprised to find out it doesn't actually validate just yet). – BoltClock Sep 09 '15 at 19:38
  • @BoltClock Considering that he accepted my answer, I think what he meant was: *I wanted to select all spans that are previous to inputs.* --> *Ï wanted to use "all spans that are previous to inputs" as a selector inside `not()`* That's how I interpreted the question. However, you might be right because his HTML doesn't provide a case in which a span *isn't* preceding an input. I will edit my post with your comment in mind. – Bram Vanroy Sep 09 '15 at 19:43
  • Yeah, the whole question seems pretty confusing to me. It's not clear to me what exactly the OP is asking. Maybe the duplicate votes were warranted after all. – BoltClock Sep 09 '15 at 19:44
0

Only simple selectors are allowed within :not() pseudo. http://www.w3.org/TR/selectors/#simple-selectors-dfn

/* the X argument can be replaced with any simple selectors */
:not(X) {
  property: value;
}
Aaron
  • 10,187
  • 3
  • 23
  • 39