CSS Only Pie Chart - How to add spacing/padding between slices?
Asked Answered
D

2

13

I've built a CSS only pie chart, but I need to add space between each slice almost as if it were a border. I've attempted to add a border to each slice but that doesn't actually work.

Any ideas on how to make this CSS pie chart look more like the following image?

CSS pie chart

Here is my code:

.palette {
  height: 48px;
  width: 48px;
}
.palette .colorOuter1,
.palette .colorOuter2,
.palette .colorOuter3,
.palette .colorOuter4,
.palette .colorOuter5 {
  height: 200px;
  width: 200px;
  border-radius: 50%;
  position: absolute;
  top: 0;
  left: 0;
  clip: rect(0px, 200px, 200px, 100px);
}
.palette .colorOuter1 {
  clip: auto;
  background: #eee;
}
.palette .colorOuter2 {
  transform: rotate(0deg);
}
.palette .colorOuter2 {
  transform: rotate(72deg);
}
.palette .colorOuter3 {
  transform: rotate(144deg);
}
.palette .colorOuter4 {
  transform: rotate(216deg);
}
.palette .colorOuter5 {
  transform: rotate(288deg);
}
.palette .colorInner1,
.palette .colorInner2,
.palette .colorInner3,
.palette .colorInner4,
.palette .colorInner5 {
  position: absolute;
  top: 0;
  left: 0;
  width: 200px;
  height: 200px;
  border-radius: 50%;
  transform: rotate(72deg);
}
.palette .colorInner1 {
  background: #5D5E63;
  clip: rect(0px, 100px, 200px, 0px);
}
.palette .colorInner2 {
  background-color: #AEADA9;
  clip: rect(0px, 100px, 100px, 0px);
}
.palette .colorInner3 {
  background-color: #D5C4A8;
  clip: rect(0px, 100px, 100px, 0px);
}
.palette .colorInner4 {
  background-color: #AA875F;
  clip: rect(0px, 100px, 100px, 0px);
}
.palette .colorInner5 {
  background-color: #B7CBC7;
  clip: rect(0px, 100px, 100px, 0px);
}
.palette .centerOverlay {
  position: absolute;
  border-radius: 50%;
  top: 60px;
  left: 60px;
  background: #fff;
  width: 80px;
  height: 80px;
  display: block;
  clip: auto;
}
<div class="palette">
  <div class="colorOuter1">
    <div class="colorInner1"></div>
  </div>
  <div class="colorOuter2">
    <div class="colorInner2"></div>
  </div>
  <div class="colorOuter3">
    <div class="colorInner3"></div>
  </div>
  <div class="colorOuter4">
    <div class="colorInner4"></div>
  </div>
  <div class="colorOuter5">
    <div class="colorInner5"></div>
  </div>
  <div class="centerOverlay"></div>
</div>
Drabeck answered 27/6, 2019 at 18:44 Comment(0)
T
26

First I would recreate this with less of code relying on clip-path like below:

.palette {
  height: 200px;
  width: 200px;
  position:relative;
  overflow:hidden;
}
.palette > * {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  border:50px solid var(--c,red);
  border-radius:50%;
  clip-path:polygon(50% 50%, 50% 0%, 100% 0%,100% 33.745%); 
}
.color1 {
  transform:rotate(72deg);
  --c:blue;
}
.color2 {
  transform:rotate(144deg);
  --c:orange;
}
.color3 {
  transform:rotate(-72deg);
  --c:green;
}
.color4 {
  transform:rotate(-144deg);
  --c:purple;
}
<div class="palette">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
</div>

Then you can apply a translation to your elements to create the gaps:

.palette {
  height: 200px;
  width: 200px;
  position:relative;
  margin:20px;
}
.palette > * {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  border:50px solid var(--c,red);
  border-radius:50%;
  clip-path:polygon(50% 50%, 50% 0%, 100% 0%,100% 33.745%); 
}
.color1 {
  transform:rotate(72deg) translate(5px,-5px);
  --c:blue;
}
.color2 {
  transform:rotate(144deg) translate(5px,-5px);
  --c:orange;
}
.color3 {
  transform:rotate(-72deg) translate(5px,-5px);
  --c:green;
}
.color4 {
  transform:rotate(-144deg) translate(5px,-5px);
  --c:purple;
}
.color5 {
  transform:rotate(0) translate(5px,-5px);
  --c:red;
}
<div class="palette">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
</div>

