Search code examples
htmlcsscolorsgradient

How can I make a color wheel using CSS (with white at center and fading to black at the rim)?


The code below produces this color wheel, which is close to what I want but not quite:

color wheel

How can I adjust the CSS so that the color wheel contains all hues (such as via conic-gradient, and maybe I've done this correctly already) and each hue transitions from full lightness (white) at the center to 0 lightness (black) at the edge?

By "lightness" I mean the L value in HSL color codes.

div {
  position: absolute;
  width: 200px;
  height: 200px;
  border-radius: 50%;
}


/* https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/radial-gradient */

.radial {
  background: radial-gradient(circle closest-side, hsl(0deg 0% 100% / 100%), hsl(0deg 0% 100% / 50%), hsl(0deg 0% 100% / 0%), hsl(0deg 0% 0% / 0%), hsl(0deg 0% 0% / 100%));
}


/* https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/conic-gradient */

.conic {
  background: conic-gradient(hsl(0deg 100% 50%), hsl(10deg 100% 50%), hsl(20deg 100% 50%), hsl(30deg 100% 50%), hsl(40deg 100% 50%), hsl(50deg 100% 50%), hsl(60deg 100% 50%), hsl(70deg 100% 50%), hsl(80deg 100% 50%), hsl(90deg 100% 50%), hsl(100deg 100% 50%), hsl(110deg 100% 50%), hsl(120deg 100% 50%), hsl(130deg 100% 50%), hsl(140deg 100% 50%), hsl(150deg 100% 50%), hsl(160deg 100% 50%), hsl(170deg 100% 50%), hsl(180deg 100% 50%), hsl(190deg 100% 50%), hsl(200deg 100% 50%), hsl(210deg 100% 50%), hsl(220deg 100% 50%), hsl(230deg 100% 50%), hsl(240deg 100% 50%), hsl(250deg 100% 50%), hsl(260deg 100% 50%), hsl(270deg 100% 50%), hsl(280deg 100% 50%), hsl(290deg 100% 50%), hsl(300deg 100% 50%), hsl(310deg 100% 50%), hsl(320deg 100% 50%), hsl(330deg 100% 50%), hsl(340deg 100% 50%), hsl(350deg 100% 50%));
}
<div class="conic" />
<div class="radial" />

Currently my radial-gradient isn't smooth from center to edge.

https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/conic-gradient

https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/radial-gradient


Solution

  • You could use blend modes like this:

    .radial {
      background: radial-gradient(closest-edge, #fff, #000);
      mix-blend-mode: luminosity; // Tells the browser to use the luminosity values from this gradient
    }
    
    .conic {
      background: conic-gradient(hsl(0deg 100% 50%), hsl(10deg 100% 50%), hsl(20deg 100% 50%), hsl(30deg 100% 50%), hsl(40deg 100% 50%), hsl(50deg 100% 50%), hsl(60deg 100% 50%), hsl(70deg 100% 50%), hsl(80deg 100% 50%), hsl(90deg 100% 50%), hsl(100deg 100% 50%), hsl(110deg 100% 50%), hsl(120deg 100% 50%), hsl(130deg 100% 50%), hsl(140deg 100% 50%), hsl(150deg 100% 50%), hsl(160deg 100% 50%), hsl(170deg 100% 50%), hsl(180deg 100% 50%), hsl(190deg 100% 50%), hsl(200deg 100% 50%), hsl(210deg 100% 50%), hsl(220deg 100% 50%), hsl(230deg 100% 50%), hsl(240deg 100% 50%), hsl(250deg 100% 50%), hsl(260deg 100% 50%), hsl(270deg 100% 50%), hsl(280deg 100% 50%), hsl(290deg 100% 50%), hsl(300deg 100% 50%), hsl(310deg 100% 50%), hsl(320deg 100% 50%), hsl(330deg 100% 50%), hsl(340deg 100% 50%), hsl(350deg 100% 50%));
    }
    

    Color wheel

    This will give you a mathematically smooth colour wheel, however it doesn’t appear visually smooth because HSL isn’t perceptually uniform.

    You might explore using LCH as an alternative approach: https://lea.verou.me/2020/04/lch-colors-in-css-what-why-and-how/