10
\$\begingroup\$

So someone challenged me to write FizzBuzz using CSS only. This was the best I could come up with, but I think the "divisible by 5, not divisible by 3" CSS rule is a bit clunky. So I'm looking for advice to provide a more readable and maintainable solution.

ol li {
  list-style-type: none;
  counter-increment: listCounter;
}
ol li:before {
  content: counter(listCounter);
}
ol li:nth-child(3n + 3):before {
  content: 'fizz';
}
ol li:nth-child(5n + 5):not(:nth-child(3n + 3)):before {
  content: '';
}
ol li:nth-child(5n + 5):after {
  content: 'buzz';
}
<ol>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ol>

\$\endgroup\$
4
\$\begingroup\$

Instead of putting ol li:before { content: counter(listCounter); } on every element and cancelling out some of them with ol li:nth-child(5n + 5):not(:nth-child(3n + 3)):before { content: ''; }, I would just show the counter on elements that need it.

I don't know why you put + 3 and + 5 in the selectors — they don't appear to be necessary.

ol li {
  list-style-type: none;
  counter-increment: listCounter;
}
ol li:not(:nth-child(3n)):not(:nth-child(5n)):before {
  content: counter(listCounter);
}
ol li:nth-child(3n):before {
  content: 'fizz';
}
ol li:nth-child(5n):after {
  content: 'buzz';
}
<ol>
  <li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li>
</ol>

Strictly speaking, the second rule could be reduced to just

ol li:not(:nth-child(5n)):before {
  content: counter(listCounter);
}

since the following rule supersedes it in for multiples of 3.

\$\endgroup\$
  • \$\begingroup\$ Awesome! I forgot that n in nth-child could never be zero. The +3 and +5 was to prevent zero from triggering fizzbuzz. \$\endgroup\$ – Pete Sep 1 '16 at 20:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.