Or if you want to create an effect of missing parts in order to keep the circular shape (like shown in your screenshot) you have to adjust the clip-path

.palette {
  height: 200px;
  width: 200px;
  position:relative;
  overflow:hidden;
}
.palette > * {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  border:50px solid var(--c,red);
  border-radius:50%;
  clip-path:polygon(
    calc(50% + 5px) 50%, 
    calc(50% + 5px) 0%, 
    100% 0%,
    100% calc(33.745% - 5px),
    50% calc(50% - 5px)); 
}
.color1 {
  transform:rotate(72deg);
  --c:blue;
}
.color2 {
  transform:rotate(144deg);
  --c:orange;
}
.color3 {
  transform:rotate(-72deg);
  --c:green;
}
.color4 {
  transform:rotate(-144deg);
  --c:purple;
}
<div class="palette">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
</div>

And with CSS variables we can easily handle everything

.palette {
  --g:10px; /* The gap between shapes*/
  --s:50px; /* the size*/

  height: 200px;
  width: 200px;
  position:relative;
  display:inline-block;
  overflow:hidden;
}
.palette > * {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  border:var(--s) solid var(--c,red);
  border-radius:50%;
  clip-path:polygon(
    calc(50% + var(--g)/2) 50%, 
    calc(50% + var(--g)/2) 0%, 
    100% 0%,
    100% calc(33.745% - var(--g)/2),
    50% calc(50% - var(--g)/2)); 
}
.color1 {
  transform:rotate(72deg);
  --c:blue;
}
.color2 {
  transform:rotate(144deg);
  --c:orange;
}
.color3 {
  transform:rotate(-72deg);
  --c:green;
}
.color4 {
  transform:rotate(-144deg);
  --c:purple;
}
<div class="palette">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
</div>

<div class="palette" style="--s:40px;--g:20px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
</div>

<div class="palette" style="--s:60px;--g:0px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
</div>

CSS pie chart

Using the same code you can easily scale to any number of slices:

With 8 slices:

.palette {
  --g:10px; /* The gap between shapes*/
  --s:50px; /* the size*/

  height: 200px;
  width: 200px;
  position:relative;
  display:inline-block;
  overflow:hidden;
}
.palette > * {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  border:var(--s) solid var(--c,red);
  border-radius:50%;
  clip-path:polygon(
    calc(50% + var(--g)/2) 50%, 
    calc(50% + var(--g)/2) 0%, 
    100% 0%,
    100% calc(0% - var(--g)/2),
    50% calc(50% - var(--g)/2)); 
}
.color1 {
  transform:rotate(45deg); /* 360/8 */
  --c:blue;
}
.color2 {
  transform:rotate(90deg);
  --c:orange;
}
.color3 {
  transform:rotate(135deg);
  --c:green;
}
.color4 {
  transform:rotate(180deg);
  --c:purple;
}
.color5 {
  transform:rotate(-45deg); /* 360/8 */
  --c:orange;
}
.color6 {
  transform:rotate(-90deg);
  --c:lightblue;
}
.color7 {
  transform:rotate(-135deg);
  --c:pink;
}
<div class="palette">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
</div>

<div class="palette" style="--s:40px;--g:20px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
</div>

<div class="palette" style="--s:60px;--g:0px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
</div>

CSS pie chart - 8 slices

With 3 slices:

.palette {
  --g:10px; /* The gap between shapes*/
  --s:50px; /* the size*/

  height: 200px;
  width: 200px;
  position:relative;
  display:inline-block;
  overflow:hidden;
}
.palette > * {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  border:var(--s) solid var(--c,red);
  border-radius:50%;
  clip-path:polygon(
    calc(50% + var(--g)/2) 50%, 
    calc(50% + var(--g)/2) 0%, 
    100% 0%,
    100% calc(78.665% - var(--g)/2),
    50% calc(50% - var(--g)/2)); 
}
.color1 {
  transform:rotate(120deg);
  --c:blue;
}
.color2 {
  transform:rotate(-120deg);
  --c:orange;
}
<div class="palette">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
</div>

