Ky -
Ky -

Reputation: 32173

Why is css styling <P> in an <A> when told not to

This made me royally confused about the :not() selector, because the behavior is the same cross-browser:

CSS:

main *:not(a) p {
    color: red;
}
a {
    color: blue;
}

HTML:

<main>
    <a href="http://example.com">
        <figure>
            <img src="http://placehold.it/640x480" alt="640x480"/>
            <figcaption>
                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
                   Donec hendrerit dolor mattis rutrum condimentum.</p>
            </figcaption>
        </figure>
    </a>
    <p>Cras non felis <a href="http://google.com">venenatis, venenatis</a>
       elit quis, rutrum tortor.</p>
</main>

SSCCE: http://jsfiddle.net/Supuhstar/SmLWS/1/

Cross browser, this styles the <A> in the <P> blue, but the <P> in the <A> red. <FIGURE> used as an example of why I want this to work.

Upvotes: 1

Views: 71

Answers (1)

zwol
zwol

Reputation: 140876

main *:not(a) p does not mean "<p>, a descendant of <main>, with no <a> anywhere in between". It means "<p>, a descendant of something which is not <a>, which is a descendant of <main>".

So, for instance, it will not match <main><a><p>...</p></a></main>, because the only thing in between the <main> and the <p> is the <a>, and it won't match <main><p>...</p></main> either, because there is nothing in between <main> and <p>. But it will match <main><figure><a><p>...</a></figure></main>, because the descendant combinator allows the *:not(a) to skip the <a> and bind to the <figure>.

EDIT: Forget the nasty thing I suggested before, I think this does what you want:

p      { color: red }
a, a p { color: blue }

When an <a> is inside a <p>, blue wins because the <a> is the nearest ancestor that set the color. When a <p> is inside an <a>, blue wins because a p is more specific than just p.

Upvotes: 3

Related Questions