KYLEJLARSON

How to Create CSS3 Pie Charts

Last week I decided to update my online resume to make it a little more graphical, because well… I’m a designer. The first step was coming up with some good ways to represent data, and pie charts seemed like a good fit to show skill development. Pie charts are pretty simple to create using a spreadsheet program or a drawing program, but I wanted something out of the ordinary that didn’t require creating new graphics every time I update them. It seemed like it should be possible with the new capabilities of CSS3 so I started working on a solution.

The two most promising things I found were Google’s Chart Wizard, (which uses javascript) and a CSS3 Pie Chart Article from Atomic Noggin. I wanted to do something purely with CSS & HTML so I took the ideas from that article and tweaked them a bit to get the result that I wanted.

There were a few things that I wanted to do differently from the original article:

  1. In the article the pie pieces are pulled out from the sphere and I wanted a solid circle.
  2. Once aligned as a solid sphere there were some rendering issues (in some browsers) aligning clipped shapes next to each other that left gaps between the shapes.
  3. I wanted to be able to add styles to the full css pie chart such as a border or drop-shadow.

Creating a Drop-Shadowed Circle

My first step was creating a circle that will be the bottom layer of the chart. This bottom circle will also hold any border or drop-shadow style. Additionally, I’ve put a div with a set height around the circle so it stays inline with the content (as the circles will be absolutely positioned to stay on top of each other). To create a circle, simply add a border-radius that is half the pixel value of the width of a square div. You’ll notice below I’ve used browser specific css tags (e.g. -moz-border-radius) for the CSS3 elements. Currently CSS3 support is varied between browsers. Eventually, as full support is included in browsers, you won’t need them any more and this will be much simpler to manage.

<style>
     .pieContainer {
          height: 100px;
     }
     .pieBackground {
          background-color: grey;
          position: absolute;
          width: 100px;
          height: 100px;
          -moz-border-radius: 50px;
          -webkit-border-radius: 50px;
          -o-border-radius: 50px;
          border-radius: 50px;
          -moz-box-shadow: -1px 1px 3px #000;
          -webkit-box-shadow: -1px 1px 3px #000;
          -o-box-shadow: -1px 1px 3px #000;
          box-shadow: -1px 1px 3px #000;
     } 
</style>
<div id="pieContainer">
     <div class="pieBackground"></div>
</div>

Adding a Slice to the CSS Pie Chart

Next you’ll want to create a half circle by using clipping to hide the 2nd half. Unless you want exactly 50% you’ll need to change the size of that circle by dropping it inside of a div that controls the rotation and use the inner div to adjust the size. For the first slice we’ll start the outer div at 0 degrees, which is the default, so we’ll only need to edit that for additional slices. (* Note that I’m adding to the code above and only displaying the new CSS.)

<style>
     .pie {
          position: absolute;
          width: 100px;
          height: 100px;
          -moz-border-radius: 50px;
          -webkit-border-radius: 50px;
          -o-border-radius: 50px;
          border-radius: 50px;
          clip: rect(0px, 50px, 100px, 0px);
     }
     .hold {
          position: absolute;
          width: 100px;
          height: 100px;
          -moz-border-radius: 50px;
          -webkit-border-radius: 50px;
          -o-border-radius: 50px;
          border-radius: 50px;
          clip: rect(0px, 100px, 100px, 50px);
     }
     #pieSlice1 .pie {
          background-color: #1b458b;
          -webkit-transform:rotate(50deg);
          -moz-transform:rotate(50deg);
          -o-transform:rotate(50deg);
          transform:rotate(50deg);
     }
</style>

<div class="pieContainer">
     <div class="pieBackground"></div>
     <div id="pieSlice1" class="hold"><div class="pie"></div></div>
</div>

Large & Multiple Slices

If you’d like to make a slice take up more than 50% of the pie chart you’ll just need to add another pie div of the same color with a hold div wrapped around it. To add a slice in a new color just change the background color. Below is an example of making a slice over 50% and a second slice of a new color.

<style>
     #pieSliceBlue .pie {
          background-color: #1b458b;
          -webkit-transform:rotate(180deg);
          -moz-transform:rotate(180deg);
          -o-transform:rotate(180deg);
          transform:rotate(180deg);
     }
     #pieSliceBlue2 {
          -webkit-transform:rotate(180deg);
          -moz-transform:rotate(180deg);
          -o-transform:rotate(180deg);
          transform:rotate(180deg);
     }
     #pieSliceBlue2 .pie {
          background-color: #1b458b;
          -webkit-transform:rotate(40deg);
          -moz-transform:rotate(40deg);
          -o-transform:rotate(40deg);
          transform:rotate(40deg);
     }
     #pieSliceRed {
          -webkit-transform:rotate(220deg);
          -moz-transform:rotate(220deg);
          -o-transform:rotate(220deg);
          transform:rotate(220deg);
     }
     #pieSliceRed .pie {
          background-color: #cc0000;
          -webkit-transform:rotate(140deg);
          -moz-transform:rotate(140deg);
          -o-transform:rotate(140deg);
          transform:rotate(140deg);
     }
