Rounin Rounin - 4 months ago 8
CSS Question

Unexpected behaviour from :nth-of-type(n+1)

I'm an avid user of the

x-of-type
family of CSS pseudo-classes:


  • :first-of-type

  • :last-of-type

  • :nth-of-type

  • :nth-last-of-type



I am usually fairly adept at ensuring that any series of similar elements (list items etc.) displays exactly as I wish it to.

In the last hour, however, I have been stuck on how to achieve the following result with a single style declaration:


  • Item 1 has a
    border-bottom

  • Item 2 has a
    border-bottom

  • Item 3 has a
    border-bottom

  • Item 4 (the last item) has no
    border-bottom



I have achieved what I need, using:

.item {
border-bottom:6px solid rgb(227,227,227);
}

.item:last-of-type {
border-bottom:none;
}


but for the purposes of brevity, I'd still prefer to achieve the same result with a single declaration.

Question:

Why won't

.item:nth-of-type(n-1) {
border-bottom:6px solid rgb(227,227,227);
}


or

.item:nth-last-of-type(n+1) {
border-bottom:6px solid rgb(227,227,227);
}


work?

Is it because
n
is simply an infinite list of numbers, including numbers before and after the number of targeted elements on the page?

If so, how can I declare "Everything but the last item" in a single declaration?

(And apologies in advance, if it's something really obvious and I've just failed to notice it...)




Added...



Here is the HTML I'm working with:

<aside>
<img src="" title="" alt="" />
<span class="something-else">Blah</span>
<span class="item">Item Details</span>

<img src="" title="" alt="" />
<span class="something-else">Blah</span>
<span class="item">Item Details</span>

<img src="" title="" alt="" />
<span class="something-else">Blah</span>
<span class="item">Item Details</span>

<img src="" title="" alt="" />
<span class="something-else">Blah</span>
<span class="item">Item Details</span>
</aside>

Answer

Is it because n is simply an infinite list of numbers, including numbers before and after the number of targeted elements on the page?

Yes, that's why :nth-of-type(n-1) appears to match every element: n counts an infinite number of times. So the last of type will still match, when n is 1 plus the total number of children of that element type. In other words, the expression n-b for any b (or n+b for b <= 1) is equivalent to n (itself n-0), which is a guaranteed match.

:nth-last-of-type(n+1) is close, but the reason that doesn't do what you want is because n starts counting from zero, so when n is zero, n+1 matches the last of type.

If so, how can I declare "Everything but the last item" in a single declaration?

You have two ways. One that you were close to is :nth-last-of-type(n+2). The other is the much clearer :not(:last-of-type).

Comments