<div class="palette" style="--s:40px;--g:20px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
</div>

<div class="palette" style="--s:60px;--g:0px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
</div>

CSS pie chart - 3 slices


Here is the formula behind the magic number used in the clip-path:

  • 5 slices: 33.75% = 50% - tan(90deg - 72deg)*50%
  • 8 slices: 0% = 50% - tan(90deg - 45deg)*50%
  • 3 slices: 78.665% = 50% - tan(90deg - 120deg)*50%

So the generic formula for N slices is 50%*(1 - tan(90deg - 360deg/N)) with N in [3 8]. If N < 3 we have trivial cases where we don't need a complex code. For N > 8 we need a different clip-path and a different formula: 50%*(1 + tan(360deg/N))

Example with 10 slices:

.palette {
  --g:10px; /* The gap between shapes*/
  --s:50px; /* the size*/

  height: 200px;
  width: 200px;
  position:relative;
  display:inline-block;
  overflow:hidden;
}
.palette > * {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  border:var(--s) solid var(--c,red);
  border-radius:50%;
  clip-path:polygon(
    calc(50% + var(--g)/2) 50%, 
    calc(50% + var(--g)/2) 0%, 
    calc(86.327% - var(--g)/2) 0%,
    50% calc(50% - var(--g)/2)); 
}
.color1 {
  transform:rotate(36deg);
  --c:blue;
}
.color2 {
  transform:rotate(72deg);
  --c:orange;
}
.color3 {
  transform:rotate(108deg);
  --c:green;
}
.color4 {
  transform:rotate(144deg);
  --c:purple;
}
.color5 {
  transform:rotate(180deg);
  --c:lightblue;
}
.color6 {
  transform:rotate(-36deg);
  --c:silver;
}
.color7 {
  transform:rotate(-72deg);
  --c:black;
}
.color8 {
  transform:rotate(-108deg);
  --c:darkgreen;
}
.color9 {
  transform:rotate(-144deg);
  --c:pink;
}
<div class="palette">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
  <div class="color9"></div>
  <div class="color10"></div>
</div>

<div class="palette" style="--s:40px;--g:20px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
  <div class="color9"></div>
  <div class="color10"></div>
</div>

<div class="palette" style="--s:60px;--g:0px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
  <div class="color9"></div>
  <div class="color10"></div>
</div>

CSS pie chart - 10 slices


An idea in case you want to achieve a gradient coloration. This rely on conic-gradient so will not work on Firefox for now:

