Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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>
like image 480
stwhite Avatar asked Jun 27 '19 18:06

stwhite


People also ask

How do you add a gap to a pie chart?

Pull the whole pie apartRight-click the pie chart, then click Format Data Series. Drag the Pie Explosion slider to increase the separation, or enter a number in the percentage box.

How do I make a pie chart with just CSS?

The CSS Setting for the Pie Chart I am defining the element as inline-grid to easily place the content at the middle using place-content: center . We use aspect-ratio: 1 to make sure the element remains square. We can also use height: var(--w) but it's always good to learn and use a new CSS property.


2 Answers

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

like image 149
Temani Afif Avatar answered Sep 23 '22 19:09

Temani Afif


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>
like image 22
Scott Weaver Avatar answered Sep 26 '22 19:09

Scott Weaver