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.
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.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;
}
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.
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
How to Overwrite Angular 2 Material Styles
Proper SCSS Asset Structure in Rails
Difference Between Body and * in CSS
Css: Background Image on Background Color
How to Handle 'Double Opacity' of Two Overlapping Divs
Less CSS: Abusing the & Operator When Nesting
Define an <Img>'s Src Attribute in CSS
Spacing Between Thead and Tbody
Using CSS to Make Table's Outer Border Color Different from Cells' Border Color
How to Remove Extra Margin Space Generated by Inline Blocks
Binding in Control with "Class" Attribute
Is There a 'Box-Shadow-Color' Property
CSS Display: Table Min-Height Not Working
Why Don't CSS Resets Use '*' to Cover All Elements
Image Scaling by CSS: Is There a Webkit Alternative for -Moz-Crisp-Edges