CSS Only Donut Chart With Custom Slices


Author: Jerry Low
Views Total: 9,790 views
Official Page: Go to website
Last Update: May 6, 2020
License: MIT

Preview:

CSS Only Donut Chart With Custom Slices

Description:

A minimal clean donut chart to represent percentage values as slices using pure CSS/SCSS.

How to use it:

1. Create the HTML for the donut chart and define the percentage value for each slice using CSS variables as follows:

<div class="donut" style="--first: .40; --second: .33; --third: .12; --fourth: .08; --fifth: 0.07">
  <div class="donut__slice donut__slice__first"></div>
  <div class="donut__slice donut__slice__second"></div>
  <div class="donut__slice donut__slice__third"></div>
  <div class="donut__slice donut__slice__fourth"></div>
  <div class="donut__slice donut__slice__fifth"></div>
  <div class="donut__label">
    <div class="donut__label__heading">
      CSSScript.Com
    </div>
    <div class="donut__label__sub">
      Donut Chart
    </div>
  </div>
</div>

2. The main CSS styles for the donut chart. Feel free to override the CSS styles as shown below:

.donut {
  --donut-size: 300px;
  --donut-border-width: 20px;
  --donut-spacing: 0;
  --donut-spacing-color: 255, 255, 255;
  --donut-spacing-deg: calc(1deg * var(--donut-spacing));
  border-radius: 50%;
  height: var(--donut-size);
  margin: 40px;
  position: relative;
  width: var(--donut-size);
}
.donut__label {
  left: 50%;
  line-height: 1.5;
  position: absolute;
  text-align: center;
  top: 50%;
  -webkit-transform: translate(-50%, -50%);
          transform: translate(-50%, -50%);
  width: 80%;
}
.donut__label__heading {
  font-size: 24px;
  font-weight: 600;
}
.donut__label__sub {
  color: #666666;
  font-size: 14px;
  letter-spacing: 0.05em;
}
.donut__slice {
  height: 100%;
  position: absolute;
  width: 100%;
}
.donut__slice::before,
.donut__slice::after {
  border: var(--donut-border-width) solid rgba(0, 0, 0, 0);
  border-radius: 50%;
  content: '';
  height: 100%;
  left: 0;
  position: absolute;
  top: 0;
  -webkit-transform: rotate(45deg);
          transform: rotate(45deg);
  width: 100%;
}
.donut__slice::before {
  border-width: calc(var(--donut-border-width) + 1px);
  box-shadow: 0 0 1px 0 rgba(var(--donut-spacing-color), calc(100 * var(--donut-spacing)));
}
.donut__slice__first {
  --first-start: 0;
}
.donut__slice__first::before {
  border-top-color: rgba(var(--donut-spacing-color), calc(100 * var(--donut-spacing)));
  -webkit-transform: rotate(calc(360deg * var(--first-start) + 45deg));
          transform: rotate(calc(360deg * var(--first-start) + 45deg));
}
.donut__slice__first::after {
  border-top-color: #ff6838;
  border-right-color: rgba(255, 104, 56, calc(100 * (var(--first) - .25)));
  border-bottom-color: rgba(255, 104, 56, calc(100 * (var(--first) - .5)));
  border-left-color: rgba(255, 104, 56, calc(100 * (var(--first) - .75)));
  -webkit-transform: rotate(calc(360deg * var(--first-start) + 45deg + var(--donut-spacing-deg)));
          transform: rotate(calc(360deg * var(--first-start) + 45deg + var(--donut-spacing-deg)));
}
.donut__slice__second {
  --second-start: calc(var(--first));
  --second-check: max(calc(var(--second-start) - .5), 0);
  -webkit-clip-path: inset(0 calc(50% * (var(--second-check) / var(--second-check))) 0 0);
          clip-path: inset(0 calc(50% * (var(--second-check) / var(--second-check))) 0 0);
}
.donut__slice__second::before {
  border-top-color: rgba(var(--donut-spacing-color), calc(100 * var(--donut-spacing)));
  -webkit-transform: rotate(calc(360deg * var(--second-start) + 45deg));
          transform: rotate(calc(360deg * var(--second-start) + 45deg));
}
.donut__slice__second::after {
  border-top-color: #ffc820;
  border-right-color: rgba(255, 200, 32, calc(100 * (var(--second) - .25)));
  border-bottom-color: rgba(255, 200, 32, calc(100 * (var(--second) - .5)));
  border-left-color: rgba(255, 200, 32, calc(100 * (var(--second) - .75)));
  -webkit-transform: rotate(calc(360deg * var(--second-start) + 45deg + var(--donut-spacing-deg)));
          transform: rotate(calc(360deg * var(--second-start) + 45deg + var(--donut-spacing-deg)));
}
.donut__slice__third {
  --third-start: calc(var(--first) + var(--second));
  --third-check: max(calc(var(--third-start) - .5), 0);
  -webkit-clip-path: inset(0 calc(50% * (var(--third-check) / var(--third-check))) 0 0);
          clip-path: inset(0 calc(50% * (var(--third-check) / var(--third-check))) 0 0);
}
.donut__slice__third::before {
  border-top-color: rgba(var(--donut-spacing-color), calc(100 * var(--donut-spacing)));
  -webkit-transform: rotate(calc(360deg * var(--third-start) + 45deg));
          transform: rotate(calc(360deg * var(--third-start) + 45deg));
}
.donut__slice__third::after {
  border-top-color: #97c95c;
  border-right-color: rgba(151, 201, 92, calc(100 * (var(--third) - .25)));
  border-bottom-color: rgba(151, 201, 92, calc(100 * (var(--third) - .5)));
  border-left-color: rgba(151, 201, 92, calc(100 * (var(--third) - .75)));
  -webkit-transform: rotate(calc(360deg * var(--third-start) + 45deg + var(--donut-spacing-deg)));
          transform: rotate(calc(360deg * var(--third-start) + 45deg + var(--donut-spacing-deg)));
}
.donut__slice__fourth {
  --fourth-start: calc(var(--first) + var(--second) + var(--third));
  --fourth-check: max(calc(var(--fourth-start) - .5), 0);
  -webkit-clip-path: inset(0 calc(50% * (var(--fourth-check) / var(--fourth-check))) 0 0);
          clip-path: inset(0 calc(50% * (var(--fourth-check) / var(--fourth-check))) 0 0);
}
.donut__slice__fourth::before {
  border-top-color: rgba(var(--donut-spacing-color), calc(100 * var(--donut-spacing)));
  -webkit-transform: rotate(calc(360deg * var(--fourth-start) + 45deg));
          transform: rotate(calc(360deg * var(--fourth-start) + 45deg));
}
.donut__slice__fourth::after {
  border-top-color: #1cb2f6;
  border-right-color: rgba(28, 178, 246, calc(100 * (var(--fourth) - .25)));
  border-bottom-color: rgba(28, 178, 246, calc(100 * (var(--fourth) - .5)));
  border-left-color: rgba(28, 178, 246, calc(100 * (var(--fourth) - .75)));
  -webkit-transform: rotate(calc(360deg * var(--fourth-start) + 45deg + var(--donut-spacing-deg)));
          transform: rotate(calc(360deg * var(--fourth-start) + 45deg + var(--donut-spacing-deg)));
}
.donut__slice__fifth {
  --fifth-start: calc(var(--first) + var(--second) + var(--third) + var(--fourth));
  --fifth-check: max(calc(var(--fifth-start) - .5), 0);
  -webkit-clip-path: inset(0 calc(50% * (var(--fifth-check) / var(--fifth-check))) 0 0);
          clip-path: inset(0 calc(50% * (var(--fifth-check) / var(--fifth-check))) 0 0);
}
.donut__slice__fifth::before {
  border-top-color: rgba(var(--donut-spacing-color), calc(100 * var(--donut-spacing)));
  -webkit-transform: rotate(calc(360deg * var(--fifth-start) + 45deg));
          transform: rotate(calc(360deg * var(--fifth-start) + 45deg));
}
.donut__slice__fifth::after {
  border-top-color: #1685b8;
  border-right-color: rgba(22, 133, 184, calc(100 * (var(--fifth) - .25)));
  border-bottom-color: rgba(22, 133, 184, calc(100 * (var(--fifth) - .5)));
  border-left-color: rgba(22, 133, 184, calc(100 * (var(--fifth) - .75)));
  -webkit-transform: rotate(calc(360deg * var(--fifth-start) + 45deg + var(--donut-spacing-deg)));
          transform: rotate(calc(360deg * var(--fifth-start) + 45deg + var(--donut-spacing-deg)));
}
See also  Morphing Side Menu with Pure CSS / CSS3

Leave a Reply

Your email address will not be published. Required fields are marked *