On CSS counters plus a CSS3 Reversi UI

CSS Counters have a lot more potential than most web developers seem to think. The common use case consists of something like:

somecontainer { counter-reset: foocount; }
Ε { counter-increment: foocount; }
Ε::before { content: counter(foocount) ". "; }

commonly used to add numbering to section headings or re-create an <ol>’s counters in order to style them (since browser support for ::marker is ridiculous).

Have you ever thought of applying the counter to different elements than the ones being counted? This way we’re able to count elements and display their total count somewhere with CSS alone! (and with the variety of selectors in CSS3, I see great potential here…). I’m referring to something like:

ul { counter-reset:foo; }
li { counter-increment:foo; }
p::after { content:counter(foo); }

From my tests, this works flawlessly in Firefox, Safari, Opera and Chrome (I’ve only checked the latest stable though), as long as the element that displays the count comes after the elements being counted (in the markup).

Another underutilized aspect of CSS counters (well, far less underused than the above, but still) is how we can combine multiple in the same pseudoelement. For instance, to count rows and cells of a table and display the count inside each cell:

table {
	counter-reset:row;
}

tr {
	counter-increment:row;
	counter-reset:cell;
}

td {
	counter-increment:cell;
}

td::after {
	content:counter(row, upper-alpha) counter(cell);
}

Which displays counters like A1, A2, A3, B1, B2, B3, etc in the cells. When the content property is more properly implemented, you wouldn’t even need the last rule.

Last but not least, a CSS3 Reversi UI (no images used!) I created a while ago that demonstrates the above (and various other things, like –finally– a use case for :empty :P ). Looks fine only in Firefox and Opera 10.5, due to lack of support for inset box shadows in Safari and buggy support in Chrome. Works fine in all 4 of them (IE is out of the question anyway).

Screenshot of the UI

The displayed counts of each player’s pieces (top right corner) are just CSS counters. Same goes for every cell’s name. This is mostly a proof of concept, since it’s impossible to determine if someone won by CSS alone, so we would have to count the pieces in JS too.

As a game it’s not finalized, you are basically only able to play against yourself and it doesn’t know when somebody won, so it’s not very useful or enjoyable. If someone wants to take it up and develop it further be my guest.

Note to avoid confusion: CSS Counters are not CSS 3. They are perfectly valid CSS 2.1. The “CSS3″ in the title (“CSS3 Reversi”) is due to other techniques used in it’s UI.

  • http://www.addyosmani.com Addy Osmani

    This is pretty cool. I just thought I should let you know there’s a little bug in Chrome at the top of the screen :) It appears to render one of the pieces outside of the main canvas area

  • http://leaverou.me Lea Verou

    If you’re talking about the one next to the name, it’s in my screenshot too. It indicates who’s currently playing.

  • http://www.addyosmani.com Addy Osmani

    Ahhh, I see. In that case allow me to rephrase my original comment – awesome work, Lea!

  • http://leaverou.me Lea Verou

    Thanks!

  • http://probablyprogramming.com Paul Bonser

    Aww, no diagonals?

    Awesome demo of some underused CSS features, though.

  • http://leaverou.me Lea Verou

    Wikipedia doesn’t mention diagonals, they are non-standard :P

    Thanks!

  • http://www.webedesigner.com/ Greg Harris

    Awesome, blog post!! I just had to comment.

  • GreLI

    Reversed «R» looks like cyrillic «Я» (http://en.wikipedia.org/wiki/Я) and reads as «Yaeversi» which is awful.

  • http://leaverou.me Lea Verou

    Then I guess you’d like it that Chrome doesn’t let transforms on ::first-letter :P

  • http://twitter.com/jsdev anthony ryan delorie

    Reall

  • http://twitter.com/jsdev anthony ryan delorie

    I can’t understate how cool this is and thank you… but why did you decide to use a table for the board? if you were to do the experiment over again what would you do differently.

  • http://leaverou.me Lea Verou

    It is a table: There are rows and columns and the relationship between them matters. Tables aren’t evil, only their misuse is.