A color picker web component.
- Form-associated custom element (i.e. it works in forms via the ElementInternals API)
- Distributed is ES module format
- Not transpiled
- Uses lit-html (as a peer dependency)
Links:
- demo
- npmjs.com/package/yet-another-color-picker
- github.com/kleinfreund/yet-another-color-picker
- as a Vue component: vue-accessible-color-picker
-
Install the package (and its peer dependencies).
npm install yet-another-color-picker lit-html@^3.0.0
Note: this web component is rendered using lit-html which will have to be installed as well.
-
Import the module to define the custom element.
JavaScript:
import 'yet-another-color-picker'
-
Load the stylesheet.
HTML:
<link rel="stylesheet" href="./node_modules/yet-another-color-picker/dist/ColorPicker.css">
-
Use the
color-pickercustom element.HTML:
<color-picker></color-picker>
Complete example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>color picker demo</title>
<link rel="stylesheet" href="./node_modules/yet-another-color-picker/dist/ColorPicker.css">
</head>
<body>
<color-picker></color-picker>
<script type="module">
import 'yet-another-color-picker'
const colorPicker = document.querySelector('color-picker')
colorPicker.addEventListener('color-change', function (event) {
console.log(event.detail)
})
</script>
</body>
</html>-
Download the files.
curl --remote-name-all 'https://cdn.jsdelivr.net/npm/yet-another-color-picker@latest/dist/ColorPicker.{js,css,d.ts}'-
Define an import map for lit-html.
Since this package does not bundle its dependencies (e.g. lit-html), the distribution files contain imports from bare module specifiers (e.g.
import { render } from 'lit-html'). Browsers don't understand bare module specifiers by default, but with import maps, you can teach them.Add the following to your HTML:
HTML:
<script type="importmap"> { "imports": { "lit-html": "https://cdn.jsdelivr.net/npm/lit-html@^3.0.0" } } </script>
This will make imports like the one mentioned above behave as if they reference the provided URL (e.g.
import { render } from 'lit-html'will behave likeimport { render } from 'https://cdn.jsdelivr.net/npm/lit-html@^3.0.0').
-
-
Import the module to define the custom element.
JavaScript:
import './ColorPicker.js'
-
Load the stylesheet.
HTML:
<link rel="stylesheet" href="./ColorPicker.css">
-
Use the
color-pickercustom element.HTML:
<color-picker></color-picker>
Complete example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>color picker demo</title>
<link rel="stylesheet" href="./ColorPicker.css">
</head>
<body>
<color-picker></color-picker>
<script type="importmap">
{
"imports": {
"lit-html": "https://cdn.jsdelivr.net/npm/lit-html@^3.0.0"
}
}
</script>
<script type="module">
import './ColorPicker.js'
const colorPicker = document.querySelector('color-picker')
colorPicker.addEventListener('color-change', function (event) {
console.log(event.detail)
})
</script>
</body>
</html>In the following sections, the web component's IDL and content attibutes, are documented.
Note: Setting a content attribute will be reflected by its corresponding IDL attribute; however, setting an IDL attribute will not be reflected by its corresponding content attribute.
-
Description: Whether to show controls for a color’s alpha channel. If set to
'hide', the alpha range input and the alpha channel input are hidden, the “Copy color” button will copy a CSS color value without alpha channel, and the object emitted in acolor-changeevent will have acssColorproperty value without alpha channel. -
Type:
'show' | 'hide' -
Required:
false -
Default:
'show' -
Content attribute:
alpha-channel -
Usage:
JavaScript:
colorPicker.alphaChannel = 'hide'
HTML:
<color-picker alpha-channel="hide"></color-picker>
-
Description: Set the color picker's current color as long as the color wasn't changed by the user already.
-
Type:
string -
Required:
false -
Default:
'' -
Content attribute:
value -
Usage:
JavaScript:
colorPicker.defaultValue = 'hsl(270 100% 50% / 0.8)'
HTML:
<color-picker value="hsl(270 100% 50% / 0.8)"></color-picker>
HTML:
<color-picker value="#f80b"></color-picker>
-
Description: Disables the color picker.
-
Type:
boolean -
Required:
false -
Default:
false -
Content attribute:
disabled -
Usage:
JavaScript:
colorPicker.disabled = true
HTML:
<color-picker disabled></color-picker>
-
Description: The current color format. Also changes when interacting with the “Switch format” button or when calling
switchFormat(). -
Type:
VisibleColorFormat -
Required:
false -
Default:
'hsl' -
Content attribute:
format -
Usage:
JavaScript:
colorPicker.format = 'hwb'
HTML:
<color-picker format="hwb"></color-picker>
-
Description: This value will be used to prefix any of the color picker’s form-associated elements’
idandforattribute values. Make sure to set this if you use multiple instances of the component on a page.Note: The IDL attribute
idof form-associated elements is reflected by its content attribute. -
Type:
string -
Required:
false -
Default:
'color-picker' -
Content attribute:
id -
Usage:
JavaScript:
colorPicker.id = 'color-picker-1'
HTML:
<color-picker id="color-picker-1"></color-picker>
-
Description: Name of the color picker (used when the color picker is part of a form).
Note: The IDL attribute
nameof form-associated elements is reflected by its content attribute. -
Type:
string -
Required:
false -
Default:
'' -
Content attribute:
name -
Usage:
JavaScript:
colorPicker.name = 'color-picker'
HTML:
<color-picker name="color-picker"></color-picker>
-
Description: Makes the color picker read-only.
-
Type:
boolean -
Required:
false -
Default:
false -
Content attribute:
readonly -
Usage:
JavaScript:
colorPicker.readonly = true
HTML:
<color-picker readonly></color-picker>
-
Description: The current color of the color picker.
The
valuegetter will return the current color as a string (formatted as a CSS RGB color, e.g.'rgb(127.5 0 255 / 0.8)'). This is also the form value used in form submission.The
valuesetter accepts astring(any valid CSS color in a known format works, e.g.'hsl(270 100% 50% / 0.8)') or anobject(e.g.{ h: 270, s: 100, l: 50, a: 0.8 }). -
Type:
string | ColorHsl | ColorHwb | ColorRgb -
Required:
false -
Default:
'rgb(255 255 255 / 1)' -
Content attribute: None. The
valueIDL attribute doesn't directly reflect a content attribute. However, thevalueIDL attribute does reflect thedefaultValueIDL attribute as long as the dirty flag isn't set. -
Usage:
JavaScript:
colorPicker.value = 'hsl(270 100% 50% / 0.8)' colorPicker.value //> 'rgb(127.5 0 255 / 0.8)'
JavaScript:
colorPicker.value = { h: 270, s: 100, l: 50, a: 0.8 }
-
Description: A list of visible color formats. Controls for which formats the color
inputelements are shown and in which order the formats will be cycled through when activating the format switch button. -
Type:
VisibleColorFormat(an array ofVisibleColorFormats) -
Required:
false -
Default:
['hex', 'hsl', 'hwb', 'rgb'] -
Content attribute:
visible-formats -
Usage:
JavaScript:
colorPicker.visibleFormats = ['hsl', 'hwb']
HTML:
<color-picker visible-formats="hsl,hwb"></color-picker>
-
Description: Copies the current color (determined by the active color format).
This method behaves the same as activating the “Copy color” button.
Only works in secure browsing contexts (i.e. HTTPS).
-
Return type:
Promise<void>(the promise returned by callingwindow.navigator.clipboard.writeText) -
Usage:
JavaScript:
colorPicker.copyColor()
-
Description: Sets the next active color format by cycling through
colorPicker.visibleFormats. This method behaves the same as activating the “Switch format” button. To set a specific color format, use theformatproperty. -
Return type:
void -
Usage:
JavaScript:
colorPicker.switchFormat()
- Description: The
changeevent is fired when the color is changed. - Type:
Event
-
Description: The
color-changeevent is fired when the color is changed. -
Type:
CustomEvent<ColorChangeDetail> -
Data: Emits an object whose
detailproperty contains both the internalcolorsobject and a CSS color value as a string based on the currently active format. ThecssColorproperty respects thealphaChannelIDL attribute.{ colors: { hex: string hsl: ColorHsl hwb: ColorHwb rgb: ColorRgb } cssColor: string }
-
Usage:
HTML:
<color-picker color="hsl(270 100% 50% / 0.8)"></color-picker>
JavaScript:
import 'yet-another-color-picker' const colorPicker = document.querySelector('color-picker') colorPicker.addEventListener('color-change', function (event) { console.log(event.detail) }) colorPicker.value = 'rebeccapurple'
-
Description: The
color-copyevent is fired once a copy operation succeeded. -
Type:
CustomEvent<ColorChangeDetail> -
Data: Emits the same event data as the
color-changeevent. -
Usage:
HTML:
<color-picker color="hsl(270 100% 50% / 0.8)"></color-picker>
JavaScript:
import 'yet-another-color-picker' const colorPicker = document.querySelector('color-picker') colorPicker.addEventListener('color-copy', function (event) { console.log(event.detail) }) colorPicker.copyColor()
- Description: The
inputevent is fired when the color is changed. - Type:
Event
You can customize the GUI of the color picker using CSS custom properties:
:root {
--cp-color-focus: tomato;
--cp-width-border: 2px;
}Available custom properties and their default values:
| Custom property | Default value |
|---|---|
--cp-color-background-input |
#fff |
--cp-color-background |
#fff |
--cp-color-border |
#000 |
--cp-color-focus |
#19f |
--cp-color-text-input |
currentColor |
--cp-color-text |
currentColor |
--cp-font-family |
-apple-system, BlinkMacSystemFont, Segoe UI, Arial, sans-serif |
--cp-font-size |
0.8em |
--cp-spacing |
6px |
--cp-width-border |
1px |
--cp-width-color-space |
300px |
This package uses semantic versioning.
See CONTRIBUTING.md.
The color picker consists of the following main elements:
-
Color space:
For fine-tuning the saturation and lightness/value, a slice of the HSV cylinder for the currently selected hue is shown.
The HSV cylinder is more convenient for this task than the HSL cylinder as it shows a color at 100% saturation and 100% value in the top right corner (i.e. one can drag the color space thumb into the corner as a quasi shortcut). The HSL cylinder’s slice has this color at the halfway point of the Y axis (i.e. at 50% lightness) which isn’t easy to select.
-
Hue slider:
A slider for selecting the current hue. This rotates the HSV cylinder; thus, it changes the slice of the HSV cylinder that’s shown in the color space.
-
Alpha slider:
A slider for selecting the current alpha value.
-
Copy button:
Copies the color formatted as a CSS color string in the active format.
-
Color inputs:
A set of text fields which allow you to enter the individual components of each color. The text fields are shown based on the active format.
-
Switch format button:
Cycles through the available color formats (currently HEX, HSL, HWB, and RGB).
- Re-consider minification strategy following https://lit.dev/docs/tools/publishing/#don't-bundle-minify-or-optimize-modules (see also https://open-wc.org/guides/developing-components/publishing/#do-not-minify).