I’ve been trying to put some of CSS3’s nth-*
selectors to use in a site I’m working on right now, and I’ve run into a problem. I’m testing my markup and styles in Safari 5 (before moving on to other browsers), and I am trying to style child elements 3, 7, 11, etc. So I write this rule:
p:nth-of-type(4n - 1) { … }
That should work, right? After all, 4(1) − 1 = 3; 4(2) − 1 = 7; 4(3) − 1 = 11.
Well I open up Safari, and my changes haven’t taken. OK. How about a different but equivalent equation?
p:nth-of-type(4n + 3) { … }
Again, pretty simple: 4(0) + 3 = 3; 4(1) + 3 = 7; 4(2) + 3 = 11. The last one hasn’t taken, for whatever reason, but this one’s right on.
Still nothing.
I begin to doubt my math skills. I’ve been doing software of one type or another for 15 years, but my bachelor’s degree is in electrical engineering. I had to take four calculus classes, linear algebra, and differential equations. OK, I haven’t used most of that in years, but an + b
is simple algebra—stuff I’ve been doing for over 20 years. I know simple algebra.
I decide to fire up Firefox (version 3.6.12). Lo and behold, there is the formatting I’ve been trying desperately to get to show up. Firefox gets it (so does Opera, for the record), but Safari doesn’t (neither does Chrome). Evidently we have a Webkit bug.
For grins, even though it won’t get me where I want to go, I try this:
p:nth-of-type(4n) { … }
The formatting appears correctly in both Firefox and Safari! Therefore Webkit does understand nth-of-type
, but something about an + b
gives it heartburn that an
doesn’t.
I try one more thing: remove the whitespace in the equation.
p:nth-of-type(4n+3) { … }
It works! Safari and Firefox both rendered the formatting properly. Webkit just doesn’t care for the whitespace.
But is whitespace forbidden in the equation? Here’s what the spec has to say:
Whitespace is permitted after the “(“, before the “)”, and on either side of the “+” or “-” that separates the an and b parts when both are present.
Valid Examples with white space:
:nth-child( 3n + 1 ) :nth-child( +3n - 2 ) :nth-child( -n+ 6) :nth-child( +6 )
So then, we do have a bug. Webkit doesn’t respect the whitespace in nth-child
and the other nth-*
selectors. The workaround is easy enough, but it’s going to be hard for me to break the habit of adding space around the arithmetic operator. It’s a best practice, so far as I’m concerned, for code readability. Nevertheless, the expressions are simple enough that it’s not a terrible price to pay to get Safari/Chrome to play.
If you want to see it in action, check out this test file. Below is a screen capture of Safari’s rendering (left) and Firefox’s rendering (right). As you can see, Safari only renders nth-child(2n+1)
correctly while Firefox renders them both correctly.