
FizzBuzz in CSS3
I was reading Rachel Andrew's 24 ways post on Cleaner Code with CSS3 Selectors today, in which she covered nth-child
selectors, and I was reminded of the FizzBuzz phenomenon which swept through Programming Reddit a couple of years ago. I thought it would be relatively easy to implement a CSS solution to the problem based on the nth-child
selectors and generated content.
First I tried a quick test based on an ordered list and Rachel's example code for the table:
ol:nth-child(3n) li:after { content: "Fizz"; }
Using the advanced technique of copy and paste I quickly produced an ol
element with 100 li
's in it and observed the results. It wasn't quite a spectacular failure, but no Fizz appeared. A little reflection and I think I've figured out what I was doing wrong - the li
is already the nth-child
of ol
and there are no further li
child elements, so the rule doesn't match anything. After a bit of fiddling around I came up with two alternatives, cut out the li altogether:
ol :nth-child(3n):after { content: "Fizz"; }
Or use nth-of-type
directly on li
instead of nth-child
:
ol li:nth-of-type(3n):after { content: "Fizz"; }
Then I realised that the ordered list was probably a mistake - I ought to be printing the number when none of Fizz, Buzz or FizzBuzz applies. My initial thinking was that having the number built into the markup would make it easier, but now I realised I'd have to both remove the default numbers and then insert new numbers in. So I switched to a table with 100 rows in it and started reading up on counters and numbering. This seems to work almost like a programming language, first you declare your variable on the root element:
table { counter-reset: number; }
Then you stick it in a loop:
tr td:before { counter-increment: number; content: counter(number); }
So now I have a table which counts up to 100, I override the generated content for each third and fifth child:
tr:nth-child(3n) td:before { content: "Fizz"; } tr:nth-child(5n) td:before { content: "Buzz"; }
Finally specify the content for elements which are both a third and a fifth child:
tr:nth-child(3n):nth-child(5n) td:before { content: "FizzBuzz"; }
And, ta-da, FizzBuzz implemented in CSS (with the slightly unusual input requirement of a 100 row HTML table).
Print article | This entry was posted by robertc on 22/12/09 at 07:08:57 pm . Follow any responses to this post through RSS 2.0. |