Chooses a number, or a lowest and highest number, along a range by dragging, clicking or the arrow keys: fine lines that turn red up to a narrow thumb, a thin line with a round thumb, a filled bar, or a tall filled bar with its label and value inside; a number box beside it takes a typed value.
Options
| Choice | Values | Default | What it does |
|---|---|---|---|
looksmbk-slider--look-<value> | ticksstandardfillcontained | ticks | Ticks: a row of fine lines on a sunken band that turn red up to a narrow thumb. Standard: a thin rounded line, red up to a round thumb. Fill: a thick bar filled red up to a thin light handle, with optional marks between the lowest and highest values. Contained: the filled bar as tall as a control of its size, the label at its start and the value at its end inside it, white where the red passes under them. Figma: Style=Ticks, Standard, Fill, Contained, Ticks the default. |
sizesmbk-slider--size-<value> | lgmdsm | lg | The thumb and the line or bar: the ticks thumb is the selection size tall, the round thumb the icon size across, the fill bar the selection size tall, the contained bar the control size tall. The row that takes the pointer stays at least the smallest touch size at every size. Figma: lg, md, sm, lg the default. |
typesmbk-slider--type-<value> | singlerange | single | One value, red from the start up to the thumb; or a range, two thumbs that stop when they meet and red between them. Figma: Type=Single, Range. |
Examples
Usage
A label, the value with its unit, the lines and the lowest and highest values.
Range
Two thumbs for a lowest and a highest value, the lines red between them; they stop when they meet.
Standard
The standard look: a thin line, red up to a round thumb; a single value, a range and disabled.
Fill
The fill look: a thick bar filled red up to a thin light handle, with fine marks between the lowest and highest values; a single value, a range, disabled, and without the marks.
Contained
The contained look: the filled bar as tall as a control, the label and value inside it, white where the red passes under them; a panel of settings, a range with its lowest and highest values and marks under it, and disabled.
Contained sizes
The contained bar at the large, medium and small control heights, its words and the space around them a step smaller each time.
Guidelines
Purpose
Chooses a number along a range where a rough position matters more than typing an exact figure: a speed, a share, a level. The range type chooses two, a lowest and a highest, such as a price band. Dragging, clicking anywhere along it and the arrow keys all move it, and an optional number box beside it takes an exact figure typed in. It comes in four looks. Ticks, the default, is its own: a row of fine vertical lines on a sunken band, the lines turning brand red up to a narrow red thumb, or between two. Standard is the familiar one: a thin rounded line, red up to a round thumb. Fill is a thick bar filled red up to a thin light handle, with fine marks under it. Contained is the fill look's bar made as tall as a button, with the label and the value inside it; where the red passes under them, the words turn white.
When to use
- A value along a continuous range where a rough setting is enough, and seeing where it sits between the ends helps: a speed, a quantity, an opacity.
- A value the reader tries a few times, watching something else change as they move it.
- A value that is set roughly most of the time but sometimes exactly: add the number box.
Which look:
- Ticks, the default, where the slider is part of the system's own look: a tool's settings, a calculator.
- Standard, where a reader expects a familiar slider, or space is short, since its line is thin.
- Fill, for a level or an amount, where the filled bar reads as how much: a volume, an opacity, a share. It suits a slider opened from a toolbar.
- Contained, for a panel of settings stacked one under another, such as an editor's controls: each slider is one bar the height of a button with its words inside, so a stack of them reads as one panel and takes half the height.
When not to use
- A few named choices. Use a segmented control, where every choice shows and one press picks it.
- Only an exact figure, or a range too wide to set by dragging. Use the number field; when a rough setting helps too, give the slider its number box.
- A value the reader should only read. A slider looks movable; show the number, or a progress bar for an amount done.
Usage rules
Do
- Give the value its unit, through the format the wrapper takes, so both the shown and the spoken value carry it.
- Choose a step that matches how precisely the value matters.
- Give the slider a width where the lines sit comfortably apart, around the width Figma draws it. With number boxes, add their width beside it.
- Leave the value out of the label row when the number box is on: the box already shows it.
- In the contained look, keep the label and the value short, so they sit apart inside the bar and the handle crosses them only on its way. For a range, word the pair briefly, since both values share the bar with the label.
- Leave half a thumb's width of room beside a slider: at its lowest and highest values a thumb reaches that far past the ends of the band. Never put it inside something that clips its edges.
Don't
- Use a slider for a handful of named choices.
- Hide the value, or the label row that holds it, when the exact number matters to the reader at a glance.
- Put the slider where its container would squeeze it very narrow; the lines crowd together.
Show the value with its unit, so it can be read without guessing what the number counts.
A bare number leaves the reader to guess whether it is meters, seconds or a share.
For a few named choices, use a segmented control: every choice is visible and one press picks it.
A slider with three stops hides the choices and makes a press into a drag.
Anatomy
- The block, a column: the label row, then the body, or the row when there is a number box. In the contained look the label row is inside the rail instead.
- The header part, the label row: the label part at the start and the value part at the end. The value can be left out; hiding the label hides the whole row. In the contained look it lies over the bar, inside the rail after the track, and a copy of it sits inside the fill.
- The label part is the label component, and names the slider.
- The value part, the current value in words, its unit included; for a range, both values.
- The row part, only with a number box: the body with a number box after it, or for a range one before it and one after it.
- The number part, the number box: the input component at its small size, at a fixed narrow width, centered on the rail. It shows the value as a bare number.
- The body part: the rail, then the bounds.
- The rail part, the row that takes the pointer. In the ticks and standard looks it is the smallest touch size tall at every size; in the fill look it is the bar, and the area that takes the pointer is never less than the smallest touch size tall; in the contained look it is the bar, at least a control's height, and it grows when the label wraps.
- The track part, centered in the rail: in the ticks look the sunken band with the gray lines; in the standard look the thin rounded gray line; in the fill look the thick pale bar; in the contained look the same pale bar, as tall as the rail.
- The fill part, inside the track: the red part from the start, or the lower thumb, to the value, or the upper thumb. In the fill and contained looks it reaches a little past each handle, so even the lowest value shows a short red stub around the handle. In the contained look it holds the copy of the label row, in white, as wide as the bar and moved back by the fill's start, so the words it cuts off line up with the ones on the bar.
- The lines part, inside the fill, in the ticks look only: the same lines in red, as wide as the rail and moved back by the fill's start, so they sit exactly on the gray ones.
- The thumb part, centered on the value: a narrow red bar a little taller than the lines in the ticks look, a red circle in the standard look, a thin light line inside the red bar in the fill and contained looks. A range has two.
- The bubble part, the tooltip component over a thumb, showing that thumb's value while it is pressed or has keyboard focus.
- The control part, a native range input, invisible, right after each thumb: it does the keyboard, form and screen reader work, and a single slider's input also takes the pointer.
- The bounds part, optional: the lowest and highest values under the rail.
- The marks part, in the fill and contained looks only and optional: a fixed number of fine marks between the lowest and highest values. They are a scale to read by eye, not one mark per step.
Behavior
A single slider's native input does everything: a drag moves the thumb, a click or tap anywhere on the rail jumps it there, and the arrow keys move it by one step, Page Up and Page Down by larger steps and Home and End to the ends, as the browser does for every range. The value, the red lines and the thumb follow at once.
A range has an input for each thumb, and Tab moves from the lower to the upper. The keys work as for one value, but each thumb stops at the other: the lower can go no higher than the upper and the upper no lower than the lower, so they meet and never cross. The pointer is taken by the rail: a press or tap moves the nearer thumb there and a drag carries it on; when the two sit together, a press above them takes the upper one and a press below takes the lower.
When the pointer rests on it, the thumb lifts and its red darkens; while it is pressed, the thumb lifts further, darkens again and the bubble shows its value above it. The bubble also shows while the thumb has keyboard focus. The lift and the color use the state motion and the bubble fades with the feedback motion; none of it moves, so it stays the same under reduced motion. The fill and contained looks' handle keeps its look on hover and press; its bubble shows as the others do.
The number box shows the value as a bare number and changes as the thumb moves. A number typed into it moves the thumb when the reader presses Enter or leaves the box: it is kept between the lowest and highest values and rounded to the step, and a box left empty goes back to the value. The up and down arrow keys step the box as they step the slider. Numbers are read and written the way the reader's language writes them. In a range, the lower box goes no higher than the upper value and the upper box no lower than the lower value. Scrolling over the box never changes it. When the value comes from the box, the change handler is called with the new value only, without the range input's change event.
Hiding the label hides its whole row, the value at its end included, so no row is left with a number alone. The bubble still shows the value whenever the thumb is pressed or has keyboard focus.
In the contained look the label and the value sit inside the bar. Where the red part passes under them they turn white, cut at the red's edge, and stay dark on the pale part, so they read on both. The handle passes over the words as it moves. A press on the words moves the value there, as a press anywhere on the bar does; the label never takes the press. A label too long for the bar wraps, and the bar grows taller to hold it. Hiding the label leaves the bar with no words in it.
The lines spread across whatever width the slider is given, always the same number of them, from a hairline inside one end to a hairline inside the other. The fill look's marks do the same between the lowest and highest values.
In the narrow layout, and on any touch screen, the area that takes a finger grows to the comfortable touch size above and below the rail. The look does not change; the difference is presentational only.
In plain markup, a range's inputs do not take the pointer, so the page must handle presses and drags on the rail itself and give the thumb being dragged data-pressed, which draws it pressed. The React wrapper does this for you.
In plain markup, the page places the parts itself with inline styles: the fill's start and width and each thumb's start as percentages, and the red lines' start set back by the fill's start in the rail's container units (cqi), so they line up with the gray lines. It must update them whenever a value changes. The same percentages serve all three looks. The React wrapper does this for you.
In plain markup, a number box is an input carrying the input's small classes and the number part's class, inside the row part; the page keeps it and the range input in step itself. The React wrapper does this for you.
In plain markup, the contained look's label row goes inside the rail, after the track and before the first thumb. Its copy goes inside the fill, after the lines: a span with the header part's class holding the same label, written as a span with the label's classes, and the same value. The page sets the copy's start back by the fill's start in the rail's container units, as it does for the lines, and keeps its words the same as the row's. The React wrapper does this for you.
Accessibility
What it does for you
- The input is a real range input, so it is announced as a slider with its name, its value and its ends, and it takes part in forms.
- The label names it. With the label hidden, the same words become its accessible name, so it always has one.
- A range's two thumbs each have their own name: the label followed by "lowest" or "highest", or the words the page gives. Each reports only the values it can reach.
- The value is read out in the same words shown, unit included, not as a bare number.
- A number box is named for the same value as the slider beside it: the label, or for a range the label followed by "lowest" or "highest". A screen reader announces it as a number field, so the two are told apart by what they are.
- A number box comes after its thumb in the Tab order; a range's come first and last, around the two thumbs. On a phone it brings up the keyboard for numbers.
- The shown value, the bubble and the bounds are hidden from assistive technology, because the input already says all of them. So is the contained look's white copy of the words, which is inside the hidden track.
- A click anywhere on the rail moves the thumb, so dragging is never the only way to set it.
- The focus ring draws around the thumb, with the page color between the ring and the thumb so it reads over the lines. In the fill and contained looks it draws around the whole bar instead, a small gap away, since the handle is too thin to ring. In forced colors mode an outline takes its place.
- The value is shown by where the thumbs are and by the words, never by color alone. In the contained look the words keep their contrast on both parts of the bar: white on the red, the usual text color on the pale part.
- Disabled, it cannot be focused or moved, its number box is disabled too, and the lines, thumb and words turn to the disabled colors, not a fade. The block carries
aria-disabled, so its faint words read as part of a control out of reach.
What you must do
- Give the slider a label. Hiding it still uses the same words as its accessible name.
- Give the value its unit through the format the wrapper takes, so both the shown and the spoken value carry it.
- In markup written by hand, add
aria-disabledto the block of a disabled slider.
How to test
- Tab to the slider: the focus ring shows around the thumb, and in a forced-color mode an outline takes its place. A range takes Tab from the lower thumb to the upper.
- Press the arrow keys, Page Up, Page Down, Home and End: the thumb and the value follow at once. In a range, neither thumb passes the other.
- With a screen reader, it is read as a slider by its name, with its value in words and its ends; a number box is read as a number field.
- Type a number in the number box and press Enter: the thumb moves to it, kept between the ends and rounded to the step.
- On a touch screen, a tap anywhere on the rail moves the thumb.
- In the contained look, move the thumb across the words: they turn white over the red, line up with the dark ones letter for letter, and read on both parts.
- With text at 200% and the page 320 pixels wide, the label and value stay whole; in the contained look a long label wraps and the bar grows to hold it.
Keyboard
| Key | What it does |
|---|---|
| Tab | Moves focus to the slider's thumb, or from a range's lower thumb to its upper one, and on to the number box. |
| Arrow keys | Move the thumb by one step; each thumb of a range stops at the other. |
| Page UporPage Down | Moves the thumb by a larger step. |
| HomeorEnd | Moves the thumb to the lowest or the highest value. |
| Enter | In the number box, sets the thumb to the number typed. |
| Up ArroworDown Arrow | In the number box, steps its value as they step the slider. |
Source
The files the slider is made of. Its folder on GitHub (opens in a new tab) holds them with its wrapper and its document.
Stylesheet
/* smbk-slider — Slider. Figma "Slider" 4711:52100 over "SliderThumb" 4711:51614.
* Four looks. Ticks, the default: a row of fine vertical lines on a sunken
* band; the lines turn brand red up to the thumb, a narrow red bar, or between
* two thumbs for a range. Standard: a thin rounded line, red up to a round
* thumb. Fill: a thick bar filled red up to a thin light handle. Contained:
* the fill look's bar as tall as a control, the label and value inside it. Each
* thumb has a native range input, invisible, right after it in the markup:
* the input does the keyboard, form and screen reader work, and the thumb
* reads the input's states with :has(+ …). A single slider's input also lies
* over the whole rail and takes the pointer; a range's two inputs cannot
* share the pointer, so the wrapper takes it on the rail and moves the nearer
* thumb. The wrapper sets the value as percentages: the red window's start
* and width, the red lines' offset inside it, and each thumb's place. */
.smbk-slider {
display: grid;
gap: var(--smbk-space-stack-sm);
min-width: 0;
}
/* ---- the label row: label at the start, value at the end ---- */
.smbk-slider__header {
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: var(--smbk-space-inline-md);
min-width: 0;
}
.smbk-slider__value {
margin-inline-start: auto;
color: var(--smbk-color-text-default);
font-family: var(--smbk-typography-body-xs-font-family);
font-size: var(--smbk-typography-body-xs-font-size);
font-weight: var(--smbk-typography-body-xs-font-weight);
line-height: var(--smbk-typography-body-xs-line-height);
letter-spacing: var(--smbk-typography-body-xs-letter-spacing);
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
.smbk-slider__body {
display: grid;
gap: var(--smbk-space-stack-xs);
}
/* ---- the rail: the row that takes the pointer, the smallest touch size tall.
It is a size container, so the red lines can be as wide as the whole rail
however narrow their window is. ---- */
.smbk-slider__rail {
position: relative;
height: var(--smbk-size-target-min);
container-type: inline-size;
}
/* The band and its lines. 45 lines, as Figma draws, spread across the band:
the first and last sit a hairline in from its ends, the rest evenly between. */
.smbk-slider__track {
position: absolute;
inset-inline: 0;
top: 50%;
translate: 0 -50%;
box-sizing: border-box;
height: var(--smbk-size-icon-md);
padding-inline: calc(var(--smbk-border-width-hairline) / 2);
color: var(--smbk-color-border-control);
background-color: var(--smbk-color-surface-sunken);
background-image: repeating-linear-gradient(to right, currentColor 0 var(--smbk-border-width-hairline), transparent var(--smbk-border-width-hairline) calc((100% - var(--smbk-border-width-hairline)) / 44));
background-origin: content-box;
background-repeat: no-repeat;
pointer-events: none;
}
/* The red window: from the start (or the lower thumb) to the value (or the
upper thumb). It holds the red lines and cuts them off at its edges. */
.smbk-slider__fill {
position: absolute;
inset-block: 0;
overflow: hidden;
}
/* The same lines in red, as wide as the rail and moved back by the window's
start, so every red line sits exactly on a gray one. */
.smbk-slider__lines {
position: absolute;
inset-block: 0;
box-sizing: border-box;
width: 100cqi;
padding-inline: calc(var(--smbk-border-width-hairline) / 2);
color: var(--smbk-color-border-brand);
background-color: var(--smbk-color-surface-sunken);
background-image: repeating-linear-gradient(to right, currentColor 0 var(--smbk-border-width-hairline), transparent var(--smbk-border-width-hairline) calc((100% - var(--smbk-border-width-hairline)) / 44));
background-origin: content-box;
background-repeat: no-repeat;
}
.smbk-slider__thumb {
position: absolute;
top: 50%;
translate: 0 -50%;
box-sizing: border-box;
width: var(--smbk-size-8);
height: var(--smbk-size-selection-lg);
margin-inline-start: calc(var(--smbk-size-8) / -2);
border: var(--smbk-border-width-hairline) solid var(--smbk-color-border-rim-subtle);
border-radius: var(--smbk-radius-full);
background: var(--smbk-color-surface-brand);
box-shadow: var(--smbk-elevation-control);
pointer-events: none;
}
/* The value bubble: the tooltip, over the thumb, its arrow's tip on the thumb's top.
Two classes, so these win over the tooltip's own block rule wherever it loads. */
.smbk-slider__thumb > .smbk-slider__bubble {
position: absolute;
bottom: calc(100% + var(--smbk-size-icon-xs) / 2);
left: 50%;
translate: -50% 0;
visibility: hidden;
opacity: 0;
}
/* The input: as wide as the rail plus one thumb, so the browser's own thumb,
drawn at the drawn thumb's width, lands where the drawn thumb is. */
.smbk-slider__control {
position: absolute;
top: 0;
inset-inline-start: calc(var(--smbk-size-8) / -2);
box-sizing: border-box;
width: calc(100% + var(--smbk-size-8));
height: 100%;
margin: 0;
padding: 0;
border: 0;
background: transparent;
opacity: 0;
appearance: none;
cursor: pointer;
}
.smbk-slider__control::-webkit-slider-runnable-track {
height: 100%;
background: transparent;
}
.smbk-slider__control::-webkit-slider-thumb {
width: var(--smbk-size-8);
height: 100%;
appearance: none;
}
.smbk-slider__control::-moz-range-track {
height: 100%;
background: transparent;
}
.smbk-slider__control::-moz-range-thumb {
width: var(--smbk-size-8);
height: 100%;
border: 0;
background: transparent;
}
/* ---- sizes: lg is the default above ---- */
.smbk-slider--size-md .smbk-slider__track {
height: var(--smbk-size-icon-sm);
}
.smbk-slider--size-md .smbk-slider__thumb {
height: var(--smbk-size-selection-md);
}
.smbk-slider--size-sm .smbk-slider__track {
height: var(--smbk-size-icon-xs);
}
.smbk-slider--size-sm .smbk-slider__thumb {
width: var(--smbk-size-6);
height: var(--smbk-size-selection-sm);
margin-inline-start: calc(var(--smbk-size-6) / -2);
}
.smbk-slider--size-sm .smbk-slider__control {
inset-inline-start: calc(var(--smbk-size-6) / -2);
width: calc(100% + var(--smbk-size-6));
}
.smbk-slider--size-sm .smbk-slider__control::-webkit-slider-thumb {
width: var(--smbk-size-6);
}
.smbk-slider--size-sm .smbk-slider__control::-moz-range-thumb {
width: var(--smbk-size-6);
}
/* ---- the standard look: a thin rounded line, red up to a round thumb ---- */
.smbk-slider--look-standard .smbk-slider__track {
height: var(--smbk-size-6);
padding-inline: 0;
border-radius: var(--smbk-radius-full);
background-color: var(--smbk-color-border-control);
background-image: none;
}
.smbk-slider--look-standard.smbk-slider--size-md .smbk-slider__track,
.smbk-slider--look-standard.smbk-slider--size-sm .smbk-slider__track {
height: var(--smbk-size-4);
}
.smbk-slider--look-standard .smbk-slider__fill {
border-radius: var(--smbk-radius-full);
background-color: var(--smbk-color-action-brand-background);
}
/* The red lines belong to the ticks look only. */
.smbk-slider--look-standard .smbk-slider__lines,
.smbk-slider--look-fill .smbk-slider__lines,
.smbk-slider--look-contained .smbk-slider__lines {
display: none;
}
/* The round thumb, the icon size across. The input and the browser's own thumb follow its width,
as for the ticks thumb. */
.smbk-slider--look-standard .smbk-slider__thumb {
width: var(--smbk-size-icon-md);
height: var(--smbk-size-icon-md);
margin-inline-start: calc(var(--smbk-size-icon-md) / -2);
}
.smbk-slider--look-standard .smbk-slider__control {
inset-inline-start: calc(var(--smbk-size-icon-md) / -2);
width: calc(100% + var(--smbk-size-icon-md));
}
.smbk-slider--look-standard .smbk-slider__control::-webkit-slider-thumb {
width: var(--smbk-size-icon-md);
}
.smbk-slider--look-standard .smbk-slider__control::-moz-range-thumb {
width: var(--smbk-size-icon-md);
}
.smbk-slider--look-standard.smbk-slider--size-md .smbk-slider__thumb {
width: var(--smbk-size-icon-sm);
height: var(--smbk-size-icon-sm);
margin-inline-start: calc(var(--smbk-size-icon-sm) / -2);
}
.smbk-slider--look-standard.smbk-slider--size-md .smbk-slider__control {
inset-inline-start: calc(var(--smbk-size-icon-sm) / -2);
width: calc(100% + var(--smbk-size-icon-sm));
}
.smbk-slider--look-standard.smbk-slider--size-md .smbk-slider__control::-webkit-slider-thumb {
width: var(--smbk-size-icon-sm);
}
.smbk-slider--look-standard.smbk-slider--size-md .smbk-slider__control::-moz-range-thumb {
width: var(--smbk-size-icon-sm);
}
.smbk-slider--look-standard.smbk-slider--size-sm .smbk-slider__thumb {
width: var(--smbk-size-icon-xs);
height: var(--smbk-size-icon-xs);
margin-inline-start: calc(var(--smbk-size-icon-xs) / -2);
}
.smbk-slider--look-standard.smbk-slider--size-sm .smbk-slider__control {
inset-inline-start: calc(var(--smbk-size-icon-xs) / -2);
width: calc(100% + var(--smbk-size-icon-xs));
}
.smbk-slider--look-standard.smbk-slider--size-sm .smbk-slider__control::-webkit-slider-thumb {
width: var(--smbk-size-icon-xs);
}
.smbk-slider--look-standard.smbk-slider--size-sm .smbk-slider__control::-moz-range-thumb {
width: var(--smbk-size-icon-xs);
}
/* ---- the fill look: a thick bar filled red up to a thin light handle. The rail is the handle's
travel: it is set in from each end of the bar by half the handle and the small inline space
around it, and the bar is drawn that far past it. The red part reaches that far past each
handle, so at the lowest value a short red stub still holds the handle. The input is as wide as
the bar, and the browser's own thumb is the handle with that space on both sides, so the
browser's place for a value is where the handle is drawn. ---- */
.smbk-slider--look-fill .smbk-slider__rail {
height: var(--smbk-size-selection-lg);
margin-inline: calc(var(--smbk-space-inline-xs) + var(--smbk-size-4) / 2);
}
.smbk-slider--look-fill.smbk-slider--size-md .smbk-slider__rail {
height: var(--smbk-size-selection-md);
}
.smbk-slider--look-fill.smbk-slider--size-sm .smbk-slider__rail {
height: var(--smbk-size-selection-sm);
}
/* The bar, left in the rail's flow rather than placed, so the red part inside it is placed
against the rail, in the same percentages as the handles. */
.smbk-slider--look-fill .smbk-slider__track {
position: static;
display: block;
height: 100%;
margin-inline: calc((var(--smbk-space-inline-xs) + var(--smbk-size-4) / 2) * -1);
padding-inline: 0;
translate: none;
border-radius: var(--smbk-radius-control-sm);
background-color: var(--smbk-color-surface-neutral-subtle);
background-image: none;
}
.smbk-slider--look-fill .smbk-slider__fill {
box-sizing: content-box;
margin-inline-start: calc((var(--smbk-space-inline-xs) + var(--smbk-size-4) / 2) * -1);
padding-inline: calc(var(--smbk-space-inline-xs) + var(--smbk-size-4) / 2);
border-radius: var(--smbk-radius-control-sm);
background-color: var(--smbk-color-action-brand-background);
}
.smbk-slider--look-fill .smbk-slider__thumb {
width: var(--smbk-size-4);
height: var(--smbk-size-16);
margin-inline-start: calc(var(--smbk-size-4) / -2);
border: 0;
background: var(--smbk-color-action-brand-foreground);
box-shadow: none;
}
.smbk-slider--look-fill.smbk-slider--size-md .smbk-slider__thumb {
height: var(--smbk-size-12);
}
.smbk-slider--look-fill.smbk-slider--size-sm .smbk-slider__thumb {
height: var(--smbk-size-8);
}
/* At least the smallest touch size tall, however thin the bar. */
.smbk-slider--look-fill .smbk-slider__control {
top: 50%;
translate: 0 -50%;
inset-inline-start: calc((var(--smbk-space-inline-xs) + var(--smbk-size-4) / 2) * -1);
width: calc(100% + var(--smbk-space-inline-xs) * 2 + var(--smbk-size-4));
height: max(100%, var(--smbk-size-target-min));
}
.smbk-slider--look-fill .smbk-slider__control::-webkit-slider-thumb {
width: calc(var(--smbk-space-inline-xs) * 2 + var(--smbk-size-4));
}
.smbk-slider--look-fill .smbk-slider__control::-moz-range-thumb {
width: calc(var(--smbk-space-inline-xs) * 2 + var(--smbk-size-4));
}
/* A range's rail takes the pointer over the whole bar. */
.smbk-slider--look-fill.smbk-slider--type-range .smbk-slider__rail::before {
content: '';
position: absolute;
inset-inline: calc((var(--smbk-space-inline-xs) + var(--smbk-size-4) / 2) * -1);
top: 50%;
translate: 0 -50%;
height: max(100%, var(--smbk-size-target-min));
}
/* ---- the contained look: the fill look's bar as tall as a control of its size, the label at its
start and the value at its end inside it. The bar, the red part, the handle and the input are
placed as in the fill look, by how far the bar reaches past the rail: the handle's width and the
space around it, a step wider at each larger size. The words are the label row, moved into the
rail and laid over the bar; a copy of the row inside the red part, as wide as the bar and moved
back by the red part's start as the ticks look's red lines are, draws the same words in the text
color on brand, so where the red passes under the words they turn, cut at its edge. ---- */
.smbk-slider--look-contained {
--smbk-slider-reach: calc(var(--smbk-space-inline-md) + var(--smbk-size-4) / 2);
--smbk-slider-bar: var(--smbk-size-control-lg);
--smbk-slider-inset: var(--smbk-space-inset-2xl);
--smbk-slider-corner: var(--smbk-radius-control-lg);
}
.smbk-slider--look-contained.smbk-slider--size-md {
--smbk-slider-reach: calc(var(--smbk-space-inline-sm) + var(--smbk-size-4) / 2);
--smbk-slider-bar: var(--smbk-size-control-md);
--smbk-slider-inset: var(--smbk-space-inset-xl);
--smbk-slider-corner: var(--smbk-radius-control-md);
}
.smbk-slider--look-contained.smbk-slider--size-sm {
--smbk-slider-reach: calc(var(--smbk-space-inline-xs) + var(--smbk-size-4) / 2);
--smbk-slider-bar: var(--smbk-size-control-sm);
--smbk-slider-inset: var(--smbk-space-inset-lg);
--smbk-slider-corner: var(--smbk-radius-control-sm);
}
/* The bar and the words share the rail's one cell, so a label that wraps makes the bar taller.
The bar comes first: the words are drawn over it, and the red part, being placed, over both. */
.smbk-slider--look-contained .smbk-slider__rail {
display: grid;
height: auto;
min-height: var(--smbk-slider-bar);
margin-inline: var(--smbk-slider-reach);
}
.smbk-slider--look-contained .smbk-slider__track,
.smbk-slider--look-contained .smbk-slider__rail > .smbk-slider__header {
grid-area: 1 / 1;
margin-inline: calc(var(--smbk-slider-reach) * -1);
}
.smbk-slider--look-contained .smbk-slider__track {
position: static;
height: auto;
padding-inline: 0;
translate: none;
border-radius: var(--smbk-slider-corner);
background-color: var(--smbk-color-surface-neutral-subtle);
background-image: none;
}
.smbk-slider--look-contained .smbk-slider__fill {
box-sizing: content-box;
margin-inline-start: calc(var(--smbk-slider-reach) * -1);
padding-inline: var(--smbk-slider-reach);
border-radius: var(--smbk-slider-corner);
background-color: var(--smbk-color-action-brand-background);
}
/* The words, inset as a control's are, and never closer to an end than the red part reaches past
a handle there, so a handle at either end stays clear of them. The pointer goes through them to
the input or the rail. */
.smbk-slider--look-contained .smbk-slider__header {
box-sizing: border-box;
align-items: center;
padding-block: var(--smbk-space-inset-xs);
padding-inline: max(var(--smbk-slider-inset), calc(var(--smbk-slider-reach) * 2));
color: var(--smbk-color-text-default);
pointer-events: none;
}
.smbk-slider--look-contained .smbk-slider__fill > .smbk-slider__header {
position: absolute;
inset-block: 0;
width: calc(100cqi + var(--smbk-slider-reach) * 2);
color: var(--smbk-color-text-on-brand);
}
.smbk-slider--look-contained .smbk-slider__header > .smbk-slider__label {
min-width: 0;
color: inherit;
font-family: var(--smbk-typography-label-lg-font-family);
font-size: var(--smbk-typography-label-lg-font-size);
font-weight: var(--smbk-typography-label-lg-font-weight);
line-height: var(--smbk-typography-label-lg-line-height);
letter-spacing: var(--smbk-typography-label-lg-letter-spacing);
}
.smbk-slider--look-contained .smbk-slider__header > .smbk-slider__value {
color: inherit;
font-family: var(--smbk-typography-body-md-font-family);
font-size: var(--smbk-typography-body-md-font-size);
font-weight: var(--smbk-typography-body-md-font-weight);
line-height: var(--smbk-typography-body-md-line-height);
letter-spacing: var(--smbk-typography-body-md-letter-spacing);
}
.smbk-slider--look-contained.smbk-slider--size-sm .smbk-slider__header > .smbk-slider__label {
font-family: var(--smbk-typography-label-md-font-family);
font-size: var(--smbk-typography-label-md-font-size);
font-weight: var(--smbk-typography-label-md-font-weight);
line-height: var(--smbk-typography-label-md-line-height);
letter-spacing: var(--smbk-typography-label-md-letter-spacing);
}
.smbk-slider--look-contained.smbk-slider--size-sm .smbk-slider__header > .smbk-slider__value {
font-family: var(--smbk-typography-body-sm-font-family);
font-size: var(--smbk-typography-body-sm-font-size);
font-weight: var(--smbk-typography-body-sm-font-weight);
line-height: var(--smbk-typography-body-sm-line-height);
letter-spacing: var(--smbk-typography-body-sm-letter-spacing);
}
/* The handle is half the bar tall; its bubble clears the bar's top, a quarter of the bar above it. */
.smbk-slider--look-contained .smbk-slider__thumb {
width: var(--smbk-size-4);
height: calc(var(--smbk-slider-bar) / 2);
margin-inline-start: calc(var(--smbk-size-4) / -2);
border: 0;
background: var(--smbk-color-action-brand-foreground);
box-shadow: none;
}
.smbk-slider--look-contained .smbk-slider__thumb > .smbk-slider__bubble {
bottom: calc(150% + var(--smbk-size-icon-xs) / 2);
}
.smbk-slider--look-contained .smbk-slider__control {
top: 50%;
translate: 0 -50%;
inset-inline-start: calc(var(--smbk-slider-reach) * -1);
width: calc(100% + var(--smbk-slider-reach) * 2);
height: 100%;
}
.smbk-slider--look-contained .smbk-slider__control::-webkit-slider-thumb {
width: calc(var(--smbk-slider-reach) * 2);
}
.smbk-slider--look-contained .smbk-slider__control::-moz-range-thumb {
width: calc(var(--smbk-slider-reach) * 2);
}
.smbk-slider--look-contained.smbk-slider--type-range .smbk-slider__rail::before {
content: '';
position: absolute;
inset-inline: calc(var(--smbk-slider-reach) * -1);
inset-block: 0;
}
/* ---- range: the rail takes the pointer, the thumbs take hover ---- */
.smbk-slider--type-range .smbk-slider__rail {
cursor: pointer;
touch-action: pan-y;
}
.smbk-slider--type-range .smbk-slider__control {
pointer-events: none;
}
.smbk-slider--type-range .smbk-slider__thumb {
pointer-events: auto;
}
/* ---- states: each thumb reads the input right after it ---- */
@media (hover: hover) {
.smbk-slider__thumb:has(+ .smbk-slider__control:hover),
.smbk-slider--type-range .smbk-slider__thumb:hover {
background: var(--smbk-color-action-brand-background-hover);
box-shadow: var(--smbk-elevation-raised);
}
}
.smbk-slider__thumb:has(+ .smbk-slider__control:active),
.smbk-slider--type-range .smbk-slider__thumb:active,
.smbk-slider__thumb[data-pressed] {
background: var(--smbk-color-action-brand-background-pressed);
box-shadow: var(--smbk-elevation-raised-strong);
}
/* The bubble shows while the thumb is pressed, and while it has keyboard focus, so the value
stays in sight when the label row is hidden. */
.smbk-slider__thumb:has(+ .smbk-slider__control:active) > .smbk-slider__bubble,
.smbk-slider--type-range .smbk-slider__thumb:active > .smbk-slider__bubble,
.smbk-slider__thumb[data-pressed] > .smbk-slider__bubble,
.smbk-slider__thumb:has(+ .smbk-slider__control:focus-visible) > .smbk-slider__bubble {
visibility: visible;
opacity: 1;
}
/* Figma's focus style: the page color in the gap, then the focus ring, so the
ring reads clearly over the lines. The transparent outline is what forced
colors mode paints, since it drops shadows. */
.smbk-slider__thumb:has(+ .smbk-slider__control:focus-visible) {
outline: var(--smbk-focus-ring-width) solid transparent;
outline-offset: var(--smbk-focus-ring-offset);
box-shadow:
0 0 0 var(--smbk-focus-ring-offset) var(--smbk-color-surface-canvas),
0 0 0 calc(var(--smbk-focus-ring-offset) + var(--smbk-focus-ring-width)) var(--smbk-color-border-focus);
}
/* The fill look's handle keeps its look on hover and press, as Figma draws it, and its focus
ring goes round the whole bar, not the handle; the contained look's the same. */
:is(.smbk-slider--look-fill, .smbk-slider--look-contained) .smbk-slider__thumb:is(:hover, :active, [data-pressed], :has(+ .smbk-slider__control:is(:hover, :active, :focus-visible))) {
outline: 0;
background: var(--smbk-color-action-brand-foreground);
box-shadow: none;
}
:is(.smbk-slider--look-fill, .smbk-slider--look-contained) .smbk-slider__rail:has(.smbk-slider__control:focus-visible) .smbk-slider__track {
outline: var(--smbk-focus-ring-width) solid var(--smbk-color-border-focus);
outline-offset: var(--smbk-focus-ring-offset);
}
.smbk-slider__control:disabled {
cursor: default;
}
.smbk-slider__rail:has(.smbk-slider__control:disabled) {
cursor: default;
}
.smbk-slider__rail:has(.smbk-slider__control:disabled) .smbk-slider__track {
color: var(--smbk-color-border-subtle);
}
.smbk-slider__rail:has(.smbk-slider__control:disabled) .smbk-slider__lines {
color: var(--smbk-color-icon-disabled);
}
.smbk-slider__thumb:has(+ .smbk-slider__control:disabled) {
border-color: var(--smbk-color-border-control-disabled);
background: var(--smbk-color-icon-disabled);
box-shadow: none;
pointer-events: none;
}
/* Disabled, the standard line and the fill bar's red part turn gray; the handle turns to the
subtle track color. */
.smbk-slider--look-standard .smbk-slider__rail:has(.smbk-slider__control:disabled) .smbk-slider__track {
background-color: var(--smbk-color-border-control-disabled);
}
.smbk-slider--look-standard .smbk-slider__rail:has(.smbk-slider__control:disabled) .smbk-slider__fill,
:is(.smbk-slider--look-fill, .smbk-slider--look-contained) .smbk-slider__rail:has(.smbk-slider__control:disabled) .smbk-slider__fill {
background-color: var(--smbk-color-action-disabled-foreground);
}
:is(.smbk-slider--look-fill, .smbk-slider--look-contained) .smbk-slider__thumb:has(+ .smbk-slider__control:disabled) {
background: var(--smbk-color-surface-track-subtle);
}
/* The contained look's words on the grayed part turn to the inverse text color, as dim as the
disabled words beside them in either theme. */
.smbk-slider--look-contained:has(.smbk-slider__control:disabled) .smbk-slider__fill > .smbk-slider__header > :is(.smbk-slider__label, .smbk-slider__value) {
color: var(--smbk-color-text-inverse);
}
.smbk-slider:has(.smbk-slider__control:disabled) .smbk-slider__marks {
color: var(--smbk-color-border-control-disabled);
}
.smbk-slider:has(.smbk-slider__control:disabled) .smbk-slider__label,
.smbk-slider:has(.smbk-slider__control:disabled) .smbk-slider__value,
.smbk-slider:has(.smbk-slider__control:disabled) .smbk-slider__bounds {
color: var(--smbk-color-text-disabled);
}
/* ---- min and max under the band ---- */
.smbk-slider__bounds {
display: flex;
justify-content: space-between;
gap: var(--smbk-space-inline-md);
color: var(--smbk-color-text-subtlest);
font-family: var(--smbk-typography-body-xs-font-family);
font-size: var(--smbk-typography-body-xs-font-size);
font-weight: var(--smbk-typography-body-xs-font-weight);
line-height: var(--smbk-typography-body-xs-line-height);
letter-spacing: var(--smbk-typography-body-xs-letter-spacing);
}
/* The fill look's marks between the lowest and highest values: 21 fine marks, the first and last
at the ends of their space, the rest evenly between. They do not stand for steps. */
.smbk-slider__marks {
flex: 1 1 auto;
align-self: center;
height: var(--smbk-size-6);
color: var(--smbk-color-border-control);
background-image: repeating-linear-gradient(to right, currentColor 0 var(--smbk-border-width-hairline), transparent var(--smbk-border-width-hairline) calc((100% - var(--smbk-border-width-hairline)) / 20));
background-repeat: no-repeat;
}
/* ---- the number box: a small input beside the rail, one at each end for a range, centered on
the rail. It carries the input's own classes, so the input's stylesheet draws it. ---- */
.smbk-slider__row {
display: flex;
align-items: flex-start;
gap: var(--smbk-space-inline-md);
min-width: 0;
}
.smbk-slider__row > .smbk-slider__body {
flex: 1 1 auto;
min-width: 0;
}
.smbk-slider__row > .smbk-slider__number {
flex: none;
width: var(--smbk-size-64);
margin-block-start: calc((var(--smbk-size-target-min) - var(--smbk-size-control-sm)) / 2);
}
.smbk-slider--look-fill .smbk-slider__row > .smbk-slider__number {
margin-block-start: calc((var(--smbk-size-selection-lg) - var(--smbk-size-control-sm)) / 2);
}
.smbk-slider--look-fill.smbk-slider--size-md .smbk-slider__row > .smbk-slider__number {
margin-block-start: calc((var(--smbk-size-selection-md) - var(--smbk-size-control-sm)) / 2);
}
.smbk-slider--look-fill.smbk-slider--size-sm .smbk-slider__row > .smbk-slider__number {
margin-block-start: calc((var(--smbk-size-selection-sm) - var(--smbk-size-control-sm)) / 2);
}
.smbk-slider--look-contained .smbk-slider__row > .smbk-slider__number {
margin-block-start: calc((var(--smbk-slider-bar) - var(--smbk-size-control-sm)) / 2);
}
/* ---- the narrow form: a finger-sized target, the look unchanged ---- */
@container style(--smbk-layout: narrow) {
.smbk-slider__control {
top: calc((var(--smbk-size-target-min) - var(--smbk-size-target-comfortable)) / 2);
height: var(--smbk-size-target-comfortable);
}
.smbk-slider--type-range .smbk-slider__rail::before {
content: '';
position: absolute;
inset-inline: 0;
top: calc((var(--smbk-size-target-min) - var(--smbk-size-target-comfortable)) / 2);
height: var(--smbk-size-target-comfortable);
}
/* The fill bar may be thinner than the smallest touch size, so its target is centered on it. */
.smbk-slider--look-fill .smbk-slider__control,
.smbk-slider--look-fill.smbk-slider--type-range .smbk-slider__rail::before {
top: 50%;
height: var(--smbk-size-target-comfortable);
}
/* The contained bar may be shorter than the comfortable size, so its target is centered on it and never less. */
.smbk-slider--look-contained .smbk-slider__control,
.smbk-slider--look-contained.smbk-slider--type-range .smbk-slider__rail::before {
top: 50%;
translate: 0 -50%;
height: max(100%, var(--smbk-size-target-comfortable));
}
}
/* ---- touch: the same finger-sized target on any touch screen, at any width ----
The narrow form above grows the target where the layout is narrow; a touch screen grows it too, so a tablet
in a wide layout gets it as well. The rules are the narrow form's, repeated, since one block cannot answer
to both a container and a media query. */
@media (pointer: coarse) {
.smbk-slider__control {
top: calc((var(--smbk-size-target-min) - var(--smbk-size-target-comfortable)) / 2);
height: var(--smbk-size-target-comfortable);
}
.smbk-slider--type-range .smbk-slider__rail::before {
content: '';
position: absolute;
inset-inline: 0;
top: calc((var(--smbk-size-target-min) - var(--smbk-size-target-comfortable)) / 2);
height: var(--smbk-size-target-comfortable);
}
/* The fill bar may be thinner than the smallest touch size, so its target is centered on it. */
.smbk-slider--look-fill .smbk-slider__control,
.smbk-slider--look-fill.smbk-slider--type-range .smbk-slider__rail::before {
top: 50%;
height: var(--smbk-size-target-comfortable);
}
/* The contained bar may be shorter than the comfortable size, so its target is centered on it and never less. */
.smbk-slider--look-contained .smbk-slider__control,
.smbk-slider--look-contained.smbk-slider--type-range .smbk-slider__rail::before {
top: 50%;
translate: 0 -50%;
height: max(100%, var(--smbk-size-target-comfortable));
}
}
/* ---- motion: the thumb lifts and darkens with the state purpose; the bubble fades with the
feedback purpose, as the tooltip does. Nothing here moves, so all of it stays under reduced motion. ---- */
.smbk-slider__thumb {
transition-property: box-shadow, background-color;
transition-duration: var(--smbk-motion-state-duration);
transition-timing-function: var(--smbk-motion-state-easing);
}
.smbk-slider__thumb > .smbk-slider__bubble {
transition-property: opacity, visibility;
transition-duration: var(--smbk-motion-feedback-duration);
transition-timing-function: var(--smbk-motion-feedback-easing);
}
/* ---- high contrast (forced colors) ---- */
/* In Windows high-contrast mode the browser drops fills and shadows; this puts the meaning back with the
user's own colors. Nothing here applies outside that mode. */
@media (forced-colors: active) {
/* The band keeps its lines (drawn as a background image, which forced colors would drop), in
CanvasText; the part up to the thumb is filled with Highlight; the thumb is CanvasText. */
.smbk-slider__track,
.smbk-slider__lines {
forced-color-adjust: none;
}
.smbk-slider__track {
background-color: Canvas;
color: CanvasText;
}
.smbk-slider__lines {
background-color: Highlight;
color: HighlightText;
}
.smbk-slider__thumb {
border-color: Canvas;
background: CanvasText;
}
.smbk-slider__rail:has(.smbk-slider__control:disabled) .smbk-slider__track {
color: GrayText;
}
.smbk-slider__rail:has(.smbk-slider__control:disabled) .smbk-slider__lines {
background-color: GrayText;
color: Canvas;
}
.smbk-slider__thumb:has(+ .smbk-slider__control:disabled) {
background: GrayText;
}
.smbk-slider:has(.smbk-slider__control:disabled) :is(.smbk-slider__label, .smbk-slider__value, .smbk-slider__bounds) {
color: GrayText;
}
/* The standard line in CanvasText; the fill bar's edge in CanvasText; in both, the part up to the
thumb in Highlight, and the fill look's handle in HighlightText on it. */
.smbk-slider--look-standard .smbk-slider__track {
background-color: CanvasText;
}
.smbk-slider--look-fill .smbk-slider__track,
.smbk-slider--look-contained .smbk-slider__track {
border: var(--smbk-border-width-hairline) solid CanvasText;
}
.smbk-slider--look-standard .smbk-slider__fill,
.smbk-slider--look-fill .smbk-slider__fill,
.smbk-slider--look-contained .smbk-slider__fill {
forced-color-adjust: none;
background-color: Highlight;
}
:is(.smbk-slider--look-fill, .smbk-slider--look-contained) .smbk-slider__thumb,
:is(.smbk-slider--look-fill, .smbk-slider--look-contained) .smbk-slider__thumb:is(:hover, :active, [data-pressed], :has(+ .smbk-slider__control:is(:hover, :active, :focus-visible))) {
forced-color-adjust: none;
background: HighlightText;
}
:is(.smbk-slider--look-fill, .smbk-slider--look-contained) .smbk-slider__rail:has(.smbk-slider__control:focus-visible) .smbk-slider__track {
outline-color: Highlight;
}
.smbk-slider--look-standard .smbk-slider__rail:has(.smbk-slider__control:disabled) .smbk-slider__track,
.smbk-slider--look-standard .smbk-slider__rail:has(.smbk-slider__control:disabled) .smbk-slider__fill,
:is(.smbk-slider--look-fill, .smbk-slider--look-contained) .smbk-slider__rail:has(.smbk-slider__control:disabled) .smbk-slider__fill {
background-color: GrayText;
}
:is(.smbk-slider--look-fill, .smbk-slider--look-contained) .smbk-slider__thumb:has(+ .smbk-slider__control:disabled) {
background: Canvas;
}
/* The contained look's words on the part up to the thumb, in HighlightText on it, or Canvas on GrayText. */
.smbk-slider--look-contained .smbk-slider__fill > .smbk-slider__header {
color: HighlightText;
}
.smbk-slider--look-contained:has(.smbk-slider__control:disabled) .smbk-slider__fill > .smbk-slider__header > :is(.smbk-slider__label, .smbk-slider__value) {
color: Canvas;
}
/* The marks are a background image, which forced colors would drop. */
.smbk-slider__marks {
forced-color-adjust: none;
color: CanvasText;
}
.smbk-slider:has(.smbk-slider__control:disabled) .smbk-slider__marks {
color: GrayText;
}
}Tokens it reads
| Token and CSS | Value | Preview | Foundation |
|---|---|---|---|
| space.stack.sm--smbk-space-stack-sm | comfortable: 8pxcompact: 6pxchanges with density | Spacing | |
| space.inline.md--smbk-space-inline-md | comfortable: 8pxcompact: 6pxchanges with density | Spacing | |
| color.text.default--smbk-color-text-default | light: #232527dark: #e7ebf0changes with theme | Color | |
| typography.body-xs--smbk-typography-body-xs-font-family--smbk-typography-body-xs-font-size--smbk-typography-body-xs-font-weight--smbk-typography-body-xs-line-height--smbk-typography-body-xs-letter-spacing--smbk-typography-body-xs-text-transform | fontFamily: Geist, Geist Fallback, system-ui, sans-seriffontSize: 12pxfontWeight: 400lineHeight: 1.5letterSpacing: 0px | The quick brown fox | Typography |
| space.stack.xs--smbk-space-stack-xs | 4px | Spacing | |
| size.target.min--smbk-size-target-min | 24px | Size | |
| size.icon.md--smbk-size-icon-md | 20px | Size | |
| border-width.hairline--smbk-border-width-hairline | 1px | Border width | |
| color.border.control--smbk-color-border-control | #7c8692 | Color | |
| color.surface.sunken--smbk-color-surface-sunken | light: #373d430ddark: #00000066changes with theme | Color | |
| color.border.brand--smbk-color-border-brand | #cc0d0d | Color | |
| size.8--smbk-size-8 | 8px | Size | |
| size.selection.lg--smbk-size-selection-lg | 24px | Size | |
| color.border.rim-subtle--smbk-color-border-rim-subtle | light: #ffffff33dark: #ffffff08changes with theme | Color | |
| radius.full--smbk-radius-full | 9999px | Radius | |
| color.surface.brand--smbk-color-surface-brand | #cc0d0d | Color | |
| elevation.control--smbk-elevation-control | light: 0px 0px 1px 0px #373d430d, 0px 1px 2px 0px #373d431a, 0px 2px 4px 0px #373d430ddark: 0px 0px 1px 0px #0000001a, 0px 1px 2px 0px #00000026, 0px 2px 4px 0px #0000001a | Elevation | |
| size.icon.xs--smbk-size-icon-xs | 12px | Size | |
| size.icon.sm--smbk-size-icon-sm | 16px | Size | |
| size.selection.md--smbk-size-selection-md | 20px | Size | |
| size.6--smbk-size-6 | 6px | Size | |
| size.selection.sm--smbk-size-selection-sm | 16px | Size | |
| size.4--smbk-size-4 | 4px | Size | |
| color.action.brand.background--smbk-color-action-brand-background | #cc0d0d | Color | |
| space.inline.xs--smbk-space-inline-xs | 4px | Spacing | |
| radius.control.sm--smbk-radius-control-sm | 4px | Radius | |
| color.surface.neutral-subtle--smbk-color-surface-neutral-subtle | light: #373d431adark: #606a7533changes with theme | Color | |
| size.16--smbk-size-16 | 16px | Size | |
| color.action.brand.foreground--smbk-color-action-brand-foreground | #f9fafb | Color | |
| size.12--smbk-size-12 | 12px | Size | |
| size.control.lg--smbk-size-control-lg | comfortable: 48pxcompact: 40pxchanges with density | Size | |
| space.inset.2xl--smbk-space-inset-2xl | comfortable: 24pxcompact: 16pxchanges with density | Spacing | |
| radius.control.lg--smbk-radius-control-lg | 8px | Radius | |
| space.inline.sm--smbk-space-inline-sm | comfortable: 6pxcompact: 4pxchanges with density | Spacing | |
| size.control.md--smbk-size-control-md | comfortable: 40pxcompact: 32pxchanges with density | Size | |
| space.inset.xl--smbk-space-inset-xl | comfortable: 16pxcompact: 12pxchanges with density | Spacing | |
| radius.control.md--smbk-radius-control-md | 6px | Radius | |
| size.control.sm--smbk-size-control-sm | comfortable: 32pxcompact: 28pxchanges with density | Size | |
| space.inset.lg--smbk-space-inset-lg | comfortable: 12pxcompact: 8pxchanges with density | Spacing | |
| space.inset.xs--smbk-space-inset-xs | 4px | Spacing | |
| color.text.on-brand--smbk-color-text-on-brand | #f9fafb | Color | |
| typography.label-lg--smbk-typography-label-lg-font-family--smbk-typography-label-lg-font-size--smbk-typography-label-lg-font-weight--smbk-typography-label-lg-line-height--smbk-typography-label-lg-letter-spacing--smbk-typography-label-lg-text-transform | fontFamily: Geist, Geist Fallback, system-ui, sans-seriffontSize: 16pxfontWeight: 500lineHeight: 1.4letterSpacing: 0px | The quick brown fox | Typography |
| typography.body-md--smbk-typography-body-md-font-family--smbk-typography-body-md-font-size--smbk-typography-body-md-font-weight--smbk-typography-body-md-line-height--smbk-typography-body-md-letter-spacing--smbk-typography-body-md-text-transform | fontFamily: Geist, Geist Fallback, system-ui, sans-seriffontSize: 16pxfontWeight: 400lineHeight: 1.5letterSpacing: 0px | The quick brown fox | Typography |
| typography.label-md--smbk-typography-label-md-font-family--smbk-typography-label-md-font-size--smbk-typography-label-md-font-weight--smbk-typography-label-md-line-height--smbk-typography-label-md-letter-spacing--smbk-typography-label-md-text-transform | fontFamily: Geist, Geist Fallback, system-ui, sans-seriffontSize: 14pxfontWeight: 500lineHeight: 1.4letterSpacing: 0px | The quick brown fox | Typography |
| typography.body-sm--smbk-typography-body-sm-font-family--smbk-typography-body-sm-font-size--smbk-typography-body-sm-font-weight--smbk-typography-body-sm-line-height--smbk-typography-body-sm-letter-spacing--smbk-typography-body-sm-text-transform | fontFamily: Geist, Geist Fallback, system-ui, sans-seriffontSize: 14pxfontWeight: 400lineHeight: 1.5letterSpacing: 0px | The quick brown fox | Typography |
| color.action.brand.background-hover--smbk-color-action-brand-background-hover | #a51d17 | Color | |
| elevation.raised--smbk-elevation-raised | light: 0px 2px 8px 1px #373d431a, 0px 1px 2px 0px #373d431adark: 0px 2px 8px 1px #00000026, 0px 1px 2px 0px #00000026 | Elevation | |
| color.action.brand.background-pressed--smbk-color-action-brand-background-pressed | #761812 | Color | |
| elevation.raised-strong--smbk-elevation-raised-strong | light: 0px 4px 16px 1px #373d431a, 0px 2px 4px 0px #373d431adark: 0px 4px 16px 1px #00000026, 0px 2px 4px 0px #00000026 | Elevation | |
| focus.ring.width--smbk-focus-ring-width | 2px | Focus | |
| focus.ring.offset--smbk-focus-ring-offset | 2px | Focus | |
| color.surface.canvas--smbk-color-surface-canvas | light: #e7ebf0dark: #111213changes with theme | Color | |
| color.border.focus--smbk-color-border-focus | light: #cc0d0ddark: #f34336changes with theme | Color | |
| color.border.subtle--smbk-color-border-subtle | light: #c4cdd8dark: #2d3237changes with theme | Color | |
| color.icon.disabled--smbk-color-icon-disabled | light: #9ba5b1dark: #606a75changes with theme | Color | |
| color.border.control-disabled--smbk-color-border-control-disabled | light: #c4cdd8dark: #606a75changes with theme | Color | |
| color.action.disabled.foreground--smbk-color-action-disabled-foreground | light: #7c8692dark: #606a75changes with theme | Color | |
| color.surface.track-subtle--smbk-color-surface-track-subtle | light: #c4cdd8dark: #2d3237changes with theme | Color | |
| color.text.inverse--smbk-color-text-inverse | light: #f9fafbdark: #232527changes with theme | Color | |
| color.text.disabled--smbk-color-text-disabled | light: #7c8692dark: #606a75changes with theme | Color | |
| color.text.subtlest--smbk-color-text-subtlest | light: #606a75dark: #7c8692changes with theme | Color | |
| size.64--smbk-size-64 | 64px | Size | |
| size.target.comfortable--smbk-size-target-comfortable | 44px | Size | |
| motion.state.duration--smbk-motion-state-duration | 200ms | Motion | |
| motion.state.easing--smbk-motion-state-easing | cubic-bezier(0.65, 0, 0.35, 1) | Motion | |
| motion.feedback.duration--smbk-motion-feedback-duration | 150ms | Motion | |
| motion.feedback.easing--smbk-motion-feedback-easing | cubic-bezier(0.16, 1, 0.3, 1) | Motion |
Manifest
{
"name": "slider",
"block": "smbk-slider",
"summary": "Chooses a number, or a lowest and highest number, along a range by dragging, clicking or the arrow keys: fine lines that turn red up to a narrow thumb, a thin line with a round thumb, a filled bar, or a tall filled bar with its label and value inside; a number box beside it takes a typed value.",
"adapt": "css",
"axes": {
"look": {
"values": [
"ticks",
"standard",
"fill",
"contained"
],
"default": "ticks",
"description": "Ticks: a row of fine lines on a sunken band that turn red up to a narrow thumb. Standard: a thin rounded line, red up to a round thumb. Fill: a thick bar filled red up to a thin light handle, with optional marks between the lowest and highest values. Contained: the filled bar as tall as a control of its size, the label at its start and the value at its end inside it, white where the red passes under them. Figma: Style=Ticks, Standard, Fill, Contained, Ticks the default."
},
"size": {
"values": [
"lg",
"md",
"sm"
],
"default": "lg",
"description": "The thumb and the line or bar: the ticks thumb is the selection size tall, the round thumb the icon size across, the fill bar the selection size tall, the contained bar the control size tall. The row that takes the pointer stays at least the smallest touch size at every size. Figma: lg, md, sm, lg the default."
},
"type": {
"values": [
"single",
"range"
],
"default": "single",
"description": "One value, red from the start up to the thumb; or a range, two thumbs that stop when they meet and red between them. Figma: Type=Single, Range."
}
},
"flags": {},
"parts": [
"header",
"label",
"value",
"row",
"number",
"body",
"rail",
"track",
"fill",
"lines",
"thumb",
"bubble",
"control",
"bounds",
"marks"
],
"figmaNodeId": "4711:52100"
}