Browser Support for CSS :First-Child and :Last-Child

Browser support for CSS :first-child and :last-child

:first-child and :last-child, along with complimentary compatibility chart.

:first-child is supported IE9 properly, and IE7 and IE8 sort of (see chart).

:last-child is supported by IE9+ only.

Both of them are supported well by the good browsers.

first-child & last-child cross-browser compatibility

Here's the thing. At the time I wrote the original answer:

  • YouTube has dropped support for IE6
  • Facebook's timeline won't work in IE7
  • Microsoft is urging people to use at least IE8 (due to for XP users).

These are big companies who have large user bases, and even they are urging people to move or get nothing (or at least get basic functionality).

According to this page by quirksmode, :first-child is supported in IE7+, but :last-child is only supported in IE9+. Which means if you are planning to use this, you should get ready to forget the older IE altogether.

However, you can use selectivizr which gives you leverage to make these styles work for older browsers.

CSS first-child and last-child don't work when used on the same element

I'm wondering why is that and if there is any workaround to that in CSS? It seems like CSS bug to me - first element can be also last element.

It's not a bug. It's how the cascade works: if an element is both the first child and the last child, then if you have :first-child and :last-child in separate rules and they both match the same element, then anything in the later declared or more specific rule will override the other.

You can find an example of this behavior here, with the border-radius shorthand property, and workarounds that include using the component properties instead of the shorthand, as well as specifying a separate rule altogether using one of the following selectors...

I'm looking for something like: "first child is also last child" selector. Does it exist?

Literally, you would chain both pseudo-classes like this, which works fine:

:first-child:last-child

However there exists a special pseudo-class that acts the same way:

:only-child

The main difference (in fact, the only difference) between these two selectors is specificity: the first one is more specific as it contains one additional pseudo-class. There is no difference even in browser support, as :last-child and :only-child are both supported by the exact same versions of each browser.

css ie8 first-child & last-child

You have two issues here: Firstly the :last-child selector, and secondly the RGBA background colours.

  1. IE8 does not support :last-child. (It does support :first-child though)

    You can see the browser support for these (and all other CSS selectors) at Quirksmode.org.

    The quickest and easiest way to deal with this if you need IE8 support is simply to add classes to the relevant elements and style them that way instead. It's the old-school way of doing things, but then IE8 is something of an old-school browser.

    If you really need to use selectors like :last-child, and you really need to support IE8, there are Javascript solutions you could try:

    • http://selectivizr.com/ -- this is a JS library that adds support for a bunch of CSS selectors to old IE versions. It requires you to also use another lib such as jQuery that it uses to do the hard work.

    • https://code.google.com/p/ie7-js/ -- this is a JS library that tries to patch old IE versions to fix as many of the bugs and quirks as possible and back-fill as many missing features as possible. It's pretty wide-ranging in what it does. It does include most of the advanced CSS features.

    Either of these libraries should do the trick for you to add :last-child support, unless you have users with JS turned off.

  2. However as I said, IE8 does support :first-child, so missing selectors isn't the reason for your code not working in this case. The reason your CSS isn't working for :first-child is because you're using an RGBA colour for the background. IE8 doesn't support RGBA colours.

    For this, the only solution available is a JS library called CSS3Pie. This adds various CSS3 features to IE6/7/8, including RGBA colour support (albeit to a limited extent; it doesn't do everything).

CSS how to apply :first-child and :last-child

Directly fixing what you provided, you need:

.addthis_toolbox a:first-child
{
margin-bottom:5px;
}
.addthis_toolbox a:last-child
{
margin-bottom:0px;
}

The problem with .addthis_toolbox:first-child is that it selects a .addthis_toolbox that is the first child of its parent. And that's not what you wanted.


I might be getting confused here, but if you're trying to add a gap between every a, use this to handle it:

.addthis_toolbox a + a {
margin-top: 5px;
}

It's neater and has better browser support due to not using :last-child.

not:first-child selector

One of the versions you posted actually works for all modern browsers (where CSS selectors level 3 are supported):

div ul:not(:first-child) {
background-color: #900;
}

If you need to support legacy browsers, or if you are hindered by the :not selector's limitation (it only accepts a simple selector as an argument) then you can use another technique:

Define a rule that has greater scope than what you intend and then "revoke" it conditionally, limiting its scope to what you do intend:

div ul {
background-color: #900; /* applies to every ul */
}

div ul:first-child {
background-color: transparent; /* limits the scope of the previous rule */
}

When limiting the scope use the default value for each CSS attribute that you are setting.

Is the :last-child selector bad for performance?

If it was deferred from CSS2 for performance concerns, but reintroduced in Selectors 3, I suspect that it's because performance is no longer an issue as it previously was.

Remember that :last-child is the definitive and only way to select the last child of a parent (besides :nth-last-child(1), obviously). If browser implementers no longer have performance concerns, neither should we as authors.

The only compelling reason I can think of for overriding a border style with :first-child as opposed to :last-child is to allow compatibility with IE7 and IE8. If that boosts performance, let that be a side effect. If you don't need IE7 and IE8 support, then you shouldn't feel compelled to use :first-child over :last-child. Even if browser performance is absolutely critical, you should be addressing it the proper way by testing and benchmarking, not by premature optimization.

CSS nth-last-child browser support

HTML

  <ul>
<li>First Item</li>
<li>Second Item</li>
<li>Third Item</li>
<li>Fourth Item</li>
<li>Fifth Item</li>
</ul>

CSS:

li {
background: slategrey;
}
/* select the second-last item */
li:nth-last-child(2) {
background: lightslategrey;
}

Sample Image

See more details

Mention in HTML5Please Selectors

Adding a list to HTML5Please Selector section for css, which mentions the availability of nth-last-child after IE8 sunset.

Usage of selectivizr

<script type="text/javascript" src="[JS library]"></script>
<!--[if (gte IE 6)&(lte IE 8)]>
<script type="text/javascript" src="selectivizr.js"></script>
<noscript><link rel="stylesheet" href="[fallback css]" /></noscript>
<![endif]-->
  • Just include this script in your page's tag. If you're not
    already using a JavaScript library, you'll need to choose one from
    the table below.

Sample Image

IE8 :nth-child and :before

You can (ab)use the adjacent sibling combinator (+) to achieve this with CSS that works in IE7/8.

See: http://jsfiddle.net/thirtydot/LvvNL/64/

/* equivalent to li:nth-child(1) */
#nav-primary ul li:first-child a {
border-top: 5px solid red;
}
/* equivalent to li:nth-child(2) */
#nav-primary ul li:first-child + li a {
border-top: 5px solid blue;
}
/* equivalent to li:nth-child(3) */
#nav-primary ul li:first-child + li + li a {
border-top: 5px solid green;
}​

You cannot emulate more complex variations of :nth-child() such as :nth-child(odd) or :nth-child(4n+3) with this method.

Is there a CSS selector for the first direct child only?

What you posted literally means "Find any divs that are inside of section divs and are the first child of their parent." The sub contains one tag that matches that description.

It is unclear to me whether you want both children of the main div or not. If so, use this:

div.section > div

If you only want the header, use this:

div.section > div:first-child

Using the > changes the description to: "Find any divs that are the direct descendents of section divs" which is what you want.

Please note that all major browsers support this method, except IE6. If IE6 support is mission-critical, you will have to add classes to the child divs and use that, instead. Otherwise, it's not worth caring about.



Related Topics



Leave a reply



Submit