Making Charts with CSS

Share this:

There are many ways to make visual representations of data: bar charts, line graphs, scatter diagrams, sparklines... not to mention the many ways in which you can implement them on the web. In this post I'll be looking at plain CSS methods for styling data. But before we take a look at some examples, I think it's worth briefly going over our design goals first.

Guidelines for Chart Making

There are three guidelines to developing a chart on the web:

Accessibility: everyone should be able to view some format of the data we present, even if it's a boring table (boring is better than nothing).

Ease of development: graph-making shouldn't be unnecessarily complex, and we'll certainly want to avoid technical debt for the future.

Performance: we need to make sure that users don't spend a lot of time waiting for assets to download or for elements to be painted to the screen.

These goals are likely to change depending on the type of chart that make, as performance is going to be less of a concern for a static bar chart than a crazy interactive map. With these guidelines in mind, let's look at a few examples.

CSS Bar Charts

There are a couple of ways to make a simple bar chart in CSS. For starters we'll use a definition list for our data:

This technique is relatively simple, but I can't help but think that this information should always be set in a table by default. Although I'm a little wary of styling tables in this way, that certainly doesn't mean it's impossible. For instance, Eric Meyer wrote about this technique and described how to position finicky table elements to behave like a bar chart. This is his original markup for the table:

Unlike the example I used earlier, where I implemented a number of automatically generated helper classes in Sass to define the width of the bar charts, Eric used inline styles on the td element with those values being calculated server side or with JavaScript, rather than added by hand.

I really like that each row in the table has a header such as Q1, Q2, etc. — that feels really neat and tidy rather than depending on a definition list to describe the content. They're easy to position and will fall back nicely to a standard table if the CSS fails to load for whatever reason.

However, one of the problems with this approach is that it requires absolutely positioning each table row side by side, which means that if we want to add more data then we'll need to do a lot more work than simply updating the markup. This means it could be a pain to work with in the future.

Sparklines

We don't always have to use tables when representing information like this. That's probably the case when we make a series of sparklines, tiny graphs that sit next to a line of text and help readers get a quick overview of the information. Wilson Miner outlined this method and made sure to focus on the accessibility of the information beforehand:

I've updated the original markup from what Wilson used since to me this feels like it should fit into a figure, as the docs on MDN state that:

Usually [a figure]... is an image, an illustration, a diagram, a code snippet, or a schema that is referenced in the main text, but that can be moved to another page or to an appendix without affecting the main flow.

That makes a lot more sense to me than a plain ul element. But anyway, here's what that looks like without any CSS:

Very accessible! Next up we can add styles to that sparkline element and position it to the right of the link with inline-block. And again, we could use that Sass class generator we used earlier to set the height of each bar. But, let's keep those styles inline just for now:

Make sure to hover over each entry in the list to see an expanded version of the diagram that I've added. Although it's not particularly helpful in terms of breaking down the data, it shows that we aren't stuck with charts in one single representation; manipulating these visualisations with such ease is a great advantage when using simple markup and CSS.

CSS Pie Charts

Lea Verou recently wrote a great piece about making pie charts. One possibility she suggests is using pseudo elements that cover a circle and nudging them around with transform: rotate().

Another possibility is SVG, which has a number of advantages, some of which we'll list in the next section.

If browsers supported conic-gradient(), that would be a very compelling way to create them. They don't quite yet, but Lea has a polyfill for it that works wonderfully. Here's a pie chart demo using it that we made for one of the last polls we did here on CSS-Tricks:

Wrapping up

Plain CSS and markup solutions for charts and graphs work to a certain extent, and in many situations they're probably the safest bet. But I think it's worth exploring alternative solutions to representing data.

In the next post in this series I'll be looking at SVG and JavaScript solutions to making charts.

You put the labels in the left column, then in the second column you use a div and figure out the relative percentage of the width of that column for each value. Then float the actual value to the right of the div.

Why set up classes for each width % on the bar chart? I’ve always just stuck an inline style on the row, means you don’t clog up your stylesheet with unnecessary styles and gives you more flexibility (e.g. you can use 83.46217% if you so wish).

style="width:83%" takes up less space than class="percentage-83", and saves all of that space in the stylesheet.

👋

CSS-Tricks* is created, written by, and maintained by Chris Coyier and a team of swell people. It is built on WordPress and powered up by Jetpack. It is made possible through sponsorships from products and services we like.