Last active
June 21, 2021 18:57
-
-
Save jerrylow/b609c70c45717d7aa08c0cc4e29f4558 to your computer and use it in GitHub Desktop.
Pure CSS Donut Chart Mixin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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