Recreating Apple's Color Picker Icon
Tags: css, design, webdev, showdev
Published: 2022-09-16 09:01:14

I'm currently working on a colorpicker, where a user can select a predefined theme-color:

![Initial colorpicker](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/voprouq1w0hr5pmvmcwf.png)

While this is fairly simple to code and use, there **will** be cases where the user needs to create a custom color.

So, how do you indicate that a color is custom, is not a part of the default theme-colors — and can be modified?

I've spent quite some time investigating this, and then I discovered how Apple do it in their Notes-app: 

![Apple Color Picker](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/85vaijul3i7tlfjoee25.jpeg)

Simple and beautiful! The chosen color is displayed at the center of the circle, surrounded by an inner border and a gradient of hues.

But how to achieve this in CSS?

As always, Temani Afif has [the answer](https://dev.to/afif/border-with-gradient-and-radius-387f).

We'll just replace the `linear-gradient` with a `conic-gradient`: 

```css
.box::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit; 
  padding: 8px; 
  background: conic-gradient(
    hsl(360, 100%, 50%),
    hsl(315, 100%, 50%),
    hsl(270, 100%, 50%),
    hsl(225, 100%, 50%),
    hsl(180, 100%, 50%),
    hsl(135, 100%, 50%),
    hsl(90, 100%, 50%),
    hsl(45, 100%, 50%),
    hsl(0, 100%, 50%)
) border-box;
  -webkit-mask: 
     linear-gradient(#fff 0 0) content-box, 
     linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude; 
}
```

... which results in this:

![Color Picker Icon with gradient border](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t4ymged0o2rgujpobxar.png)

Nice! Now, for the "inner border", I created a second mask:

```css
.box::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit; 
  padding: 12px;
  background: linear-gradient(var(--body-bg) 0 0) border-box;
  -webkit-mask: 
     linear-gradient(#fff 0 0) content-box, 
     linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude; 
}
```

Which gives us:

![With inner white border](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/shl8iyyvtbqjy03nrefr.png)

Almost there ... but what about "dark mode"? Did you notice the `--body-bg`-variable? That takes care of inheriting the background-color, so:

![Dark mode](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pt7qtgra2hqpsxaboi0q.png)

The great thing about this technique, is that it just works with and without `border-radius`:

![Square picker](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8852ndpzp5nhxuo7g4ur.png)

---

## Final Thoughts

I must admit it annoys me a bit to use **both** `pseudo`-elements for masks: one for the `conic-gradient` and one for the inner border. The last one should simply "cut out" an area and let the background-color of the page or section "shine through". If you know how to do this, please share your findings in the comments!

---

After I finished writing this post, I noticed that Apple's icon is a bit more de-saturated. To achieve this, just change the `saturation`-part of the `hsl`-colors in the mask.

Example: Change `hsl(360, 100%, 50%)` to `hsl(360, 80%, 50%)` etc.


![Desaturated](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f54tz08ow31vhobxsdwi.png)