A field or a swatch that opens a panel to choose a color: by dragging in a square and along strips, by typing its code, or by picking a saved swatch.
Options
| Choice | Values | Default | What it does |
|---|---|---|---|
typesmbk-color-picker--type-<value> | fieldswatch | field | Field shows the color and its code with a caret, as a select does; Swatch shows the color alone, for toolbars and tight rows. |
sizesmbk-color-picker--size-<value> | mdsm | md | The input’s two heights. Field holds a 20 or 16 px swatch; Swatch is a 40 or 32 px square holding a 24 or 16 px one. |
errorsmbk-color-picker--error | On or off | Off | The color is not one the form can take. Draws the input’s danger border on the trigger. |
opensmbk-color-picker--open | On or off | Off | The panel is showing. Set by the component while it is open; the caret turns up. |
Examples
Usage
A field that shows the color and its code; pressed, or with Enter, Space or the down arrow, it opens the panel under it.
The panel
What it opens: the color area, the hue and opacity sliders, the format, the code and the eyedropper (in a browser that has one), and saved colors.
Opacity and the code only
The format, the eyedropper and the saved colors can each be left out.
Swatches in a tight row
The swatch type shows the color alone, for a toolbar or a row of settings.
Sizes
The field and the swatch at the input’s two heights.
Disabled
Dimmed, and it does not open.
Guidelines
Purpose
Lets the reader set a color, such as a brand color, a chart series or a label's color. It is a field or a swatch that opens a panel: a color area, a hue slider and an opacity slider to find a color by eye, the code to type an exact one, an eyedropper to take one from the screen, and saved colors to pick from. Every part works from the keyboard and says its value in words.
When to use
- A setting that is a color: a brand color, a theme's accent, a chart series, a label.
- The swatch type in a toolbar or a tight row of settings, such as fill and line.
When not to use
- To choose among a few set colors only. Use the color swatch picker.
- To enter a code with nothing else. Use the color field.
Usage rules
Do
- Label the picker with what the color is for.
- Give saved colors when the reader is likely to reuse them, such as a brand's palette.
Don't
- Use the swatch type where there is room for the field: the code is what many readers check.
- Put a picker in a row so tight its panel has no room; the panel is as wide as it is.
Label the picker with what the color is for, so the reader and a screen reader know which color they change.
Use a lone swatch where there is room for the field: the code is what many readers check.
Anatomy
- The block, around the trigger and the panel.
- The trigger part, a button that is the input's well: its markup carries the input's classes and the select's well, value and icon parts. The field type holds the swatch part (a color swatch), the value part (the code) and the caret part, which turns up while the panel is open; the swatch type holds the swatch alone in a square as tall as the input.
- The name part, the code and the color in words, read by screen readers only: it names the trigger after its label, and the visible code is hidden from them so it is not heard twice.
- The panel part, the popover's panel at the picker's own width, holding, the medium stack step apart:
- the area part, a color area that fills the panel's width;
- two slider parts, a hue slider and an opacity slider, with their top rows hidden;
- the code part, a row of the format part (a small select), the field part (a small color field) and the eyedropper part (a small secondary icon button);
- the swatches part, a divider part over a small square color swatch picker.
- The opacity slider, the format, the eyedropper and the swatches can each be left out.
Behavior
Pressing the trigger opens the panel under it, or above it when there is more room there; pressing it again closes it. Every part of the panel shares one color, so a change in one shows in all, and in the trigger. The picker holds its own color from a first color, or follows the color the page gives it, and reports each change.
The eyedropper is shown only in a browser that has one, once the page runs; it takes a color from anywhere on the screen and keeps the color's opacity. The format menu offers the hex code. A change in the code field keeps the color's opacity too. Given a name, the picker sends the color with the form as a hex code with its opacity.
Disabled, the trigger is dimmed and does not open; read-only, the color can be read and the panel does not open. The panel alone is also a component, for a page that shows and places it itself, such as a side panel of settings.
Accessibility
What it does for you
- The trigger is one button, named by its label and the color: the code and its name in words, such as “Brand color, #3E63DD, vibrant blue”. It says it opens a dialog, and whether it is open.
- Enter, Space or the down arrow open the panel, a dialog named “Color picker”. Focus stays on the trigger, and Tab goes into the panel next, through the area, the sliders, the format, the code, the eyedropper and the swatches.
- Escape closes the panel and puts focus back on the trigger; a press outside or focus moving away close it too.
- Each part of the panel keeps its own keys and says its value in words: see the color area, the color slider, the color field and the color swatch picker.
- The eyedropper button is named “Pick a color from the screen”.
What you must do
- Give the trigger a label, such as “Brand color”, so its name says what the color is for.
- Give the words the picker says by itself, such as the names of the panel's sliders, format, code, eyedropper and swatches, in the page's own language. They keep their English unless the page gives its own.
How to test
- Tab to the trigger and press Enter, Space or Down Arrow: the panel opens with focus still on the trigger. Press Tab: focus goes into the panel through each part in turn.
- Press Escape: the panel closes and focus is back on the trigger.
- With a screen reader, the trigger is read by its label, the code and the color's name, as a button that opens a dialog, and the panel as a dialog named “Color picker”.
- With text at 200% and the page 320 pixels wide, the panel stays whole and every part stays reachable.
- In a forced-color mode, the focus ring shows on every part.
Keyboard
| Key | What it does |
|---|---|
| Tab | Moves focus to the trigger. With the panel open, moves into the panel and through its parts. |
| EnterorSpaceorDown Arrow | On the trigger, opens the panel. |
| Escape | Closes the panel and puts focus back on the trigger. |
Source
The files the color picker is made of. Its folder on GitHub (opens in a new tab) holds them with its wrapper and its document.
Stylesheet
/* smbk-color-picker — Color picker. Figma "Color picker" 7411:823 and "Color picker panel" 7411:824.
* The trigger is a button that is the input's well, built as the select's is: it carries smbk-input and the
* select's well part, so its chrome, hover, focus, disabled and two sizes are the input's and its button rules
* the select's. Field holds a swatch, the code (the select's value part) and the caret (the input's icon part);
* Swatch holds a swatch alone and hugs it. The panel is the popover's panel at its own width, holding the color
* area, the sliders, the code row and the swatches, the medium stack step apart. This stylesheet only adds the
* picker's own widths and rows. */
.smbk-color-picker {
display: inline-flex;
width: 100%;
}
/* Swatch: a square as tall as the input, the swatch in its middle, the medium inset round it at md. */
.smbk-color-picker--type-swatch {
width: auto;
}
/* Field: the trigger fills the picker's width, as a field does; the popover's anchor around it does too. */
.smbk-color-picker--type-field > .smbk-popover__anchor {
flex: 1 1 auto;
min-width: 0;
}
.smbk-input.smbk-color-picker__trigger {
flex: 1 1 auto;
}
.smbk-color-picker--type-swatch .smbk-input.smbk-color-picker__trigger {
flex: none;
justify-content: center;
width: var(--smbk-size-control-md);
padding: 0;
}
.smbk-color-picker--type-swatch .smbk-input--size-sm.smbk-color-picker__trigger {
width: var(--smbk-size-control-sm);
}
/* The code and the color in words, which name the trigger for screen readers only. */
/* .smbk-color-picker__name: hidden from view, kept for screen readers and the keyboard, by the shared rule in visually-hidden/visually-hidden.css. */
/* ---- the panel: the popover's, at the picker's width and the medium stack step ---- */
.smbk-popover.smbk-color-picker__panel {
width: var(--smbk-size-color-picker-width);
gap: var(--smbk-space-stack-md);
}
/* The area fills the panel's width. */
.smbk-color-area.smbk-color-picker__area {
max-width: none;
}
/* The format, the code and the eyedropper in one row: the code takes what the others leave. */
.smbk-color-picker__code {
display: flex;
align-items: center;
gap: var(--smbk-space-inline-sm);
}
.smbk-select.smbk-color-picker__format {
flex: none;
width: auto;
}
.smbk-input.smbk-color-picker__field {
flex: 1 1 auto;
min-width: 0;
}
.smbk-color-picker__eyedropper {
flex: none;
}
.smbk-color-picker__swatches {
display: flex;
flex-direction: column;
gap: var(--smbk-space-stack-md);
}
/* ---- touch: the last strip and the code row stop halfway to each other ----
The last strip takes an invisible press area on a touch screen, and the code row's text box reaches above its line
to take the press; over a row that holds the format's select, the strip's area stops halfway into the panel's gap,
and the text's reach stops halfway to the strip (the panel's gap and the room over the line in the small well). Nothing drawn moves. */
@media (pointer: coarse) {
.smbk-color-slider:has(+ .smbk-color-picker__code .smbk-select__well) .smbk-color-slider__track::after {
inset-block-end: max(min(0%, (100% - var(--smbk-size-target-comfortable)) / 2), var(--smbk-space-stack-md) / -2);
}
.smbk-color-picker__code .smbk-input__control {
padding-block-start: max(0%, min((var(--smbk-size-target-comfortable) - 1lh) / 2, (var(--smbk-space-stack-md) + (var(--smbk-size-control-sm) - 1lh) / 2) / 2));
margin-block-start: min(0%, max((1lh - var(--smbk-size-target-comfortable)) / 2, (var(--smbk-space-stack-md) + (var(--smbk-size-control-sm) - 1lh) / 2) / -2));
}
}Tokens it reads
| Token and CSS | Value | Preview | Foundation |
|---|---|---|---|
| size.control.md--smbk-size-control-md | comfortable: 40pxcompact: 32pxchanges with density | Size | |
| size.control.sm--smbk-size-control-sm | comfortable: 32pxcompact: 28pxchanges with density | Size | |
| size.color-picker.width--smbk-size-color-picker-width | 256px | Size | |
| space.stack.md--smbk-space-stack-md | comfortable: 12pxcompact: 8pxchanges with density | Spacing | |
| space.inline.sm--smbk-space-inline-sm | comfortable: 6pxcompact: 4pxchanges with density | Spacing | |
| size.target.comfortable--smbk-size-target-comfortable | 44px | Size |
Manifest
{
"name": "color-picker",
"block": "smbk-color-picker",
"summary": "A field or a swatch that opens a panel to choose a color: by dragging in a square and along strips, by typing its code, or by picking a saved swatch.",
"adapt": "css",
"axes": {
"type": {
"values": [
"field",
"swatch"
],
"default": "field",
"description": "Field shows the color and its code with a caret, as a select does; Swatch shows the color alone, for toolbars and tight rows."
},
"size": {
"values": [
"md",
"sm"
],
"default": "md",
"description": "The input’s two heights. Field holds a 20 or 16 px swatch; Swatch is a 40 or 32 px square holding a 24 or 16 px one."
}
},
"flags": {
"error": {
"description": "The color is not one the form can take. Draws the input’s danger border on the trigger."
},
"open": {
"description": "The panel is showing. Set by the component while it is open; the caret turns up."
}
},
"parts": [
"trigger",
"swatch",
"value",
"name",
"caret",
"panel",
"area",
"slider",
"code",
"format",
"field",
"eyedropper",
"swatches",
"divider"
],
"figmaNodeId": "7411:823"
}