:first-child
is a CSS selector that has been around since the CSS 2.1 spec. It is extremely useful and can be used effectively in various ways.
:last-child
has finally made an appearance in CSS 3. One would think that selectors such as first and last child are pretty much the same and would be implemented at the same time. This is not the case and they have pretty big performance differences.
Why isn't :last-child included within CSS2?
Jonathan Snook has an extremely informative article called Why we don't have a parent selector. It is an interesting & in depth article that covers why:last-child
is is so difficult for the browser to render and the article also has examples of :first-child
vs :last-child
.
Simply put, :last-child
only functions correctly once the entire page has loaded. The way :last-child
is rendered while the page is busy loading is executed differently throughout the different browsers.
Never use :last-child
I feel thatlast-child
is not necessary in most cases. I say most cases to cover myself but I haven't run into a situation where it's a necessity. The only times I find I need first/last-child is when I'm styling some sort of list.
A typical example would be: padding-right
and/or border-right
applied to a navigation's list items.
#nav li{border-right: 1px solid black; padding-right: 20px;}


#nav li:last-child{border-right: 0; padding-right: 0;}
This, however, won't even work on LTE IE8.
Use :first-child instead
:first-child
is contained within the CSS2.1 spec and therefore is supported within IE8 and has buggy support within IE7. It would be a FAR better idea to make use of this.
Swap the properties around — Instead of border/padding right, set it to border/padding left.
#nav li{border-left: 1px solid black; padding-left: 20px;}
The menu example would look something like this:
You can solve this problem very easily without
:last-child
and have it supported by IE7(buggy) and 8.
#nav li:first-child{border-left: 0; padding-left: 0;}
It's very easy to convert your CSS into very efficient and cross browser friendly CSS — All you need to do is think about what it is you are trying to doing and imagine how else it could be achieved.
I wish it worked properly in IE7
What is the deal with IE7 and:first-child
? Very basically, IE7 will see a comment as the first child. In IE7 li:first-child
would not work on the following html:
<ul>
<!-- This is a comment -->
<li>One</li>
<li>One</li>
<li>One</li>
</ul>
Now that we've established that things can be done more efficiently and in a cross-browser friendly fashion without too much difficulty, would it be possible to make :first-child
function properly within IE7 even if there are html comments throughout the html?
Your first thought might be:
No, it's the way IE7 renders HTML. Let's move onYour first thoughtWhat selectors do IE7 support that are more reliable and could solve this simple problem? IE7 supports adjacent selectors. I really love adjacent selectors and I think it is very under-rated. Chris Coyier has an article which explains adjacent selectors and other selectors too.
Basically, an adjacent selector selects the element that directly follows the targeted element. For example:
p + p{background: red}
This would select any paragraph element that has a preceding paragraph element. This would mean that the first paragraph element would not be selected because it does not contain any preceding paragraph element.
Pseudo-select via Non-selection
By this I mean that you could add a left border to every list item except the first. This could create the illusion of:first-child
.
li + li{border-left: 1px solid black; padding-left: 20px}
This probably isn't as efficient as :first-child
, but it does add to the cross-browser compatibility and it can be of great use in many cases.