.palette {
  --g:10px; /* The gap between shapes*/
  --s:50px; /* the size*/

  height: 200px;
  width: 200px;
  position:relative;
  display:inline-block;
  overflow:hidden;
}
.palette > * {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  border:var(--s) solid transparent;
  background:
     linear-gradient(#fff,#fff) padding-box,
     conic-gradient(from calc(-1*var(--d,0deg)), red,blue,green) border-box;
  border-radius:50%;
  clip-path:polygon(
    calc(50% + var(--g)/2) 50%, 
    calc(50% + var(--g)/2) 0%, 
    calc(86.327% - var(--g)/2) 0%,
    50% calc(50% - var(--g)/2)); 
  transform:rotate(var(--d,0deg));
}
.color1 {
  --d:36deg;
}
.color2 {
  --d:72deg;
}
.color3 {
  --d:108deg;
}
.color4 {
  --d:144deg;
}
.color5 {
  --d:180deg;
}
.color6 {
  --d:-36deg;
}
.color7 {
  --d:-72deg;
}
.color8 {
  --d:-108deg;
}
.color9 {
  --d:-144deg;
}
<div class="palette">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
  <div class="color9"></div>
  <div class="color10"></div>
</div>

<div class="palette" style="--s:40px;--g:20px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
  <div class="color9"></div>
  <div class="color10"></div>
</div>

<div class="palette" style="--s:60px;--g:0px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
  <div class="color9"></div>
  <div class="color10"></div>
</div>

Conic gradient CSS pie chart

You can simulate another gradient coloration with linear-gradient and you will have better support:

.palette {
  --g:10px; /* The gap between shapes*/
  --s:50px; /* the size*/

  height: 200px;
  width: 200px;
  position:relative;
  display:inline-block;
  overflow:hidden;
}
.palette > * {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  padding:var(--s);
  background:
     linear-gradient(#fff,#fff)      content-box,
     linear-gradient(red,blue,green) padding-box;
  border-radius:50%;
  clip-path:polygon(
    calc(50% + var(--g)/2) 50%, 
    calc(50% + var(--g)/2) 0%, 
    100% 0%,
    100% calc(0% - var(--g)/2),
    50% calc(50% - var(--g)/2)); 
  transform:rotate(var(--d,0deg));
}
.palette > *:before {
  content:"";
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  padding:inherit;
  background:inherit;
  transform:rotate(calc(-1*var(--d,0deg)));
  border-radius:50%;
}
.color1 {
  --d:45deg;
}
.color2 {
  --d:90deg;
}
.color3 {
  --d:135deg;
}
.color4 {
  --d:180deg;
}
.color5 {
  --d:-45deg;
}
.color6 {
  --d:-90deg;
}
.color7 {
  --d:-135deg;
}
<div class="palette">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
</div>

<div class="palette" style="--s:40px;--g:20px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
</div>

<div class="palette" style="--s:60px;--g:0px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
</div>

CSS pie chart with linear gradient

We can add mask for full transparency:

.palette {
  --g:10px; /* The gap between shapes*/
  --s:50px; /* the size*/

  height: 200px;
  width: 200px;
  position:relative;
  display:inline-block;
  overflow:hidden;
}
.palette > * {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  background:linear-gradient(red,blue,green) padding-box;
  -webkit-mask:radial-gradient(farthest-side,transparent calc(99% - var(--s)),#fff calc(100% - var(--s))); 
  mask:radial-gradient(farthest-side,transparent calc(99% - var(--s)),#fff calc(100% - var(--s))); 
  border-radius:50%;
  clip-path:polygon(
    calc(50% + var(--g)/2) 50%, 
    calc(50% + var(--g)/2) 0%, 
    100% 0%,
    100% calc(0% - var(--g)/2),
    50% calc(50% - var(--g)/2)); 
  transform:rotate(var(--d,0deg));
}
.palette > *:before {
  content:"";
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  background:inherit;
  transform:rotate(calc(-1*var(--d,0deg)));
  border-radius:50%;
}
.color1 {
  --d:45deg;
}
.color2 {
  --d:90deg;
}
.color3 {
  --d:135deg;
}
.color4 {
  --d:180deg;
}
.color5 {
  --d:-45deg;
}
.color6 {
  --d:-90deg;
}
.color7 {
  --d:-135deg;
}

body {
  background:linear-gradient(to left,grey,#fff);
}
<div class="palette">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
</div>

<div class="palette" style="--s:40px;--g:20px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
</div>

<div class="palette" style="--s:60px;--g:0px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
</div>

Same thing with the conic-gradient:

.palette {
  --g:10px; /* The gap between shapes*/
  --s:50px; /* the size*/

  height: 200px;
  width: 200px;
  position:relative;
  display:inline-block;
  overflow:hidden;
}
.palette > * {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  background: conic-gradient(from calc(-1*var(--d,0deg)), red,blue,green);
  -webkit-mask:radial-gradient(farthest-side,transparent calc(99% - var(--s)),#fff calc(100% - var(--s))); 
  mask:radial-gradient(farthest-side,transparent calc(99% - var(--s)),#fff calc(100% - var(--s))); 
  
  border-radius:50%;
  clip-path:polygon(
    calc(50% + var(--g)/2) 50%, 
    calc(50% + var(--g)/2) 0%, 
    calc(86.327% - var(--g)/2) 0%,
    50% calc(50% - var(--g)/2)); 
  transform:rotate(var(--d,0deg));
}
.color1 {
  --d:36deg;
}
.color2 {
  --d:72deg;
}
.color3 {
  --d:108deg;
}
.color4 {
  --d:144deg;
}
.color5 {
  --d:180deg;
}
.color6 {
  --d:-36deg;
}
.color7 {
  --d:-72deg;
}
.color8 {
  --d:-108deg;
}
.color9 {
  --d:-144deg;
}

body {
  background:linear-gradient(to left,grey,white);
}
<div class="palette">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
  <div class="color9"></div>
  <div class="color10"></div>
</div>

<div class="palette" style="--s:40px;--g:20px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
  <div class="color9"></div>
  <div class="color10"></div>
</div>

<div class="palette" style="--s:60px;--g:0px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
  <div class="color9"></div>
  <div class="color10"></div>
</div>

For IE Support

Here is another idea with more support that should work for old browsers:

#colorWheel {
  width: 300px;
  height: 300px;
  position: relative;
  border-radius: 100%;
  overflow: hidden;
}

#colorWheel:after {
  content: "";
  position: absolute;
  border-radius: inherit;
  /* adjust the value to control the thickness*/
  top: 30px;
  left: 30px;
  right: 30px;
  bottom: 30px;
  /**/
  background: #fff;
}

#colorWheel span {
  position: absolute;
  border-style: solid;
  border-width: 150px 36px; /*adjust the 36px to control the distance*/
  left: 50%;
  top: 50%;
  color: transparent;
}

span:nth-child(1) {
  border-top-color: #bf6040;
  transform: translate(-50%, -50%) rotate(36deg);
}

span:nth-child(2) {
  border-top-color: #bf8040;
  transform: translate(-50%, -50%) rotate(72deg);
}

span:nth-child(3) {
  border-top-color: #bf9f40;
  transform: translate(-50%, -50%) rotate(108deg);
}

span:nth-child(4) {
  border-top-color: #bfbf40;
  transform: translate(-50%, -50%) rotate(144deg);
}

span:nth-child(5) {
  border-top-color: #9fbf40;
  transform: translate(-50%, -50%) rotate(180deg);
}

span:nth-child(6) {
  border-top-color: #80bf40;
  transform: translate(-50%, -50%) rotate(216deg);
}

span:nth-child(7) {
  border-top-color: #60bf40;
  transform: translate(-50%, -50%) rotate(252deg);
}

span:nth-child(8) {
  border-top-color: #40bf40;
  transform: translate(-50%, -50%) rotate(288deg);
}

span:nth-child(9) {
  border-top-color: #40bf60;
  transform: translate(-50%, -50%) rotate(324deg);
}

span:nth-child(10) {
  border-top-color: #40bf80;
  transform: translate(-50%, -50%) rotate(360deg);
}
<div id="colorWheel">
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
  </div>

Here is a SASS code to easily generate the shape:

$num:10;

@for $i from 1 through $num {
  span:nth-child(#{$i}) {
    border-top-color: hsl($i * 15, 50%, 50%);
    transform: translate(-50%,-50%) rotate($i * (360deg/$num));
  }
}

#colorWheel {
  width: 300px;
  height: 300px;
  position: relative;
  border-radius: 100%;
  overflow: hidden;
}
#colorWheel:after {
  content:"";
  position:absolute;
  border-radius:50%;
  /* adjust the value to control the thickness*/
  top:30px;
  left:30px;
  right:30px;
  bottom:30px;
  /**/
  background:#fff;
}


#colorWheel span {
  position: absolute;
  border-style: solid;
  border-width: 150px 36px; /*adjust the 36px to control the distance*/
  left: 50%;
  top: 50%;
  color:transparent;
}

Related: Sass/CSS color wheel

Tanishatanitansy answered 28/6, 2019 at 0:5 Comment(8)
Awesome answer! The only potential issue I could see here is that clip-path doesn't appear to be supported for IE 11... caniuse.com/#feat=css-clip-pathDrabeck
@Drabeck yes IE has no luck with me :) I will probably find another trick ;)Tanishatanitansy
Have you by chance found another method that gets around the IE issue?Drabeck
@Drabeck I tried few but it becomes really hard to maintain. I guess your best way is to consider SVG if you want to handle IE11, a pure CSS will be a pain.Tanishatanitansy
@Drabeck if you are still intrested, I found a way supported in IE ;) check the last codeTanishatanitansy
@TemaniAfif Do you know if theres a way to dynamically generate the "magic" number in the clip path based on a dynamic number of segments?Puppetry
I need a example for 2 clip. Who can help.Stoa
@TemaniAfif here is my ask #75419403Stoa
F
2

