Koenyn
Koenyn

Reputation: 704

how can I compound css selectors together

is it possible to use a :not() selector with a :nth-of-type(1) selector?

i.e. I want to select the first

that doesn't have the title "something"

<html>
    <head>
        <style type="text/css">
            p
            {
                color:#000000;
            }
            p:not([title=something]):nth-of-type(1)
            {
                color:#ff0000;
            }
        </style>
    </head>
    <body>

        <h1>This is a heading</h1>

        <p title="something">This is a paragraph.</p>
        <p>This is another paragraph.</p>
        <p>This is another paragraph.</p>

        <div>This is some text in a div element.</div>


    </body>
</html>

Upvotes: 2

Views: 1476

Answers (3)

BoltClock
BoltClock

Reputation: 724402

As mentioned by the other answers, :nth-of-type() only refers to the element type, which in this case is p. The selector p:not([type=something]):nth-of-type(1) simply means a p element that is :not([type=something]) and is also the first p.

Anyway, what you're asking can be done in pure CSS using the general sibling selector, but may involve unnecessarily verbose and repetitive selectors:

p:not([title=something]) ~ p:not([title=something])
{
    color:#000000;
}
p:not([title=something])
{
    color:#ff0000;
}

If you just want to apply this to p elements without a title attribute, you can shorten your selectors a little:

p:not([title]) ~ p:not([title])
{
    color:#000000;
}
p:not([title])
{
    color:#ff0000;
}

I came up with this technique for use with classes first, which I describe in greater detail here, but it can be applied to a number of things, including attributes, for which I have another example here.

Upvotes: 2

gen_Eric
gen_Eric

Reputation: 227310

The nth-of-type is acting on the original selector (p), it's not acting on the result of p:not([title=something]).

p:not([title=something]):nth-of-type(1)

This is saying, find the <p> without a title of "someting" that is also the 1st <p> on the page. This doesn't find any elements as the 1st <p> has the title "something".

What you want is the 1st <p> that doesn't contain the title "something". I don't know if CSS has a good way of doing that.

If you're willing to use jQuery, you can use do this:

$('p:not([title="something"]):eq(0)')

or:

$('p').not('[title="something"]').eq(0)

Upvotes: 4

Rusty Fausak
Rusty Fausak

Reputation: 7525

The problem is that the nth-of-type pseudo-class is defined as:

[nth-of-type] matches elements on the basis of their positions within a parent element’s list of child elements.

So the pseudo-class :nth-of-type(1) is limiting your selection to the p child at position 1.

Your pseudo-class not([title=something]) is limiting your selection to the p elements without the attribute/value title='something', just as you suspect.

The two selectors together are resulting in no elements because the p child at position 1 has title='something'.

For a better understanding, try the following:

p:nth-of-type(1) { color: red; }
p:not([title=something]) { text-decoration:underline; }

More information: Pseudo-classes, nth-of-type

Upvotes: 3

Related Questions