Как сделать так, чтобы ввод диапазона HTML5 имел разный цвет до и после слайдера?

93

введите описание изображения здесь

Я хочу, чтобы левая сторона была зеленой, а правая - серой. Как на картинке выше было бы ИДЕАЛЬНО. Предпочтительно решение на чистом CSS (нужно беспокоиться только о WebKit).

Возможно ли такое?

Шамун
источник
Наверное, что пробовали? Разместите свой код здесь.
j08691

Ответы:

118

Решение на чистом CSS :

  • Chrome: скройте переполнение input[range]и заполните все пространство слева до большого пальца цветом тени.
  • IE: не нужно изобретать велосипед:::-ms-fill-lower
  • Firefox не нужно изобретать велосипед:::-moz-range-progress

/*Chrome*/
@media screen and (-webkit-min-device-pixel-ratio:0) {
    input[type='range'] {
      overflow: hidden;
      width: 80px;
      -webkit-appearance: none;
      background-color: #9a905d;
    }
    
    input[type='range']::-webkit-slider-runnable-track {
      height: 10px;
      -webkit-appearance: none;
      color: #13bba4;
      margin-top: -1px;
    }
    
    input[type='range']::-webkit-slider-thumb {
      width: 10px;
      -webkit-appearance: none;
      height: 10px;
      cursor: ew-resize;
      background: #434343;
      box-shadow: -80px 0 0 80px #43e5f7;
    }

}
/** FF*/
input[type="range"]::-moz-range-progress {
  background-color: #43e5f7; 
}
input[type="range"]::-moz-range-track {  
  background-color: #9a905d;
}
/* IE*/
input[type="range"]::-ms-fill-lower {
  background-color: #43e5f7; 
}
input[type="range"]::-ms-fill-upper {  
  background-color: #9a905d;
}
<input type="range"/>

deathangel908
источник
1
Привет, deathangel908, хорошее решение. Я бы просто улучшил часть тени блока: box-shadow: -80px 0 0px 80px # 43e5f7;
Филип Витковски,
32
Проблема с этим в Chrome заключается в том, что если вы хотите, чтобы ползунок был больше дорожки, тогда тень блока перекрывала дорожку с высотой большого пальца. Есть ли способ ограничить тень блока внутри дорожки?
mharris7190
1
Это не работает для входов с шириной в процентах. У кого-нибудь есть обходной путь?
Remi Sture
2
Рабочую версию CSS / JS можно найти здесь: jsfiddle.net/remisture/esyvws3d
Реми Стуре
3
@tenwest Вау, это ужасно. Спасибо за обновления!
CodeF0x
50

Хотя принятый ответ теоретически хорош, он игнорирует тот факт, что большой палец не может быть больше размера дорожки без того, чтобы его не отрубил overflow: hidden. Посмотрите этот пример того, как справиться с этим с помощью небольшого кусочка JS.

// .chrome styling Vanilla JS

document.getElementById("myinput").oninput = function() {
  this.style.background = 'linear-gradient(to right, #82CFD0 0%, #82CFD0 ' + this.value + '%, #fff ' + this.value + '%, white 100%)'
};
#myinput {
  background: linear-gradient(to right, #82CFD0 0%, #82CFD0 50%, #fff 50%, #fff 100%);
  border: solid 1px #82CFD0;
  border-radius: 8px;
  height: 7px;
  width: 356px;
  outline: none;
  transition: background 450ms ease-in;
  -webkit-appearance: none;
}
<div class="chrome">
  <input id="myinput" type="range" value="50" />
</div>

dargue3
источник
Можете
@Husna Я расширил этот ответ, чтобы также обрабатывать атрибуты min max, надеюсь, это поможет.
htmn
1
@Husna Вы должны рассчитать% как разницу между вашим максимальным и минимальным значением. Например, если у вас есть min: 0 и max: 10, вы должны использовать в JS :,+ this.value / (10-0)*100 +'%, #fff
Розарио Руссо
4
@Rosario Russo Вам просто нужно заменить this.value в JS с помощью(this.value-this.min)/(this.max-this.min)*100
Silvan
29

Да, это возможно. Хотя я бы не рекомендовал это, потому чтоinput range самом деле не поддерживается должным образом всеми браузерами, потому что в HTML5 добавлен новый элемент, а HTML5 - это только черновик (и будет надолго), поэтому до стилизации, возможно, не лучший выбор.

