s4nji
s4nji

Reputation: 455

:last-child pseudo class confusion

In this JSFiddle, the last .tab class doesn't get the correct border-radius effect (top right rounded corner).

I think I have my logic correct in saying :last-child selects the last .tab of .tabbed in this case.

What am I doing wrong?

CSS:

body {
    background: black;
    color: white;
    padding: 5px; }

.tabbed {
    height: 550px;
}

.tabbed .tab {
    padding: 6px 14px;
    background: rgba(255,255,255,0.25);
    border: 1px solid rgba(255,255,255,0.4);
    border-radius: 0px;
    border-left-width: 0;
    float: left;
}

.tabbed .tab:first-child {
    border-radius: 3px 0 0 0;
    border-left-width: 1px;
}

.tabbed .tab:last-child {
    border-radius: 0 3px 0 0;
}

HTML:

<ul class='tabbed'>
    <li class='tab'>Menu 1</li>
    <li class='tab'>Menu 2</li>
    <li class='tab'>Menu 3</li>
    <li class='tab'>Menu 4</li>
    <li class='tab'>Menu 5</li>
    <li> <br/><br/> </li>
    <li class='dummy'>Content 1</li>
    <li class='dummy'>Content 2</li>
    <li class='dummy'>Content 3</li>
    <li class='dummy'>Content 4</li>
    <li class='dummy'>Content 5</li>
</ul>

Upvotes: 4

Views: 1447

Answers (4)

nicerobot
nicerobot

Reputation: 9235

Here's how i would do it:

body {
    background: black;
    color: white;
    padding: 5px; }

.content {clear:both;}
.tall {
    height: 550px;
}

.tabbed .tab {
padding: 6px 14px;
background: rgba(255,255,255,0.25);
border: 1px solid rgba(255,255,255,0.4);
float: left; }

.tabbed .tab:first-child {
border-radius: 3px 0 0 0;
border-left-width: 1px; }

.tabbed .tab:last-child {
border-radius: 0 3px 0 0; }

And because i think it seems inappropriate to include the content within a class called tabbed, change the HTML to be structured as:

<div class="tall">
<ul class='tabbed'>
    <li class='tab'>Menu 1</li>
    <li class='tab'>Menu 2</li>
    <li class='tab'>Menu 3</li>
    <li class='tab'>Menu 4</li>
    <li class='tab'>Menu 5</li>
</ul>
<ul class="content">
    <li class='dummy'>Content 1</li>
    <li class='dummy'>Content 2</li>
    <li class='dummy'>Content 3</li>
    <li class='dummy'>Content 4</li>
    <li class='dummy'>Content 5</li>
</ul>
</div>
<hr/><!-- just here to show you the height remains -->

Upvotes: 1

ScottS
ScottS

Reputation: 72261

In a comment, you state: "It needs to be on the same ul parent. Or another ul, below the last li on the first ul." If that is so, then do this:

<ul class='tabbed'>
    <li class='tab'>Menu 1</li>
    <li class='tab'>Menu 2</li>
    <li class='tab'>Menu 3</li>
    <li class='tab'>Menu 4</li>
    <li class='tab'>Menu 5</li>
    <li>
    <ul>
    <li class='dummy'>Content 1</li>
    <li class='dummy'>Content 2</li>
    <li class='dummy'>Content 3</li>
    <li class='dummy'>Content 4</li>
    <li class='dummy'>Content 5</li>
    </ul>
    </li>
</ul>

Then this css (with modern browsers):

.tabbed {
height: 550px; }

.tabbed .tab {
padding: 6px 14px;
background: rgba(255,255,255,0.25);
border: 1px solid rgba(255,255,255,0.4);
border-radius: 0px;
border-left-width: 0;
float: left; }

.tabbed .tab:first-child {
border-radius: 3px 0 0 0;
border-left-width: 1px; }

.tabbed .tab:nth-last-child(2) {
border-radius: 0 3px 0 0; }

.tabbed li:last-child {
   clear: left;
}

See this fiddle.

Upvotes: 3

Andrew Marshall
Andrew Marshall

Reputation: 96934

To expand on Didier G.'s answer, what you should really be using here is the :first-of-type & :last-of-type pseudo selectors. However, the :nth-of-type selector (and its similar shorthand versions) does not appear to support using a classname for searching, only selecting, e.g. the following will select the first child of .tabbed, if and only if it has the class .tab:

.tabbed .tab:first-of-type

whereas this will select the first child of .tabbed that is of type li:

.tabbed li:first-of-type

I cannot find any reference explicitly stating this behavior, but it is vaguely implied in the specification:

The :nth-of-type(an+b) pseudo-class notation represents an element that has an+b-1 siblings with the same expanded element name

Where an expanded element name is the tag name, and cannot be a class or ID selector.

You can see this behavior live on JSFiddle.

Upvotes: 1

Didier Ghys
Didier Ghys

Reputation: 30666

According to this documentation:

The :first-child pseudo class means "if this element is the first child of its parent". :last-child means "if this element is the last child of its parent". Note that only element nodes (HTML tags) count, these pseudo-classes ignore text nodes.

See also W3C doc

It is not applied in your case because the last .tab is not the last child of the parent ul.

If you create two lists, then the css is applied as expected.

Upvotes: 5

Related Questions