<input type="range"> #
::: section-content
<input>
elements of type range
let the user specify a
numeric value which must be no less than a given value, and no more than
another given value. The precise value, however, is not considered
important. This is typically represented using a slider or dial control
rather than a text entry box like the
number input type.
Because this kind of widget is imprecise, it should only be used if the control's exact value isn't important. :::
Try it #
::: section-content ::: iframe ::: {.output-header .border-rounded-top}
HTML Demo: <input type="range"> #
Reset :::
::: {#warning-no-script .warning-container} ::: warning The interactive example cannot be shown because JavaScript is disabled. ::: :::
::: {#warning-mathml-not-supported .warning-container .hidden} ::: warning The interactive example cannot be shown because MathML is not supported by your browser. ::: :::
::: {#editor-container .editor-container .tabbed-standard .hidden .border-rounded-bottom editor-type=“tabbed”} ::: {#tab-container .section .tabs} ::: {#tablist .tab-list role=“tablist”} HTML
CSS
JavaScript :::
::: {#html-panel .section .hidden tabindex=“0” role=“tabpanel” aria-labelledby=“html” aria-hidden=“true”} ::: {#html-editor}
Audio settings:
<input type="range" id="volume" name="volume" min="0" max="11" />
<label for="volume">Volume</label>
<input type="range" id="cowbell" name="cowbell" min="0" max="100" value="90" step="10" />
<label for="cowbell">Cowbell</label>
::: :::
::: {#css-panel .section .hidden tabindex=“0” role=“tabpanel” aria-labelledby=“css” aria-hidden=“true”} ::: {#css-editor} p, label { font: 1rem ‘Fira Sans’, sans-serif; }
input {
margin: 0.4rem;
}
::: :::
::: {#js-panel .section .hidden tabindex=“0” role=“tabpanel” aria-labelledby=“js” aria-hidden=“true”} ::: {#js-editor} ::: ::: :::
::: {#output .output-container}
Output #
::: :::
::: {.section .console-container .hidden aria-hidden=“true”}
Console Output #
![] clear console
::: {#console .console} ::: :::
::: {#html-output .output .editor-tabbed} %html-content% ::: :::
If the user's browser doesn't support type range
, it will fall back
and treat it as a
text
input.
:::
Validation #
::: section-content There is no pattern validation available; however, the following forms of automatic validation are performed:
- If the
value
is set to something which can't be converted into a valid floating-point number, validation fails because the input is suffering from a bad input. - The value won't be less than
min
. The default is 0. - The value won't be greater than
max
. The default is 100. - The value will be a multiple of
step
. The default is 1. :::
Value #
::: section-content
The
value
attribute contains a string which contains
a string representation of the selected number. The value is never an
empty string (""
). The default value is halfway between the specified
minimum and maximum—unless the maximum is actually less than the
minimum, in which case the default is set to the value of the min
attribute. The algorithm for determining the default value is:
::: code-example [js]{.language-name}
defaultValue =
rangeElem.max < rangeElem.min
? rangeElem.min
: rangeElem.min + (rangeElem.max - rangeElem.min) / 2;
:::
If an attempt is made to set the value lower than the minimum, it is set to the minimum. Similarly, an attempt to set the value higher than the maximum results in it being set to the maximum. :::
Additional attributes #
::: section-content
In addition to the attributes shared by all
<input>
elements, range inputs offer the following attributes.
:::
list #
::: section-content
The value of the list
attribute is the
id
of a
<datalist>
element located in the same document. The
<datalist>
provides a list of predefined values to
suggest to the user for this input. Any values in the list that are not
compatible with the
type
are not included in the
suggested options. The values provided are suggestions, not
requirements: users can select from this predefined list or provide a
different value.
See the adding tick marks below for an example of how the options on a range are denoted in supported browsers. :::
max #
::: section-content
The greatest value in the range of permitted values. If the
value
entered into the element exceeds this, the
element fails
constraint validation. If
the value of the
max
attribute isn't a
number, then the element has no maximum value.
This value must be greater than or equal to the value of the
min
attribute. See the HTML
max
attribute.
:::
min #
::: section-content
The lowest value in the range of permitted values. If the
value
of the element is less than this, the element
fails
constraint validation. If a value
is specified for min
that isn't a valid number, the input has no
minimum value.
This value must be less than or equal to the value of the
max
attribute. See the HTML
min
attribute.
::: {#sect1 .notecard .note}
Note: If the min
and max
values are equal or the max
value is
lower than the min
value the user will not be able to interact with
the range.
:::
:::
step #
::: section-content
The step
attribute is a number that specifies the granularity that the
value must adhere to. Only values that match the specified stepping
interval (
min
if specified,
value
otherwise, or an appropriate default value if neither of those is
provided) are valid.
The step
attribute can also be set to the any
string value. This
step
value means that no stepping interval is implied and any value is
allowed in the specified range (barring other constraints, such as
min
and
max
). See the
Setting step to the any
value example for how this works in
supported browsers.
::: {#sect2 .notecard .note} Note: When the value entered by a user doesn't adhere to the stepping configuration, the user agent may round off the value to the nearest valid value, preferring to round numbers up when there are two equally close options. :::
The default stepping value for range
inputs is 1, allowing only
integers to be entered, unless the stepping base is not an integer;
for example, if you set min
to -10 and value
to 1.5, then a step
of 1 will allow only values such as 1.5, 2.5, 3.5,… in the positive
direction and -0.5, -1.5, -2.5,… in the negative direction. See the
HTML step
attribute.
:::
Non-standard Attributes #
orient #
::: section-content
Similar to the -moz-orient non-standard CSS property impacting the
<progress>
and
<meter>
elements, the
orient
attribute defines the orientation of the range slider. Values
include horizontal
, meaning the range is rendered horizontally, and
vertical
, where the range is rendered vertically.
::: {#sect3 .notecard .note}
Note: The following input attributes do not apply to the input
range: accept
, alt
, checked
, dirname
, formaction
,
formenctype
, formmethod
, formnovalidate
, formtarget
, height
,
maxlength
, minlength
, multiple
, pattern
, placeholder
,
readonly
, required
, size
, and src
. Any of these attributes, if
included, will be ignored.
:::
:::
Examples #
::: section-content
While the number
type lets users enter a number with optional
constraints forcing their value to be between a minimum and a maximum
value, it does require that they enter a specific value. The range
input type lets you ask the user for a value in cases where the user may
not even care—or know—what the specific numeric value selected is.
A few examples of situations in which range inputs are commonly used:
- Audio controls such as volume and balance, or filter controls.
- Color configuration controls such as color channels, transparency, brightness, etc.
- Game configuration controls such as difficulty, visibility distance, world size, and so forth.
- Password length for a password manager's generated passwords.
As a rule, if the user is more likely to be interested in the percentage of the distance between minimum and maximum values than the actual number itself, a range input is a great candidate. For example, in the case of a home stereo volume control, users typically think "set volume at halfway to maximum" instead of "set volume to 0.5". :::
Specifying the minimum and maximum #
::: section-content
By default, the minimum is 0 and the maximum is 100. If that's not what
you want, you can easily specify different bounds by changing the values
of the
min
and/or
max
attributes.
These can be any floating-point value.
For example, to ask the user for a value between -10 and 10, you can use:
::: code-example [html]{.language-name}
<input type="range" min="-10" max="10" />
:::
::: {#sect4 .code-example} ::: iframe ::: ::: :::
Setting the value's granularity #
::: section-content
By default, the granularity is 1, meaning the value is always an
integer. To control the granularity, you can change the
step
attribute. For example, If you need a value to
be halfway between 5 and 10, you should set the value of step
to 0.5:
Setting the step attribute #
::: code-example [html]{.language-name}
<input type="range" min="5" max="10" step="0.5" />
:::
::: {#sect5 .code-example} ::: iframe ::: :::
Setting step to "any" #
If you want to accept any value regardless of how many decimal places it
extends to, you can specify a value of any
for the
step
attribute:
HTML #
::: code-example [html]{.language-name}
<input id="pi_input" type="range" min="0" max="3.14" step="any" />
<p>Value: <output id="value"></output></p>
:::
JavaScript #
::: code-example [js]{.language-name}
const value = document.querySelector("#value");
const input = document.querySelector("#pi_input");
value.textContent = input.value;
input.addEventListener("input", (event) => {
value.textContent = event.target.value;
});
:::
::: {#sect6 .code-example} ::: iframe ::: :::
This example lets the user select any value between 0 and π without any restriction on the fractional part of the value selected. JavaScript is used to show how the value changes as the user interacts with the range. :::
Adding tick marks #
::: section-content
To add tick marks to a range control, include the list
attribute,
giving it the id
of a
<datalist>
element which
defines a series of tick marks on the control. Each point is represented
using an
<option>
element with its
value
set to the range's value at which a mark
should be drawn.
HTML #
::: code-example [html]{.language-name}
<label for="temp">Choose a comfortable temperature:</label><br />
<input type="range" id="temp" name="temp" list="markers" />
<datalist id="markers">
<option value="0"></option>
<option value="25"></option>
<option value="50"></option>
<option value="75"></option>
<option value="100"></option>
</datalist>
:::
Result #
::: {#sect7 .code-example} ::: iframe ::: ::: :::
Using the same datalist for multiple range controls #
::: section-content
To help you from repeating code you can reuse that same
<datalist>
for multiple <input type="range">
elements, and other
<input>
types.
::: {#sect8 .notecard .note}
Note: If you also want to
show the labels as in
the example below then you would need a datalist
for each range input.
:::
HTML #
::: code-example [html]{.language-name}
<p>
<label for="temp1">Temperature for room 1:</label>
<input type="range" id="temp1" name="temp1" list="values" />
</p>
<p>
<label for="temp2">Temperature for room 2:</label>
<input type="range" id="temp2" name="temp2" list="values" />
</p>
<p>
<label for="temp3">Temperature for room 3:</label>
<input type="range" id="temp3" name="temp3" list="values" />
</p>
<datalist id="values">
<option value="0" label="0"></option>
<option value="25" label="25"></option>
<option value="50" label="50"></option>
<option value="75" label="75"></option>
<option value="100" label="100"></option>
</datalist>
:::
Result #
::: {#sect9 .code-example} ::: iframe ::: ::: :::
Adding labels #
::: section-content
You can label tick marks by giving the <option>
elements label
attributes. However, the label content will not be displayed by default.
You can use CSS to show the labels and to position them correctly.
Here's one way you could do this.
HTML #
::: code-example [html]{.language-name}
<label for="tempB">Choose a comfortable temperature:</label><br />
<input type="range" id="tempB" name="temp" list="values" />
<datalist id="values">
<option value="0" label="very cold!"></option>
<option value="25" label="cool"></option>
<option value="50" label="medium"></option>
<option value="75" label="getting warm!"></option>
<option value="100" label="hot!"></option>
</datalist>
:::
CSS #
::: code-example [css]{.language-name}
datalist {
display: flex;
flex-direction: column;
justify-content: space-between;
writing-mode: vertical-lr;
width: 200px;
}
option {
padding: 0;
}
input[type="range"] {
width: 200px;
margin: 0;
}
:::
Result #
::: {#sect10 .code-example} ::: iframe ::: ::: :::
Creating vertical range controls #
::: section-content By default, browsers render range inputs as sliders with the knob sliding left and right.
To create a vertical range, wherein the knob slides up and down, set the
CSS
appearance
property to slider-vertical
and include the non-standard orient
attribute for Firefox.
Horizontal range control #
Consider this range control:
::: code-example [html]{.language-name}
<input type="range" id="volume" min="0" max="11" value="7" step="1" />
:::
::: {#sect11 .code-example} ::: iframe ::: :::
This control is horizontal (at least on most if not all major browsers; others might vary).
Using the appearance property #
The
appearance
property has a non-standard value of slider-vertical
that, well, makes
sliders vertical.
We use the same HTML as in the previous examples:
::: code-example [html]{.language-name}
<input type="range" min="0" max="11" value="7" step="1" />
:::
We target just the inputs with a type of range:
::: code-example [css]{.language-name}
input[type="range"] {
appearance: slider-vertical;
}
:::
::: {#sect12 .code-example} ::: iframe ::: :::
Using the orient attribute #
In Firefox only, there is a non-standard orient
property.
Use similar HTML as in the previous examples, we add the attribute with
a value of vertical
:
::: code-example [html]{.language-name}
<input type="range" min="0" max="11" value="7" step="1" orient="vertical" />
:::
::: {#sect13 .code-example} ::: iframe ::: :::
writing-mode: bt-lr #
The
writing-mode
property should generally not be used to alter text direction for
internationalization or localization purposes, but can be used for
special effects.
We use the same HTML as in the previous examples:
::: code-example [html]{.language-name}
<input type="range" min="0" max="11" value="7" step="1" />
:::
We target just the inputs with a type of range, changing the writing
mode from the default to bt-lr
, or bottom-to-top and left-to-right:
::: code-example [css]{.language-name}
input[type="range"] {
writing-mode: bt-lr;
}
:::
::: {#sect14 .code-example} ::: iframe ::: :::
Putting it all together #
As each of the above examples works in different browsers, you can put all of them in a single example to make it work cross browser:
We keep the orient
attribute with a value of vertical
for Firefox:
::: code-example [html]{.language-name}
<input type="range" min="0" max="11" value="7" step="1" orient="vertical" />
:::
We target just the input
s with a type
of range
and orient
set to
vertical
, changing the writing-mode
from the default to bt-lr
, or
bottom-to-top and left-to-right, for pre-Blink versions of Edge, and add
appearance: slider-vertical
which is supported in Blink and Webkit
browsers:
::: code-example [css]{.language-name}
input[type="range"][orient="vertical"] {
writing-mode: bt-lr;
appearance: slider-vertical;
}
:::
::: {#sect15 .code-example} ::: iframe ::: ::: :::
Technical summary #
::: section-content
Value | A string containing the string representation of the selected
numeric value; use valueAsNumber to get the
value as a number. |
Events | change
and input |
Supported common attributes | autocomplete , list , max , min , and step |
IDL attributes | list , value , and
valueAsNumber |
DOM interface | |
Methods | stepDown()
and stepUp() |
Implicit ARIA Role | slider |
Specifications #
::: _table #
Specification #
HTML Standard
[#
range-state-(type=range)]{.small}
:::
Browser compatibility #
::: _table #
Desktop Mobile
Chrome Edge Firefox Internet Explorer Opera Safari WebView Android Chrome Android Firefox Opera Android Safari on IOS Samsung Internet
for
Android
range
4 12 23 10 11 3.1 4.4 57 52 11 5 7.0
2--4.4
Pre-Chromium Android WebView recognizes
the `range` type, but doesn\'t
implement a range-specific control.
tick_marks
Yes ≤79 109 No Yes 12.1 Yes Yes 109 Yes 12.2 Yes
vertical_orientation
Yes 12 No 10 Yes Yes Yes Yes No Yes Yes Yes
The slider can be oriented vertically The slider can be The slider can be The slider can be oriented vertically The slider can be oriented vertically The slider can be oriented vertically The slider can be oriented vertically The slider can be oriented vertically The slider can be oriented vertically The slider can be oriented vertically
by setting the non-standard oriented vertically by oriented vertically by by setting the non-standard by setting the non-standard by setting the non-standard by setting the non-standard by setting the non-standard by setting the non-standard by setting the non-standard
`-webkit-appearance: slider-vertical` setting the setting the `-webkit-appearance: slider-vertical` `-webkit-appearance: slider-vertical` `-webkit-appearance: slider-vertical` `-webkit-appearance: slider-vertical` `-webkit-appearance: slider-vertical` `-webkit-appearance: slider-vertical` `-webkit-appearance: slider-vertical`
style on the `input` element. You `writing-mode: bt-lr` `writing-mode: bt-lr` style on the `input` element. You style on the `input` element. You style on the `input` element. You style on the `input` element. You style on the `input` element. You style on the `input` element. You style on the `input` element. You
shouldn\'t use this, since it\'s style on the `input` style on the `input` shouldn\'t use this, since it\'s shouldn\'t use this, since it\'s shouldn\'t use this, since it\'s shouldn\'t use this, since it\'s shouldn\'t use this, since it\'s shouldn\'t use this, since it\'s shouldn\'t use this, since it\'s
proprietary, unless you include element. element. proprietary, unless you include proprietary, unless you include proprietary, unless you include proprietary, unless you include proprietary, unless you include proprietary, unless you include proprietary, unless you include
appropriate fallbacks for users of appropriate fallbacks for users of appropriate fallbacks for users of appropriate fallbacks for users of appropriate fallbacks for users of appropriate fallbacks for users of appropriate fallbacks for users of appropriate fallbacks for users of
other browsers. other browsers. other browsers. other browsers. other browsers. other browsers. other browsers. other browsers.
:::
See also #
::: section-content
- HTML Forms
<input>
and theHTMLInputElement
interface it's based upon<input type="number">
validityState.rangeOverflow
andvalidityState.rangeUnderflow
- Controlling multiple parameters with ConstantSourceNode
- Styling the range element{target="_blank"}
- Compatibility of CSS properties :::
::: _attribution
© 2005–2023 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5
or later.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/range{._attribution-link}
:::