【问题标题】:Styling input range for webkit with pure CSS使用纯 CSS 为 webkit 设置输入范围
【发布时间】:2016-04-23 08:44:36
【问题描述】:

我想自定义输入类型范围,例如this

我尝试使用以下代码更改拇指,如下所示,但所选范围颜色没有更改。

HTML

<input type="range" />

CSS

input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none;
  height: 20px;
  width: 20px;
  border-radius: 10px;
  background: red;
  cursor: pointer;
  border: none;
  margin-top: -8px;
}

input[type=range] {
  -webkit-appearance: none;
  outline: 0;
  margin: 0;
  padding: 0;
  height: 30px;
  width: 100%;
}

有人可以建议我更改选定的可运行轨道背景颜色吗?

【问题讨论】:

  • 纯 CSS 解决方案可以在这里找到:stackoverflow.com/a/38163892 特别是,它使用 box-shadow 来模拟 Chrome 中轨道上的颜色分割。

标签: css html pseudo-element input-type-range


【解决方案1】:

Ionic 框架正在使用有趣的方法来仅使用 CSS 设置范围输入轨道的样式。他们正在向::-webkit-slider-thumb 添加一个::before 伪元素,使其尽可能宽,然后将其定位在轨道顶部。 (我无法让 border-radius 使用它。)

input[type='range'] {
  width: 210px;
  height: 30px;
  overflow: hidden;
  cursor: pointer;
}
input[type='range'],
input[type='range']::-webkit-slider-runnable-track,
input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none;
}
input[type='range']::-webkit-slider-runnable-track {
  width: 200px;
  height: 10px;
  background: #AAA;
}
input[type='range']::-webkit-slider-thumb {
  position: relative;
  height: 30px;
  width: 30px;
  margin-top: -10px;
  background: steelblue;
  border-radius: 50%;
  border: 2px solid white;
}
input[type='range']::-webkit-slider-thumb::before {
  position: absolute;
  content: '';
  height: 10px; /* equal to height of runnable track */
  width: 500px; /* make this bigger than the widest range input element */
  left: -502px; /* this should be -2px - width */
  top: 8px; /* don't change this */
  background: #777;
}
<div class="container">
  <input type="range" min="0" max="100" value="10" />
</div>

据我所知,对于 Webkit 驱动的浏览器(和 FF),没有纯 CSS 方法可以做到这一点。 IE 提供了一种使用 -ms-fill-lower-ms-fill-upper 设置轨道两部分样式的方法,但 WebKit 中没有等效项,因此需要 JavaScript。

您可以使用linear-gradient 作为可运行轨道的背景图像,然后使用JavaScript 更改background-size 以达到所需的效果。由于问题是针对 Webkit 的,所以提供的 sn-p 目前仅适用于 Webkit 驱动的浏览器。这个方法确实允许我们在轨道上添加一个border-radius

这个 sn-p 改编自 Ana Tudor 的 CodePen Demo。该演示有办法使其在其他浏览器中也能正常工作。

window.onload = function() {
  var input = document.querySelector('input[type=range]'),
    style_el = document.createElement('style'),
    styles = [],
    track_sel = ['::-webkit-slider-runnable-track'];
  document.body.appendChild(style_el);

  styles.push('');

  input.addEventListener('input', function() {
    var min = this.min || 0,
      max = this.max || 100,
      c_style, u, edge_w, val, str = '';

    this.setAttribute('value', this.value);

    val = this.value + '% 100%';
    str += 'input[type="range"]' + track_sel[0] + '{background-size:' + val + '}';

    styles[0] = str;
    style_el.textContent = styles.join('');
  }, false);
}
input[type='range'] {
  width: 210px;
  height: 50px;
  cursor: pointer;
}
input[type='range'],
input[type='range']::-webkit-slider-runnable-track,
input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none;
}
input[type='range']::-webkit-slider-runnable-track {
  width: 200px;
  height: 10px;
  background: linear-gradient(to right, #777, #777), #AAA;
  background-size: 10% 100%;
  background-repeat: no-repeat;
  border-radius: 5px;
}
input[type='range']::-webkit-slider-thumb {
  height: 30px;
  width: 30px;
  margin-top: -10px;
  background: steelblue;
  border-radius: 50%;
  border: 2px solid white;
}
<div class="container">
  <input type="range" min="0" max="100" value="10" />
</div>

【讨论】:

  • 是的,使用 JS 我们有多种方式。最简单的方法是使用 oninput 方法调用 $('input:range').css('background', 'linear-gradient(to right, red, #005555 ' +val + '%, blue)') 。但我只需要用 CSS 来做到这一点。像 input::-webkit-slider-thumb:after 和 before 方法
  • 抱歉,我没有注意到标题中的 pure CSS 位。但是对于 Webkit 驱动的浏览器,没有办法使用纯 CSS 来做到这一点。 IE,我认为有一个上限和一个下限来设置轨道的两个部分,但 Webkit(和 FF)没有。
  • 你检查过离子范围控制吗:ionicframework.com/docs/components/#range。它仅通过 CSS 实现
  • @Ponmalar:我会看看它,但我猜他们一定在使用 JS(用于跨浏览器)。您可能还想看看这篇文章 - hongkiat.com/blog/html5-range-slider-style
  • 为什么这不适用于 safari 浏览器?只需在 Safari 中运行此代码 sn-p 即可重现此问题。
【解决方案2】:

我得到了一个不使用样式标签但使用css variable的解决方案:

const input = document.querySelector("input");

function setBackgroundSize(input) {
  input.style.setProperty("--background-size", `${getBackgroundSize(input)}%`);
}

setBackgroundSize(input);

input.addEventListener("input", () => setBackgroundSize(input));

function getBackgroundSize(input) {
  const min = +input.min || 0;
  const max = +input.max || 100;
  const value = +input.value;

  const size = (value - min) / (max - min) * 100;

  return size;
}
input[type='range'] {
  width: 400px;
}

input[type='range'],
input[type='range']::-webkit-slider-runnable-track,
input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none;
}

input[type='range']::-webkit-slider-runnable-track {
  height: 3px;
  background: linear-gradient(to right, #293043, #293043), #D7D7D7;
  background-size: var(--background-size, 0%) 100%;
  background-repeat: no-repeat;
  border-radius: 5px;

}

input[type='range']::-webkit-slider-thumb {
  width: 15px;
  height: 15px;
  cursor: pointer;
  background: #293043;
  border: solid white 1px;
  border-radius: 50%;
  margin-top: -6px;
  box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.4);
}

/** FF*/

input[type="range"]::-moz-range-progress {
  background-color: #293043;
  border-radius: 5px;
}

input[type="range"]::-moz-range-track {
  background-color: #D7D7D7;
  border-radius: 5px;
}

input[type="range"]::-moz-range-thumb {
  width: 15px;
  height: 15px;
  cursor: pointer;
  background: #293043;
  border: solid white 1px;
  border-radius: 50%;
  margin-top: -6px;
  box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.4);
}
&lt;input type="range" min="5" max="95" step="1" value="15"&gt;

这适用于 Chrome 和 Firefox :)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 2015-12-14
    • 2012-01-02
    • 2013-10-13
    • 1970-01-01
    • 2021-08-14
    • 1970-01-01
    相关资源
    最近更新 更多