Winter
Winter

Reputation: 2517

styling input type range, height differences in different browsers

I'm trying to style an input of type "range" so that it looks the same in multiple browsers.

I've found some neat resources that I have used ...

https://css-tricks.com/styling-cross-browser-compatible-range-inputs-css/

http://danielstern.ca/range.css/#/

http://www.cssportal.com/style-input-range/

... but there is one issue that does not seem to be addressed. That is that Firefox and other browsers consider the height of the input to be the height of the of the track and the thumb combined (or something similar), however, Chrome seems to only consider the height of the track to be the height of the entire input.

This is my code (condensed):

.container {
  border: 1px solid red;
  background-color: lightgreen;
  margin-top: 10px;
}

p {
  border: 1px solid blue;
  margin: 0;
  padding: 0;
}

input[type=text],
input[type=range] {
  -webkit-appearance: none;
  width: 200px;
  margin: 0;
  padding: 0;
  display: block;
  height: 50px;
}

input[type=range]:focus {
  outline: none;
}

input[type=range]::-webkit-slider-runnable-track {
  width: 100%;
  height: 4px;
  cursor: pointer;
  animate: 0.2s;
  background: #ccc;
  border: 1px solid #333;
}

input[type=range]::-webkit-slider-thumb {
  border: 1px solid #333;
  height: 30px;
  width: 8px;
  background: #fff;
  -webkit-appearance: none;
  margin-top: -7px;
}

input[type=range]:focus::-webkit-slider-runnable-track {
  background: #367ebd;
}

input[type=range]::-moz-range-track {
  width: 100%;
  height: 4px;
  cursor: pointer;
  animate: 0.2s;
  background: #ccc;
  border: 1px solid #333;
}

input[type=range]::-moz-range-thumb {
  border: 1px solid #333;
  height: 30px;
  width: 6px;
  background: #fff;
}
<div class="container">
  <p>
    Some text...
  </p>
  <input type="range" />
  <p>
    Some more text...
  </p>
</div>

<div class="container">
  <input type="text">
</div>

If you run this in Chrome and Firefox you will see that the two browsers treat this differently. In Chrome the input gets a white background.

If I remove the height: 50px; on the input[type=range], there is also an obvious difference between the way the browsers treat the height.

As you can see, this affects how the tags above and after the range input are positioned relatively.

How do I work around this?

Upvotes: 3

Views: 11964

Answers (2)

cslotty
cslotty

Reputation: 1797

I like a mix of these three tutorials:

  1. https://www.smashingmagazine.com/2021/12/create-custom-range-input-consistent-browsers/ -> nice and precise
  2. https://css-tricks.com/styling-cross-browser-compatible-range-inputs-css/ -> thorough and great for understanding
  3. https://css-tricks.com/sliding-nightmare-understanding-range-input/ -> very thorough explanations

Important to know, IMHO, that in Firefox, the width of the range track depends on the font size!!

So this is my complete CSS section for range input (using some less):

/*range container element*/
.range-slider {
  position: relative;
  width: 120px;
  height: 4em;
  margin: auto;
  margin-bottom: 1em;
  text-align: center;
}

@track-color: @darkblue;
@track-width: 100%;
@track-height: 5px;
@track-radius: 5px;
@thumb-color: @darkblue;
@thumb-height: 20px;
@thumb-width: 10px;
@thumb-radius: 0;
@contrast: 15%;

.range-slider input[type="range"] {
  position: absolute;
  left: 0;
  bottom: 0;
  font-size: 10px; /* range width firefox!! */
}

.range-slider input[type="number"] {
  border: 1px solid @lightest-grey;
  text-align: center;
  font-size: 1.6em;
  -moz-appearance: textfield;
  appearance: textfield;
  width: 2em;
}

.range-slider input[type="number"]::-webkit-outer-spin-button,
.range-slider input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
}

.range-slider input[type="number"]:invalid,
.range-slider input[type="number"]:out-of-range {
  border: 2px solid red;
}

.range-slider input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  cursor: pointer;
}

/***** Track Styles *****/