Также вам понадобится немного JavaScript. Я взял на себя смелость использовать для этого библиотеку jQuery , для простоты.

Вот и все: http://jsfiddle.net/JnrvG/1/ .

Federico-T
источник
8
Вопрос не в том, что мне нужно делать с помощью css, способ должен быть только с css.
Ipad
10
Вы можете заставить его работать в Chrome без JS ( jsfiddle.net/1xg1j3tw ). Для IE10 + вы можете использовать псевдоэлементы -ms-fill-lower и -ms-fill-upper.
Алес
1
@Ales Вы должны добавить это в дополнительный ответ.
Лука Стиб
4
Измените .change(на, on('input', func..чтобы фон изменился, когда пользователь перемещает большой палец, а не только мышь вверх.
Ями Одымель
10

Небольшое обновление к этому:

если вы используете следующее, он будет обновляться на лету, а не при отпускании мыши.

"изменить движение мыши", функция "

<script>
$('input[type="range"]').on("change mousemove", function () {
    var val = ($(this).val() - $(this).attr('min')) / ($(this).attr('max') - $(this).attr('min'));

    $(this).css('background-image',
                '-webkit-gradient(linear, left top, right top, '
                + 'color-stop(' + val + ', #2f466b), '
                + 'color-stop(' + val + ', #d3d3db)'
                + ')'
                );
});</script>
Джеймс Паркер
источник
7

Основываясь на ответе @ dargue3 , если вы хотите, чтобы ползунок был больше, чем дорожка, вы хотите полностью использовать преимущества <input type="range" />элемента и перейти на кросс-браузер, вам нужно немного дополнительных строк JS и CSS.

В Chrome / Mozilla вы можете использовать linear-gradientтехнику, но вам нужно настроить соотношение , основываясь на min, max, valueатрибуты , как упомянуто здесь по @Attila О. . Вам необходимо убедиться, что вы не применяете это в Edge, иначе большой палец не будет отображаться. @Geoffrey Lalloué объясняет это более подробно здесь .

Еще одна вещь, о которой стоит упомянуть, это то, что вам нужно настроить файл rangeEl.style.height = "20px";IE / Older. Проще говоря, это потому, что в этом случае «высота применяется не к дорожке, а ко всему вводу, включая большой палец». скрипка

/**
 * Sniffs for Older Edge or IE,
 * more info here:
 * https://stackoverflow.com/q/31721250/3528132
 */
function isOlderEdgeOrIE() {
  return (
    window.navigator.userAgent.indexOf("MSIE ") > -1 ||
    !!navigator.userAgent.match(/Trident.*rv\:11\./) ||
    window.navigator.userAgent.indexOf("Edge") > -1
  );
}

function valueTotalRatio(value, min, max) {
  return ((value - min) / (max - min)).toFixed(2);
}

function getLinearGradientCSS(ratio, leftColor, rightColor) {
  return [
    '-webkit-gradient(',
    'linear, ',
    'left top, ',
    'right top, ',
    'color-stop(' + ratio + ', ' + leftColor + '), ',
    'color-stop(' + ratio + ', ' + rightColor + ')',
    ')'
  ].join('');
}

function updateRangeEl(rangeEl) {
  var ratio = valueTotalRatio(rangeEl.value, rangeEl.min, rangeEl.max);

  rangeEl.style.backgroundImage = getLinearGradientCSS(ratio, '#919e4b', '#c5c5c5');
}

function initRangeEl() {
  var rangeEl = document.querySelector('input[type=range]');
  var textEl = document.querySelector('input[type=text]');

  /**
   * IE/Older Edge FIX
   * On IE/Older Edge the height of the <input type="range" />
   * is the whole element as oposed to Chrome/Moz
   * where the height is applied to the track.
   *
   */
  if (isOlderEdgeOrIE()) {
    rangeEl.style.height = "20px";
    // IE 11/10 fires change instead of input
    // https://stackoverflow.com/a/50887531/3528132
    rangeEl.addEventListener("change", function(e) {
      textEl.value = e.target.value;
    });
    rangeEl.addEventListener("input", function(e) {
      textEl.value = e.target.value;
    });
  } else {
    updateRangeEl(rangeEl);
    rangeEl.addEventListener("input", function(e) {
      updateRangeEl(e.target);
      textEl.value = e.target.value;
    });
  }
}

initRangeEl();
input[type="range"] {
  -webkit-appearance: none;
  -moz-appearance: none;
  width: 300px;
  height: 5px;
  padding: 0;
  border-radius: 2px;
  outline: none;
  cursor: pointer;
}


/*Chrome thumb*/

input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  -moz-appearance: none;
  -webkit-border-radius: 5px;
  /*16x16px adjusted to be same as 14x14px on moz*/
  height: 16px;
  width: 16px;
  border-radius: 5px;
  background: #e7e7e7;
  border: 1px solid #c5c5c5;
}


/*Mozilla thumb*/

input[type="range"]::-moz-range-thumb {
  -webkit-appearance: none;
  -moz-appearance: none;
  -moz-border-radius: 5px;
  height: 14px;
  width: 14px;
  border-radius: 5px;
  background: #e7e7e7;
  border: 1px solid #c5c5c5;
}


/*IE & Edge input*/

input[type=range]::-ms-track {
  width: 300px;
  height: 6px;
  /*remove bg colour from the track, we'll use ms-fill-lower and ms-fill-upper instead */
  background: transparent;
  /*leave room for the larger thumb to overflow with a transparent border */
  border-color: transparent;
  border-width: 2px 0;
  /*remove default tick marks*/
  color: transparent;
}


/*IE & Edge thumb*/

input[type=range]::-ms-thumb {
  height: 14px;
  width: 14px;
  border-radius: 5px;
  background: #e7e7e7;
  border: 1px solid #c5c5c5;
}


/*IE & Edge left side*/

input[type=range]::-ms-fill-lower {
  background: #919e4b;
  border-radius: 2px;
}


/*IE & Edge right side*/

input[type=range]::-ms-fill-upper {
  background: #c5c5c5;
  border-radius: 2px;
}


/*IE disable tooltip*/

input[type=range]::-ms-tooltip {
  display: none;
}

input[type="text"] {
  border: none;
}
<input type="range" value="80" min="10" max="100" step="1" />
<input type="text" value="80" size="3" />

htmn
источник
5

Предыдущее принятое решение больше не работает .

Я закончил тем, что написал простую функцию, которая помещает rangeв стилизованный контейнер, добавляя полосу, которая необходима перед курсором. Я написал этот пример, где легко увидеть два цвета - синий и оранжевый, установленные в CSS, поэтому их можно быстро изменить.

Fedeghe
источник
1

Если вы используете первый ответ , проблема с большим пальцем. В хроме, если вы хотите, чтобы ползунок был больше, чем дорожка , тень блока перекрывает дорожку с высотой ползунка.

Просто суммируйте все эти ответы и напишите нормально рабочий слайдер с большим пальцем ползунка: jsfiddle

const slider = document.getElementById("myinput")
const min = slider.min
const max = slider.max
const value = slider.value

slider.style.background = `linear-gradient(to right, red 0%, red ${(value-min)/(max-min)*100}%, #DEE2E6 ${(value-min)/(max-min)*100}%, #DEE2E6 100%)`

slider.oninput = function() {
  this.style.background = `linear-gradient(to right, red 0%, red ${(this.value-this.min)/(this.max-this.min)*100}%, #DEE2E6 ${(this.value-this.min)/(this.max-this.min)*100}%, #DEE2E6 100%)`
};
#myinput {
  border-radius: 8px;
  height: 4px;
  width: 150px;
  outline: none;
  -webkit-appearance: none;
}

input[type='range']::-webkit-slider-thumb {
  width: 6px;
  -webkit-appearance: none;
  height: 12px;
  background: black;
  border-radius: 2px;
}
<div class="chrome">
  <input id="myinput" type="range" min="0" value="25" max="200" />
</div>

Абдигали
источник
0

Теперь он поддерживается с псевдоэлементами в каждом из WebKit, Firefox и IE. Но, конечно, в каждом он разный. : (

Просмотрите ответы на этот вопрос и / или найдите CodePen с названием prettify <input type=range> #101для некоторых решений.

Уилсон Ф
источник
-5
input type="range" min="0" max="50" value="0"  style="margin-left: 6%;width: 88%;background-color: whitesmoke;"

приведенный выше код изменяет стиль ввода диапазона .....

Криш
источник
Работает в FireFox 57, но не в Opera 49 или Safari 11 - хуже того, ничего не поддерживает цвет переднего плана.
девон