Ticks for type=”range” HTML input

Input ranges are still a bit of a nightmarish hack when it comes to styling. That said, displaying tickmarks on major browsers is possible, with a bit of elbow grease and browser-specific solutions.


Internet Explorer / Edge

As you seem to be aware, Internet Explorer will show ticks by default if you add the HTML step attribute. In a weird twist of events, Internet Explorer and Edge are arguably the most flexible browser when it comes to styling input ranges.

<input type="range" min="0" max="100" step="25">

Chrome / Safari

In Chrome and other Webkit browsers (including Safari), you can use the datalist element to provide a custom set of tick locations on the slider. While all major browsers support this element, Firefox (and other Gecko browsers) won’t show visible tick marks.

<input type="range" min="0" max="100" step="25" list="steplist">
<datalist id="steplist">
    <option>0</option>
    <option>25</option>
    <option>50</option>
    <option>75</option>
    <option>100</option>
</datalist>

Firefox

In Firefox and other Gecko-based browsers, we’ll need to use some vendor-specific CSS to add the tick marks. You’ll have to customize this to whatever looks the most natural to you. In this example, I’ve used a horizontal repeating gradient to add “vertical stripes” that look like tick marks, but you could also use a background image, or any other style you want. You could even use a bit of Javascript to load information from the datalist element, then generate an appropriate gradient and apply it to the element so that it all happens automatically, and so it can support custom arbitrary stops.

input[type="range"]::-moz-range-track {
  padding: 0 10px;
  background: repeating-linear-gradient(to right, 
    #ccc, 
    #ccc 10%, 
    #000 10%, 
    #000 11%, 
    #ccc 11%, 
    #ccc 20%);
}
<input type="range" min="0" max="100" step="25" list="steplist">
<datalist id="steplist">
    <option>0</option>
    <option>25</option>
    <option>50</option>
    <option>75</option>
    <option>100</option>
</datalist>

Compatibility notes: As pointed out in the comments, datalist is not supported by some browsers. Depending on how those browsers handle unsupported / unrecognized elements, this may result in the browsers displaying the option values as plain text below your range input. If targeting the widest possible range of browsers is important to you, this may be a problem.

One solution is to use the awkward repeating-linear-gradient kludge for webkit browsers in addition to gecko browsers, and then remove the datalist entirely.

Another solution would be to use CSS to explicitly set the datalist to display: none. This solution is probably the most preferable, as you aren’t compromising features to provide legacy support.

Leave a Comment