/***** Chrome, Safari, Opera, and Edge Chromium *****/
input[type="range"]::-webkit-slider-runnable-track {
  background: @track-color;
  width: @track-width;
  height: @track-height;
  border-radius: @track-radius;
}

/******** Firefox ********/
input[type="range"]::-moz-range-track {
  background: @track-color;
  width: @track-width;
  height: @track-height;
  border-radius: @track-radius;
}

/***** Thumb Styles *****/

/***** Chrome, Safari, Opera, and Edge Chromium *****/
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; /* Override default look */
  appearance: none;
  margin-top: -7px; /* Centers thumb on the track */
  background-color: @thumb-color;
  height: @thumb-height;
  width: @thumb-width;
  border-radius: @thumb-radius;
}

/***** 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: @thumb-color;
  height: @thumb-height;
  width: @thumb-width;
  border-radius: @thumb-radius;
}

/***** Focus Styles *****/

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

/***** Chrome, Safari, Opera, and Edge Chromium *****/
input[type="range"]:focus::-webkit-slider-thumb {
  background: lighten(@thumb-color, @contrast);
}

/******** Firefox ********/
input[type="range"]:focus::-moz-range-thumb {
  background: lighten(@thumb-color, @contrast);
}

By using "position: relative" in the container, and "position: absolute" for the range input, we can also place two of the range sliders on top of each other, thus getting sliders for upper/lower limit.

Upvotes: 0

monikapatelIT
monikapatelIT

Reputation: 1007

Reference from css-tricks.com

Support Firefox 23+, Chrome 6+, IE 10+ as per testing

You have missed some CSS I have mention in comment

.container {
  border: 1px solid red;
  background-color: lightgreen;
  margin-top: 10px;
}
p {
  border: 1px solid blue;
  margin: 0;
  padding: 0;
}
input[type=text] {
  height: 50px;
}
input[type=text],
input[type=range] {
  -webkit-appearance: none;
  margin: 18px 0;
  width: 200px;
}
input[type=range]:focus {
  outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
  width: 100%;
  height: 8.4px;
  cursor: pointer;
  animate: 0.2s;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  background: #3071a9;
  border-radius: 1.3px;
  border: 0.2px solid #010101;
}
input[type=range]::-webkit-slider-thumb {
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  border: 1px solid #000000;
  height: 36px;
  width: 16px;
  border-radius: 3px;
  background: #ffffff;
  cursor: pointer;
  -webkit-appearance: none;
  margin-top: -14px;
}
input[type=range]:focus::-webkit-slider-runnable-track {
  background: #367ebd;
}
input[type=range]::-moz-range-track {
  width: 100%;
  height: 8.4px;
  cursor: pointer;
  animate: 0.2s;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  background: #3071a9;
  border-radius: 1.3px;
  border: 0.2px solid #010101;
}
input[type=range]::-moz-range-thumb {
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  border: 1px solid #000000;
  height: 36px;
  width: 16px;
  border-radius: 3px;
  background: #ffffff;
  cursor: pointer;
}

  /* CSS is missing in your code  */
input[type=range]::-ms-track {
  width: 100%;
  height: 8.4px;
  cursor: pointer;
  animate: 0.2s;
  background: transparent;
  border-color: transparent;
  border-width: 16px 0;
  color: transparent;
}
input[type=range]::-ms-fill-lower {
  background: #2a6495;
  border: 0.2px solid #010101;
  border-radius: 2.6px;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
}
input[type=range]::-ms-fill-upper {
  background: #3071a9;
  border: 0.2px solid #010101;
  border-radius: 2.6px;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
}
input[type=range]::-ms-thumb {
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  border: 1px solid #000000;
  height: 36px;
  width: 16px;
  border-radius: 3px;
  background: #ffffff;
  cursor: pointer;
}
input[type=range]:focus::-ms-fill-lower {
  background: #3071a9;
}
input[type=range]:focus::-ms-fill-upper {
  background: #367ebd;
}
<div class="container">
  <p>
    Some text...
  </p>
  <input type="range" />
  <p>
    Some more text...
  </p>
</div>

<div class="container">
  <input type="text">
</div>

Upvotes: 5

Related Questions