Why Range Inputs Look Different Everywhere

The HTML range input is one of the more frustrating elements to style. Every major browser renders it with its own default look — different track heights, thumb sizes, backgrounds, and alignment. Getting a consistent appearance across Chrome, Firefox, Safari, and Edge requires targeting vendor-specific pseudo-elements and resetting browser defaults.

A range input (often called a slider) has two structural parts:

  • Track — the long bar that represents the selectable value range.
  • Thumb — the draggable knob that moves along the track.
A range input is comprised of a track and thumb.
A range input is comprised of a track and thumb. (Large preview)

As of September 2021, the default rendered output differs noticeably across the four major browsers. Chrome shows a blue thumb and a two-tone track. Firefox renders a slightly shorter track with a larger, borderless thumb. Safari’s version has a shadowed track and a smaller thumb that is not vertically centered. Edge, now Chromium-based, closely resembles Chrome but uses a darker grey thumb and track fill.

Resetting The Baseline

Before applying any custom styles, you need to strip away the default appearance that each browser applies. The reset relies on four properties:

  1. -webkit-appearance: none; — a vendor prefix that clears the input’s default rendering across all major browsers.
  2. background: transparent; — removes the default background.
  3. cursor: pointer; — provides a clear affordance for interactivity.
  4. width — defines the overall width of the input.
input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  cursor: pointer;
  width: 15rem;
}

Once these baseline styles are applied, the slider will have no visible track or thumb. From that clean slate, you can rebuild the component with your own styles.

Styling The Track

The track must be targeted separately for WebKit-based browsers (Chrome, Safari, Opera, Edge Chromium) and for Firefox. The relevant pseudo-elements are:

  • ::-webkit-slider-runnable-track — applies to the track in Chrome, Safari, and Edge Chromium.
  • ::-moz-range-track — applies to the track in Firefox.
Range Input in Firefox after the track styles have been applied.
Range Input in Firefox after the track styles have been applied. (Large preview)

The only required properties are height and background. A border-radius is commonly added to round the track’s edges.

Styling The Thumb

The thumb requires more attention because browser inconsistencies are more pronounced here. The pseudo-elements to target are:

  • ::-webkit-slider-thumb — for Chrome, Safari, and Edge Chromium.
  • ::-moz-range-thumb — for Firefox.

Each browser family has its own quirks that need separate handling.

WebKit Browsers

The first step for ::-webkit-slider-thumb is to apply -webkit-appearance: none; to remove default styling. After that, you can set your own height, width, and background-color.

Range input in Chrome with custom thumb styles.
Range input in Chrome with custom thumb styles. (Large preview)

WebKit browsers do not center the thumb on the track by default. To fix this, apply a negative top margin using this formula:

margin-top = (track height / 2) - (thumb height / 2)

For example, with a track height of 8px and a thumb height of 32px:

margin-top = (8/2) - (32/2) = 4 - 16 = -12px

The resulting margin-top value is applied alongside the custom thumb styles.

/***** Thumb Styles *****/
/***** Chrome, Safari, Opera, and Edge Chromium *****/
input[type="range"]::-webkit-slider-thumb {
   -webkit-appearance: none; /* Override default look */
   appearance: none;
   margin-top: -12px; /* Centers thumb on the track */
   background-color: #5cd5eb;
   height: 2rem;
   width: 1rem;    
}

Firefox

Firefox does not have the same centering problem, but it applies a default grey border and border-radius to the thumb. To neutralize those, add:

  • border: none; — removes the grey border.
  • border-radius: 0; — removes the default rounding.

Note that WebKit browsers do not apply a default border-radius to the thumb. If you want a rounded knob, you will need to set the border-radius explicitly on both the -webkit-slider-thumb and ::-moz-range-thumb pseudo-elements.

/***** Thumb Styles *****/
/***** Firefox *****/
input[type="range"]::-moz-range-thumb {
    border: none; /*Removes extra border that FF applies*/
    border-radius: 0; /*Removes default border-radius that FF applies*/
    background-color: #5cd5eb;
    height: 2rem;
    width: 1rem;
}

Accessible Focus States

Because the range input is interactive, focus styles are required for accessibility. The WAI-ARIA slider pattern recommends placing focus on the thumb itself.

Start by removing the default focus indicator, then apply your own styles using the :focus pseudo-class combined with the thumb pseudo-elements. The outline and outline-offset properties give you control over the visual indicator.

/***** Focus Styles *****/
/* Removes default focus */
input[type="range"]:focus {
  outline: none;
}

/***** Chrome, Safari, Opera, and Edge Chromium *****/
input[type="range"]:focus::-webkit-slider-thumb {
  border: 1px solid #053a5f;
  outline: 3px solid #053a5f;
  outline-offset: 0.125rem;
}

/******** Firefox ********/
input[type="range"]:focus::-moz-range-thumb {
  border: 1px solid #053a5f;
  outline: 3px solid #053a5f;
  outline-offset: 0.125rem;     
}

One remaining inconsistency: if a border-radius is applied to the thumb, Firefox will render the outline following the thumb’s rounded shape, while WebKit browsers display a rectangular outline. There is no simple CSS workaround for this difference, but the outline still serves its accessibility purpose in both cases.

Range Input in Chrome with custom focus styles applied.
Range Input in Chrome with custom focus styles applied. (Large preview)

Complete Stylesheet

Combining the reset, track styles, thumb styles, and focus rules produces a final stylesheet that renders consistently across Chrome, Safari, Firefox, and Edge Chromium.

/********** Range Input Styles **********/
/*Range Reset*/
input[type="range"] {
   -webkit-appearance: none;
    appearance: none;
    background: transparent;
    cursor: pointer;
    width: 15rem;
}

/* Removes default focus */
input[type="range"]:focus {
  outline: none;
}

/***** Chrome, Safari, Opera and Edge Chromium styles *****/
/* slider track */
input[type="range"]::-webkit-slider-runnable-track {
   background-color: #053a5f;
   border-radius: 0.5rem;
   height: 0.5rem;  
}

/* slider thumb */
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; /* Override default look */
   appearance: none;
   margin-top: -12px; /* Centers thumb on the track */

   /*custom styles*/
   background-color: #5cd5eb;
   height: 2rem;
   width: 1rem;
}

input[type="range"]:focus::-webkit-slider-thumb {   
  border: 1px solid #053a5f;
  outline: 3px solid #053a5f;
  outline-offset: 0.125rem; 
}

/******** Firefox styles ********/
/* slider track */
input[type="range"]::-moz-range-track {
   background-color: #053a5f;
   border-radius: 0.5rem;
   height: 0.5rem;
}

/* slider thumb */
input[type="range"]::-moz-range-thumb {
   border: none; /*Removes extra border that FF applies*/
   border-radius: 0; /*Removes default border-radius that FF applies*/

   /*custom styles*/
   background-color: #5cd5eb;
   height: 2rem;
   width: 1rem;
}

input[type="range"]:focus::-moz-range-thumb {
  border: 1px solid #053a5f;
  outline: 3px solid #053a5f;
  outline-offset: 0.125rem; 
}

For quicker experimentation, a range input CSS generator called range-input.css provides a visual interface for styling common properties with a live preview. As browser support for styling form controls evolves, these manual workarounds may eventually become unnecessary — but for now, knowing the correct pseudo-elements and vendor prefixes remains essential for building polished sliders.