The way you are achieving the pie chart with CSS rotation and clipping makes it impossible to really know where the "border" actually is, and I don't think you can use border or clip-path to help much here (maybe clip-path and polygons, too difficult for me!)

You could place some more divs inside your .centerOverlay to act as more clipping masks, and then position them so that their midpoint is at exact center, rotate, and translate (not exactly fun, but). I've done two of them here as examples:

.palette {
  height: 48px;
  width: 48px;
  position:relative;
}
.palette .colorOuter1,
.palette .colorOuter2,
.palette .colorOuter3,
.palette .colorOuter4,
.palette .colorOuter5 {
  height: 200px;
  width: 200px;
  border-radius: 50%;
  position: absolute;
  top: 0;
  left: 0;
  clip: rect(0px, 200px, 200px, 100px);
}
.palette .colorOuter1 {
  clip: auto;
  background: #eee;
}
.palette .colorOuter2 {
  transform: rotate(0deg);
}
.palette .colorOuter2 {
  transform: rotate(72deg);
}
.palette .colorOuter3 {
  transform: rotate(144deg);
}
.palette .colorOuter4 {
  transform: rotate(216deg);
}
.palette .colorOuter5 {
  transform: rotate(288deg);
}
.palette .colorInner1,
.palette .colorInner2,
.palette .colorInner3,
.palette .colorInner4,
.palette .colorInner5 {
  position: absolute;
  top: 0;
  left: 0;
  width: 200px;
  height: 200px;
  border-radius: 50%;
  transform: rotate(72deg);
}
.palette .colorInner1 {
  background: #5D5E63;
  clip: rect(0px, 100px, 200px, 0px);
}
.palette .colorInner2 {
  background-color: #AEADA9;
  clip: rect(0px, 100px, 100px, 0px);
}
.palette .colorInner3 {
  background-color: #D5C4A8;
  clip: rect(0px, 100px, 100px, 0px);
}
.palette .colorInner4 {
  background-color: #AA875F;
  clip: rect(0px, 100px, 100px, 0px);
}
.palette .colorInner5 {
  background-color: #B7CBC7;
  clip: rect(0px, 100px, 100px, 0px);
}
.palette .centerOverlay {
  position: absolute;
  border-radius: 50%;
  top: 60px;
  left: 60px;
  background: #fff;
  width: 80px;
  height: 80px;
  display: block;
  clip: auto;
}
.palette .north {
  position:absolute;
  top: -60px;
  left: 50%;
  background-color:white;
  width:4px;
  height:100px;

}
.palette .northeast {
  position:absolute;
  top: -10px;
  left: 50%;
  background-color:white;
  width:4px;
  height:100px;
  transform: rotate(72deg) translate(0px, -50px)

}
<div class="palette">
  <div class="colorOuter1">
    <div class="colorInner1"></div>
  </div>
  <div class="colorOuter2">
    <div class="colorInner2"></div>
  </div>
  <div class="colorOuter3">
    <div class="colorInner3"></div>
  </div>
  <div class="colorOuter4">
    <div class="colorInner4"></div>
  </div>
  <div class="colorOuter5">
    <div class="colorInner5"></div>
  </div>
  <div class="centerOverlay">
     <div class="north"></div>
     <div class="northeast"></div>
  </div>
  
</div>
Falmouth answered 27/6, 2019 at 20:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.