James South
James South

Reputation: 10645

Why does this selector not work

Given the following markup

<div class="fixed">
    <div class="clmn2">
    </div>
    <div class="clmn2">
    </div>
</div>

And the information given on mdn

By my interpretation this selector should work.

*:not(.fixed) [class*="clmn"]

Unfortunately it does not, however this does.

div:not(.fixed) [class*="clmn"]

Any ideas why?

*Update *

If you check the linked fiddle the column in rows not marked with the class fixed should be floated.

Upvotes: 0

Views: 169

Answers (4)

Quentin
Quentin

Reputation: 944296

*:not(.fixed) foo matches

A foo element that is a descendant of any element that is not a member of the fixed class

This is different to:

A foo element that is not a descendant of any element that is a member of the fixed class

If we had:

<a class="fixed">
  <b>
    <foo></foo>
  </b>
</a>

Then the foo element is a descendant of a b element that is not a member of the fixed class. (It is also a descendant of an a element that is a member of that class, but that doesn't matter because *:not(.fixed) will happily match the b element instead.)

Upvotes: 4

Paul Roub
Paul Roub

Reputation: 36458

Actually, it's working better than you want it to.

*:not(.fixed) matches, among other things, your body element. Eventually, somewhere within the body, it finds your clm* divs, and applies the styles.

If you only want to match things that are direct descendants of something non-fixed, use:

 *:not(.fixed) > [class*="clmn"] { /* ... */ }

Which does work.

Upvotes: 1

thgaskell
thgaskell

Reputation: 13256

Your selector is too general. Since * will also select things like body. And body is not(.fixed), the rule will still be applied.

Change it to something more specific like .row:not(.fixed).

http://jsfiddle.net/sVpTA/2/

CSS

.row:not(.fixed) [class*="clmn"]{
    float: none;
    width: 100%;
    margin-left: 0!important;
}

Upvotes: 1

Jon
Jon

Reputation: 437744

Your "bad" selector matches any element with a class as given that is a descendant of any element without class fixed.

Since both the <html> and <body> elements do not have the class fixed and your inner <div>s are their descendants, the selector matches them.

The "good" selector only considers descendants of any <div> that does not have the class fixed. Since the only <div> in your HTML that has descendants also has that class, the selector matches nothing.

In general, plain :not(whatever) followed by a descendant combinator is not really useful. In your case it looks like the solution would be to replace the "descendant" combinator with the child combinator >:

:not(.fixed) > [class*="clmn"]

Upvotes: 3

Related Questions