Project: FizzBuzz in CSS
I wanted to try FizzBuzz in CSS. I've written it insert overestimate times in JavaScript so I wanted to try something different.
If by chance you're not familiar, the usual formulation of FizzBuzz is to write a program with these rules:
- Print the numbers from 1 to 100 (inclusive) except...
- Don't print each number which is divisible by 3, instead print "Fizz"
- Don't print each number which is divisible by 5, instead print "Buzz"
- Print "FizzBuzz" for those numbers which are divisible by both 3 and 5
Solution
This is my best attempt. The "output" immediately follows this style
element:
<style contenteditable></style>
<div class="solution">
</div>
Logbook
Fri Sep 22 07:40:06 PM PDT 2023
My first idea was to create a hundred <div>
s manually then style them to produce the FizzBuzz output.
I knew I could print incremental integers by styling those elements as list items. I searched mdn increment list item number css
and found many useful links. I started with MDN's "Using CSS Counters. I tried a short example, first the CSS:
<style contenteditable></style>
By the way, the contenteditable
attribute above means you can edit this to see what happens.
To use the example CSS, I threw 3 spans within this div
:
<div class="example1">
</div>
It worked! I could see the content
with the incrementing counter from my CSS. Nice. Ostensibly if I were to put 100 spans
in here, we'd see the numbers 1 to 100. I felt like I had the easy part of FizzBuzz in the bag.
For the next parts, I figured I could use the nth-child
CSS tools. I hadn't used them in a while so again I had to go to the MDN page on :nth-child()
. It was the "Functional notation" I had in mind specifically, where I could define the polynomial An+B
.
For Fizz
, my rule would be 3n+0
. I needed the +1
since the n
count starts at 0, but my list starts at 1. With that, I could override the content from my counter. I made another small example before I tried the whole shebang, to make sure I got it right.
<style contenteditable></style>
This time I used div
s instead of span
s so they'd flow downward, and I used more to clarify the effect.
<div class="example2">
</div>
Okay it almost worked, except I got the polynomial wrong. Of course 3 * 0 + 1
is 4
, but I want it to be 3
, so I actually didn't need the +1
. You can try messing with the above style
to see for yourself!
Now I felt ready to try the whole thing:
<style contenteditable></style>
<div class="attempt1">
</div>
It worked! I had to make the numerical observation that the only numbers divisible by 5
and 3
would be those divisible by 15
.
I actually figured that out by looking at the working result. I had gotten the answer before with more CSS tricks, but I felt that was less straightforward.
If you're interested, the trick was to use ::before
for the Fizz
numbers and ::after
for the Buzz
numbers such that if they were both present the content
rules wouldn't collide.
This required an extra rule for Buzz
numbers to clear the ::before
content, in case they weren't Fizz
. But that rule had to be placed specifically in the CSS document order so that it wouldn't override the Fizz
rule in the case that it was a FizzBuzz
number.
Here's a small example:
<style contenteditable></style>
<div class="attempt2">
</div>
The way I wrote the output in my examples, div
s and span
s within pre code
containers, had too much line spacing. It was obnoxious on 100 item lists. I wrote some quick CSS to fix it.
<style contenteditable></style>
I wanted to try a trick to change every instance of the word Fizz
on this page to Crackle
and Buzz
to Pop
. So FizzBuzz
would become CracklePop
. This was utterly unrelated to the main goal, just a fun thing. I decided to try a query string toggle first. So if a user accesses this site with the query string ?crackle=pop
then this would be a CracklePop page instead.
Luckily I only ever wrote Fizz
and Buzz
with capitalized first letters. If I ever wrote them lower case, I'd have to find a better solution or add special cases.
<script></script>
You can try it yourself! Just put ?crackle=pop
on the end of the current URL and retry.