How to Easily Make Donut Charts With CSS Only

CSS borders have been long known as a special property that can be used creatively to create various UI elements β€” apart from borders β€” such as strokes, chevrons, or arrows.

In this tutorial, we’re going to take a look at how you can also use it to create a donut chart with only borders, that at the end of the tutorial, will look like the following:

Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
JavaScript Course

Creating A Donut With CSS Borders

To start things off, first, let’s create a donut with only one color. To do this, I’ve set up the following rules that create a 50x50px black rectangle with a red border, at the middle of the screen.

.donut {
    background: #000;
    display: block;
    width: 50px;
    height: 50px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    border: 10px solid red;
}
donut.css
Copied to clipboard!

As you can see, this doesn’t really look like a donut, however. To fix this, and create a stroke, add a 100% border-radius with a transparent background:

.donut {
    ...
    border-radius: 100%;
}
donut.cssMake sure to remove the background property to make the fill transparent
Copied to clipboard!

Adding Segments to the Donut

To add different segments, you can change the color of each side of the border with separate rules:

.donut {
    ...
    border: 10px solid #FF6188;
    border-top: 10px solid #A9DC62;
    border-left: 10px solid #78DCDC;
    border-right: 10px solid #FFD862;
}
donut.css
Copied to clipboard!

Playing With Segments and Rotation

To make this less symmetric, you can also add a little bit of rotation. By adding a little bit of animation, you can also turn it into a circle loading indicator:

@keyframes loading {
    0%   { transform: translate(-50%, -50%) rotate(25deg);  }
    100% { transform: translate(-50%, -50%) rotate(385deg); }
}

.donut {
    transform: translate(-50%, -50%) rotate(25deg);
    /* Add animation if you want to turn it into a loading indicator */
    animation: loading 1s ease-in-out infinite;
}
donut.cssNote that by default, the element has a transform applied
Copied to clipboard!

You can also create bigger segments, by simply making neighboring borders the same color:

.donut-01 {
    /* default values */
}

.donut-02 {
    border-left: 10px solid #78DCDC;
    border-bottom: 10px solid #78DCDC;
}

.donut-03 {
    border-left: 10px solid #FF6188;
    border-right: 10px solid #FF6188;
}
donut.css
Copied to clipboard!

Playing With Different Border Styles

You can also play around with the border-style property, to create different styles of donuts. Some examples are:

.donut-01 { border-style: dotted; }
.donut-02 { border-style: double; }
.donut-03 { border-style: groove; }
.donut-04 { border-style: ridge; }
donut.css
Copied to clipboard!

Putting Everything Together

To finish things up, you can also add additional borders to it, with a box-shadow. You can add as many box-shadow as you’d like, you only need to separate the different values with a comma.

.donut {
    box-shadow: inset 0 0 10px 0px #21212191, 0 0 0 2px #212121;
}
donut.css
Copied to clipboard!

Putting everything together, this is the final set of rules that makes up the element:

.donut {
    display: block;
    border-radius: 100%;
    width: 50px;
    height: 50px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) rotate(25deg);
    border: 10px solid #FF6188;
    border-top: 10px solid #A9DC62;
    border-left: 10px solid #78DCDC;
    border-right: 10px solid #FFD862;
    box-shadow: inset 0 0 10px 0px #21212191, 0 0 0 2px #212121;
}
donut.css
Copied to clipboard!

Creating Any Type of Donut Chart in CSS

However, this solution is somewhat limiting. We cannot specify how big segments should be, and we can only work with a maximum number of 4 segments. In order to make things a bit more flexible, we can create any type of donut chart in CSS using a conic-gradient background:

Using a conic-gradientΒ we can create as many segments as we want, in any direction that we want. The above example uses the following conic-gradient as a background color for the circle:

.donut {
    display: block;
    border-radius: 100%;
    width: 75px;
    height: 75px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: conic-gradient(
        #A9DC62 0deg 90deg,
        #FFD862 90deg 180deg,
        #FF6188 180deg 360deg
    );
}
donut.css
Copied to clipboard!

We can define a comma-separated list as the segments. The first segment spans from 0 to 90 degrees, the second goes from 90 to 180, while the rest (half of the circle) goes fromΒ 180-360 degrees. Notice that if we don't start the next segment from the end of the previous one, we will get a blurred gradient:

.donut {
    background: conic-gradient(
        #A9DC62 0deg 60deg,
        #FFD862 90deg 180deg,
        #FF6188 200deg 360deg
    );
}
donut.css
Copied to clipboard!

However, this is not quite a donut yet, we're missing a hole in the middle. In order to create a hole in the center, we can add an ::after element, with the same color as the background, right in the middle of the pie chart:

.donut::after {
    content: '';
    display: block;
    position: absolute;
    width: 30px;
    height: 30px;
    background: #221f22;
    border-radius: 50%;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
donut.cssThe bigger the width and height, the bigger the radius will be
Copied to clipboard!

Summary

In summary, CSS borders can be used in various creative ways. As you’ve seen, even if you’ve already used up the border property for a given element, you can still add additional borders on top of that with the use of box-shadow. To make donut charts more customizable, it can also be replaced by SVG paths or conic gradients.

Have you already worked with CSS borders in a creative way? Let us know in the comments below! Thank you for reading through, happy styling! 🎨

JavaScript Course Dashboard

Tired of looking for tutorials?

You are not alone. Webtips has more than 400 tutorials which would take roughly 75 hours to read.

Check out our interactive course to master JavaScript in 5 hours.

Learn More

πŸ“š Get access to exclusive content

Want to get access to exclusive content? Support webtips with the price of a coffee to get access to tips, checklists, cheatsheets, and much more. β˜•

Get access Support us
Read more on
πŸŽ‰ Thank you for subscribing to our newsletter. x