Reputation:
I consider myself pretty good with CSS, but I just started working on something I realized I have no clue how to approach: A color wheel. Like this:
Can this even be done in CSS? If so, how? I would rather not have to make it in canvas if not necessary. The same goes for SVG, but I'd prefer that to canvas.
Edit: If it could be "clean" (like the sections are the correct individual shapes rather than larger shapes laid on top of each other) so I could animate the individual sections later, like pop them out on hover, that would be nice. I understand if it can't be done like that though.
Upvotes: 7
Views: 9743
Reputation: 29645
You could achieve this just in CSS by using conical gradients and specifying stopping points for each of the colors, so they are clearly delimited.
In your particular case, you have 12 colors, which means that each stop point will be at 100% / 12 = 8.333%. Color 1 from 0 to 8.333%, color 2 from 8.333% to 16.666%, color 3 from 16.666% to 25%, etc. The syntax would be like this (with fake colors):
background: conic-gradient(red 0% 8.333%, blue 8.333% 16.666%, ..... );
Conical gradients are just fairly-supported at the moment of writing this answer: Chrome, Chromium-based browsers, and Safari support it; Firefox only by activating a flag (hopefully it will soon be complete support); And support for it on Edge (pre-Chromium), IE, or mobile is spotty.
Here is one way of creating a color wheel in CSS with conical gradients and variables:
.color-wheel {
--num-colors: 12;
--color-size: calc(100% / var(--num-colors));
width: 300px;
height: 300px;
position: relative;
border-radius: 50%;
background: conic-gradient(
#f22 calc(0 * var(--color-size)) calc(1 * var(--color-size)),
#f06 calc(1 * var(--color-size)) calc(2 * var(--color-size)),
#63b calc(2 * var(--color-size)) calc(3 * var(--color-size)),
#44b calc(3 * var(--color-size)) calc(4 * var(--color-size)),
#09f calc(4 * var(--color-size)) calc(5 * var(--color-size)),
#0af calc(5 * var(--color-size)) calc(6 * var(--color-size)),
#0bd calc(6 * var(--color-size)) calc(7 * var(--color-size)),
#098 calc(7 * var(--color-size)) calc(8 * var(--color-size)),
#0a4 calc(8 * var(--color-size)) calc(9 * var(--color-size)),
#7c3 calc(9 * var(--color-size)) calc(10 * var(--color-size)),
#fe0 calc(10 * var(--color-size)) calc(11 * var(--color-size)),
#fb0 calc(11 * var(--color-size)) calc(12 * var(--color-size))
);
transform: rotate(calc(-180deg / var(--num-colors)));
}
.color-wheel::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
border-radius: 50%;
background: white;
width: 50%;
height: 50%;
transform: translate(-50%, -50%);
}
<div class="color-wheel"></div>
The code above would be simpler to write with a preprocessor like Sass or Less (using a loop, and avoiding the bulky calculations with CSS variables).
Upvotes: 6
Reputation: 3537
This is not my work, but I ran across this four-color wheel which would be an excellent starting point for an all-css version:
http://jsfiddle.net/elias94xx/3rx7w/2/
.chart {
position: absolute;
width:0;
height:0;
border-radius: 60px;
-moz-border-radius: 60px;
-webkit-border-radius: 60px;
}
#chart1 {
border-right:60px solid red;
border-top:60px solid transparent;
border-left:60px solid transparent;
border-bottom:60px solid transparent;
}
#chart2 {
border-right:60px solid transparent;
border-top:60px solid green;
border-left:60px solid transparent;
border-bottom:60px solid transparent;
}
#chart3 {
border-right:60px solid transparent;
border-top:60px solid transparent;
border-left:60px solid blue;
border-bottom:60px solid transparent;
}
#chart4 {
border-right:60px solid transparent;
border-top:60px solid transparent;
border-left:60px solid transparent;
border-bottom:60px solid yellow;
}
<div id="chart1" class="chart"></div>
<div id="chart2" class="chart"></div>
<div id="chart3" class="chart"></div>
<div id="chart4" class="chart"></div>
Upvotes: 1
Reputation: 14990
This really should be created in svg since its a complex shape for css.
svg {
stroke: white;
stroke-width: 0.1;
}
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<path id="piePiece" d="M 42.2,78.9 46.1,64.4 Q 50,65 53.88,64.48 L 57.7,78.9 Q 50,80 42.2,78.9Z" />
</defs>
<use xlink:href="#piePiece" fill="#2D8633"/>
<use xlink:href="#piePiece" transform="rotate(30,50,50)" fill="#236467"/>
<use xlink:href="#piePiece" transform="rotate(60,50,50)" fill="#2E4172"/>
<use xlink:href="#piePiece" transform="rotate(90,50,50)" fill="#413075"/>
<use xlink:href="#piePiece" transform="rotate(120,50,50)" fill="#592A71"/>
<use xlink:href="#piePiece" transform="rotate(150,50,50)" fill="#8A2E60"/>
<use xlink:href="#piePiece" transform="rotate(180,50,50)" fill="#AA3C39"/>
<use xlink:href="#piePiece" transform="rotate(210,50,50)" fill="#AA6D39"/>
<use xlink:href="#piePiece" transform="rotate(240,50,50)" fill="#AA8539"/>
<use xlink:href="#piePiece" transform="rotate(270,50,50)" fill="#AA9739"/>
<use xlink:href="#piePiece" transform="rotate(300,50,50)" fill="#A9AA39"/>
<use xlink:href="#piePiece" transform="rotate(330,50,50)" fill="#A9AA39"/>
</svg>
Upvotes: 2
Reputation: 8412
Please note this is a forked pen with some modifications to it
body {
margin: 60px auto;
background: #F5F5F7;
}
#colorWheel {
height: 100px;
width: 100px;
margin: 0 auto;
position: relative;
-webkit-transform-origin: 50px 150px;
-moz-transform-origin: 50px 150px;
-ms-transform-origin: 50px 150px;
-o-transform-origin: 50px 150px;
transform-origin: 50px 150px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
-webkit-transition: all 0.5s linear;
-moz-transition: all 0.5s linear;
-ms-transition: all 0.5s linear;
-o-transition: all 0.5s linear;
transition: all 0.5s linear;
}
#colorWheel span {
position: absolute;
-webkit-transform-origin: 50% 50%;
border-style: solid;
border-width: 150px 50px;
box-sizing: border-box;
}
#colorWheel span.color01 {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
border-color: #43a1cd transparent transparent transparent;
}
#colorWheel span.color02 {
-webkit-transform: rotate(36deg);
-moz-transform: rotate(36deg);
-ms-transform: rotate(36deg);
-o-transform: rotate(36deg);
transform: rotate(36deg);
border-color: #639b47 transparent transparent transparent;
}
#colorWheel span.color03 {
-webkit-transform: rotate(72deg);
-moz-transform: rotate(72deg);
-ms-transform: rotate(72deg);
-o-transform: rotate(72deg);
transform: rotate(72deg);
border-color: #9ac147 transparent transparent transparent;
}
#colorWheel span.color04 {
-webkit-transform: rotate(108deg);
-moz-transform: rotate(108deg);
-ms-transform: rotate(108deg);
-o-transform: rotate(108deg);
transform: rotate(108deg);
border-color: #e1e23b transparent transparent transparent;
}
#colorWheel span.color05 {
-webkit-transform: rotate(144deg);
-moz-transform: rotate(144deg);
-ms-transform: rotate(144deg);
-o-transform: rotate(144deg);
transform: rotate(144deg);
border-color: #f7941e transparent transparent transparent;
}
#colorWheel span.color06 {
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
-ms-transform: rotate(180deg);
-o-transform: rotate(180deg);
transform: rotate(180deg);
border-color: #ba3e2e transparent transparent transparent;
}
#colorWheel span.color07 {
-webkit-transform: rotate(216deg);
-moz-transform: rotate(216deg);
-ms-transform: rotate(216deg);
-o-transform: rotate(216deg);
transform: rotate(216deg);
border-color: #9a1d34 transparent transparent transparent;
}
#colorWheel span.color08 {
-webkit-transform: rotate(252deg);
-moz-transform: rotate(252deg);
-ms-transform: rotate(252deg);
-o-transform: rotate(252deg);
transform: rotate(252deg);
border-color: #662a6c transparent transparent transparent;
}
#colorWheel span.color09 {
-webkit-transform: rotate(288deg);
-moz-transform: rotate(288deg);
-ms-transform: rotate(288deg);
-o-transform: rotate(288deg);
transform: rotate(288deg);
border-color: #272b66 transparent transparent transparent;
}
#colorWheel span.color10 {
-webkit-transform: rotate(324deg);
-moz-transform: rotate(324deg);
-ms-transform: rotate(324deg);
-o-transform: rotate(324deg);
transform: rotate(324deg);
border-color: #2d559f transparent transparent transparent;
}
#colorWheel:before {
content: "";
width: 300px;
height: 300px;
overflow: hidden;
position: absolute;
top: -30px;
left: -130px;
border-radius: 100%;
border: 30px solid #ffffff;
z-index: 100;
}
#colorWheel:after {
content: "";
width: 100px;
height: 100px;
overflow: hidden;
position: absolute;
top: 100px;
left: 0px;
border-radius: 100%;
background: #ffffff;
}
<div id="colorWheel">
<span class="color01"></span>
<span class="color02"></span>
<span class="color03"></span>
<span class="color04"></span>
<span class="color05"></span>
<span class="color06"></span>
<span class="color07"></span>
<span class="color08"></span>
<span class="color09"></span>
<span class="color10"></span>
</div>
Upvotes: 3