Skip to content

Instantly share code, notes, and snippets.

@jerrylow
Last active June 21, 2021 18:57
Show Gist options
  • Save jerrylow/b609c70c45717d7aa08c0cc4e29f4558 to your computer and use it in GitHub Desktop.
Save jerrylow/b609c70c45717d7aa08c0cc4e29f4558 to your computer and use it in GitHub Desktop.
Pure CSS Donut Chart Mixin
// Pure CSS Donut Chart
// By: Jerry Low
// How to use sample: https://codepen.io/jerrylow/pen/KKdNXbJ
.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.25;
position: absolute;
text-align: center;
top: 50%;
transform: translate(-50%, -50%);
width: 60%;
}
.donut__label__heading {
font-size: 1.4em;
font-weight: 600;
line-height: 1;
}
.donut__label__sub {
color: #666666;
font-size: .8em;
letter-spacing: 0.05em;
margin-top: 5px;
}
.donut__slice {
height: 100%;
position: absolute;
width: 100%;
&::before,
&::after {
border: var(--donut-border-width) solid rgba(0,0,0,0);
border-radius: 50%;
box-sizing: border-box;
content: '';
height: 100%;
left:0;
position: absolute;
top: 0;
transform: rotate(45deg);
width: 100%;
}
&::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)))'};
}
// If you're using spacing add a div with classes
// .donut__slice and .donut__slice__space_filler in the end.
&__space_filler {
clip-path: inset(0 50% 0 0);
&::before {
border-top-color: #{'rgba(var(--donut-spacing-color), calc(100 * var(--donut-spacing)))'};
transform: rotate(calc(45deg - var(--donut-spacing-deg)));
}
&::after {
border: none;
}
}
}
$default-slices: (
first: #FF6838,
second: #FFC820,
third: #97C95C,
fourth: #1CB2F6,
fifth: #1685B8
);
@mixin create-donut($donut-slices: $default-slices) {
$slides-concat: '';
@each $slice in $donut-slices {
$name: nth($slice, 1);
$color: nth($slice, 2);
$i: index($donut-slices, $slice);
@if $i > 1 {
.donut__slice__#{$name} {
--#{$name}-start: calc(#{$slides-concat});
--#{$name}-check: max(calc(var(--#{$name}-start) - .5), 0);
clip-path: inset(0 calc(50% * (var(--#{$name}-check) / var(--#{$name}-check))) 0 0);
}
}
@else {
.donut__slice__#{$name} {
--#{$name}-start: 0;
}
}
.donut__slice__#{$name}::before {
border-top-color: #{'rgba(var(--donut-spacing-color), calc(100 * var(--donut-spacing)))'};
transform: rotate(calc(360deg * var(--#{$name}-start) + 45deg));
}
.donut__slice__#{$name}::after {
border-top-color: rgba($color, 1);
border-right-color: rgba($color, calc(100 * (var(--#{$name}) - .25)));
border-bottom-color: rgba($color, calc(100 * (var(--#{$name}) - .5)));
border-left-color: rgba($color, calc(100 * (var(--#{$name}) - .75)));
transform: rotate(calc(360deg * var(--#{$name}-start) + 45deg + var(--donut-spacing-deg)));
}
@if $i == 1 {
$slides-concat: var(--#{$name});
}
@else {
$slides-concat: $slides-concat + ' + ' + var(--#{$name});
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment