The Hashrocket blog has a little cousin now: Today I Learned is doing quite well for itself these days, with over 200 posts from 13 different Rocketeers since its launch in May. How do I know this? We've got a spiffy new statistics page.

Given that TIL's format lends itself to flurries of bite-size posts from a variety of people, we decided that a statistics page would be a great way to help visitors get a handle on what (and how often) we're posting. We list channels, authors, and most popular posts, all capped by a bar chart showing posts per day for the last 30 days.

After toying with some of our usual graphing libraries, I decided to see if I could pull off building a responsive bar chart, complete with mouseover labels, in just CSS – so I did. Here's how it works.

I wanted a fully-responsive chart with 30 bars. This is where display: flex really shines. Before flex, I'd probably have to use some table-cell hackery, but no more. With display: flex and align-items: stretch, we can easily make a set of any arbitrary number of bars with 2 pixels in between each; flex handles stretching the bars to the proper width & height.

Once I had the bar backgrounds in place, positioning the bars themselves was simple: I just stuck an absolutely positioned element inside each background element, with a percentage height output by our Rails view:

Lastly, I wanted the chart labels to not require JavaScript or extra elements of any kind. This is where the attr() property is really useful in CSS: I could set up labels as :before and :after elements on each bar, and define their content by accessing a data attribute using attr(). Here's a subset (minus aesthetic styling) of the code to show the day's date above each bar:

As you'll see, there's some negative-margin stuff to center our label properly, some positioning to stick it on the top of the bar, and content: attr(data-date), which simply takes the text from the aforementioned data-date attribute and sticks it in the :before element. Convenient!

Our hover state also shows the number of posts on a particular day – to accomplish this, we use a lot of the same code from above, plus some different positioning to put it below the bar, and some different content. The content attribute conveniently concatenates attr with any other string info, so we can do this:

&:aftermargin-top:.5remtop:100%content:attr(data-amount)" posts"

And because overlooked pluralization ("1 posts") drives me nuts, here's where that conditional singular class comes in. Having to do this is a little goofy, but hey, CSS doesn't know how to pluralize, so we just have a more robust language tell it what to do.

&.singular:aftercontent:attr(data-amount)" post"

So there you have it – a responsive, CSS-only bar graph, using some nifty new(ish) features. I put together a basic Codepen with the example code from this post, and of course check out the real TIL Statistics page for the full version, which also includes some more hover effects and label-positioning intricacies.