</style>

<div class="pieContainer">
     <div class="pieBackground"></div>
     <div id="pieSliceBlue" class="hold"><div class="pie"></div></div>
     <div id="pieSliceBlue2" class="hold"><div class="pie"></div></div>
     <div id="pieSliceRed" class="hold"><div class="pie"></div></div>
</div>

IE Fallback

As expected, this doesn’t work in any Internet Explorer browsers below version 9. If you’re concerned about IE users, a simple way to fix this is adding a conditional comment for IE with a jpg of whatever charts you’re trying to display.

Tags: ,

« Older     Newer »

22 Responses to “How to Create CSS3 Pie Charts”

  1. Brent French says:

    Awesome web design please keep up the tutorials!

  2. Allison Shapanka says:

    This is great! Thanks so much. One issue I ran into: The project I’m working on is a single page with a scroll to each section, and a fixed header image. I noticed that when the header scrolls over the pie chart, the “slice” glides over the image, rather than stay underneath (like the body of the pie chart). Any idea why this is happening?

  3. Thanks Allison, I’m glad it was helpful. I think it’s going over the top of your fixed element because of absolute positioning on the pie chart and it coming later in the code than your fixed header. If you assign a z-index with CSS on the header image you should be able to fix it. Like so – #yourHeaderImageID {z-index: 1000;}

  4. This was one of the most beautiful implementations I’ve ever seen using CSS3. Great work buddy. However, to add any kind of behavior to this pie chart is not an easy task at all. I still prefer using SVG.

  5. Kyle Larson says:

    Thanks, I really appreciate it. It could be interesting to try and combine with CSS animation, but SVG definitely has an advantage here.

  6. Elxis4 says:

    There is a bug is the above concept. If any slice is larger than 180 degrees the pie is generated with uncovered areas. To solve this I split slices bigger than 180 degrees into smaller ones.

  7. [...] build it, I used this tutorial kylejlarson.com/blog/2011/how-to-create-pie-charts-with-css3/ to make a pie chart in CSS3 as this is technically a piechart with two values and a hole in the [...]

  8. Stanley says:

    In the “Large & Multiple Slices” example the right side of the pie chart is not rounded. I notice this happens when the rotation is set to 180 degree. Any idea how to fix that?

  9. Kyle Larson says:

    Maybe try splitting the 180 into multiple pieces like Elixis4 mentioned here? I can’t seem to recreate this issue, which browser version are you seeing it in?

  10. Stanley says:

    I’m using Google Chrome Version 23.0.1271.97 m
    This is what I see: http://screencast.com/t/tOFQa8z7DfUs
    I tried to view it in Firefox and it looks perfect.

    I found another example at http://atomicnoggin.ca/test/pie-chart.html which is also using the same technique but it doesn’t has the problem when viewing in Google Chrome. Strange.

  11. Kyle Larson says:

    Interesting… Looks like a rendering issue with the windows version of chrome. If you add margin-left: -1px; to #pieSliceBlue .pie that seems to fix it. Looks like for some reason it’s over the edge of the box and that is cutting it.

  12. Günther Leenaert says:

    For cross-browser isomorphic pages, I use Eric Meyer CSS reset, which also fixes issues like these.

  13. [...] ps: How to get the timer filled as the clock ticks down? Reference here. [...]

  14. frank says:

    using the :hover on the slices is dodgy to me, any solutions?

  15. [...] How to Create Pie Charts with CSS3 [...]

  16. oudin says:

    any idea on how to make it responsive?

  17. Kyle Larson says:

    You should be able to do it with media queries and just make sure to maintain the ratios here (ie 2:1). Here’s an example file: http://www.kylejlarson.com/files/pie_test.html Just shrink the browser to below 600px and you’ll see the size change.

  18. Kris Olszewski says:

    Great tutorial. I took it step further and turned it into a JS driven widget. Check it out: https://github.com/KrisOlszewski/donut-chart

  19. Kyle Larson says:

    Thanks and nice work Kris!

  20. […] to use CSS’s property for styling pie chart such as, 1 , […]

  21. Usman Hanif says:

    how can I increase the size of pie chart. its very small in size

Leave a Reply

More Posts