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>
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>
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>
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>
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>
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>
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