Draw a Pie Chart in Pure CSS
To be short:
- create a circle
- use
clip-path
to cut out a sector
I’ve been working on my online resume for some days, and I need to draw a pie chart for my skill set.
There is a lot of JS library for charts, like Highcharts, Echart, but I want my online resume a single file, I use only HTML & CSS (I even use a base64 coded image for background -_-), so I need some pure CSS way to draw a pie chart (or donut chart).
I can use a image, but that’s not cool!
I googled a lot, I find a way using
tranform
and
clip
,
I find a demo:
css:
#container {
position: relative;
width: 100px;
height: 100px;
}
.cover {
position: absolute;
width: 100%;
height: 100%;
clip: rect(0 100px 100px 50px);
}
.pie {
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
clip: rect(0 50px 100px 0px);
}
#part1-wrapper {
transform: rotate(0deg);
}
#part1 {
background-color: rgb(255, 99, 99);
transform: rotate(60deg);
}
html
<div id="container">
<div id="part1-wrapper" class="cover">
<div id="part1" class="pie"></div>
</div>
</div>
The result is as follows, there are 2 pies in the charts
To be short, this way does 3 things:
- draw a circle (
border-radius
) in inner div, useclip
show half circle - use
clip
in outer div to show only half box - rotate inner half circle a angle, because outer box only have half visible window, so a sector comes out
That is cool, if you control the rotate angle, you can get a beautiful chart. If you want a donut, you can add a white circle on the center of the pie chart.
But this is not the end of the journey. I want to add some mouse hover animation to the chart, for example, one part get bigger when the mouse hover it.
But above method will not let us do that, because when the inner circle get bigger, it will be clipped by the outer box, only if we do not need the nested structure.
Yes we can, actually the clip
is deprecated
and there is another more powerful
clip-path
.
here is a very nice playground for clip-path
:
CSS clip-path maker
If you want to cut the top-right part of the circle, say 60 degree, we need to cut a piece as follow:
Let’s do some math, the right short edge is:
\[l_r = \frac{L}{2} - \frac{L}{2} * tan(30^\circ)\]where $L$ is the edge length if the square. so the clip-path
will be:
-webkit-clip-path: polygon(50% 0, 100% 0, 100% 21.1%, 50% 50%);
clip-path: polygon(50% 0, 100% 0, 100% 21.1%, 50% 50%);
And so on, and now you can add some lovely animations to the charts.
Let me see the example: