答案 0 :(得分:39)
在造型方面,输入范围仍然是一种噩梦般的黑客攻击。也就是说,在主要浏览器上显示勾选标记是可能的,只需要一些肘部润滑剂和浏览器特定的解决方案。
Internet Explorer / Edge
您似乎知道,如果您添加HTML step
属性,Internet Explorer将默认显示刻度。在一个奇怪的事件转折中,Internet Explorer和Edge可以说是设计输入范围时最灵活的浏览器。
<input type="range" min="0" max="100" step="25">
Chrome / Safari
在Chrome和其他Webkit浏览器(包括Safari)中,您可以使用datalist元素在滑块上提供一组自定义刻度位置。虽然所有主流浏览器都支持此元素,但Firefox(和其他Gecko浏览器)不会显示可见的刻度标记。
<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和其他基于Gecko的浏览器中,我们需要使用某些供应商特定的CSS来添加刻度线。您必须将其自定义为对您来说最自然的外观。在这个例子中,我使用水平重复渐变来添加看起来像刻度线的“垂直条纹”,但您也可以使用背景图像或任何其他您想要的样式。您甚至可以使用一些Javascript来加载来自datalist元素的信息,然后生成适当的渐变并将其应用于元素,以便它自动发生,因此它可以支持自定义任意停止。
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>
兼容性说明:正如评论中所指出的,数据主义者is not supported by some browsers。根据这些浏览器处理不支持/无法识别的元素的方式,这可能会导致浏览器在范围输入下显示选项值作为纯文本。如果定位最广泛的浏览器对您来说很重要,这可能是个问题。
一种解决方案是在gecko浏览器之外使用尴尬的repeating-linear-gradient
kludge for webkit浏览器,然后完全删除datalist。
另一种解决方案是使用CSS将数据列表显式设置为display: none
。此解决方案可能是最优选的,因为您不会牺牲功能来提供传统支持。
答案 1 :(得分:4)
您可以使用<datalist>
范围:
<input type="range" min="0" value="0" max="10" step="1" list="ticks">
<datalist id="ticks">
<option>0</option>
<option>2</option>
<option>4</option>
<option>6</option>
<option>8</option>
<option>10</option>
</datalist>
&#13;
答案 2 :(得分:2)
我希望这会帮助某人格式化FF下的刻度和数据列表。 要求选项之间有均匀的间距,并且输入+数据列表必须具有相同的宽度。
input[type="range"] {
width: 100%;
margin: 0;
box-sizing: border-box;
}
datalist {
display: flex;
width: 100%;
justify-content: space-between;
margin-top: -23px;
padding-top: 0px;
}
option {
width: 2ex;
display: flex;
justify-content: center;
height: 42px;
align-items: end;
background-image: url(tick.png);
height: 4ex;
background-position-y: -15px;
background-position-x: center;
z-index: -1;
}
答案 3 :(得分:0)
受user10452457's answer的启发,我创建了一种纠正数据列表元素间距的方法,尤其是当数据列表条目的长度变化时。缺点是您必须在其style
属性<datalist style="--list-length: XYZ;">...</datalist>
中指定数据列表的长度。如果创建数据列表时长度未知,则可以使用一些javascript更改此值。
此方法通过以某种方式拆分范围输入的宽度来工作,以使数据列表条目的文本居中在范围指针下方。第一个/最后一个数据列表条目与左/右对齐。此方法要求范围输入的width
为100%
,而margin-left
为0
。
当使用宽度为12px
的Firefox的默认缩略图时,以下css为数据列表设置样式,使其直接跟随范围输入。
/* style range */
input[type=range] {
width: 100%;
max-width: 100%;
margin-left: 0;
}
/* style datalist */
input[type=range] + datalist {
display: block;
margin-top: -4px;
}
input[type=range] + datalist option {
display: inline-block;
width: calc((100% - 12px) / (var(--list-length) - 1));
text-align: center;
}
input[type=range] + datalist option:first-child {
width: calc((100% - 12px) / ((var(--list-length) - 1) * 2) + 6px);
text-align: left;
}
input[type=range] + datalist option:last-child {
width: calc((100% - 12px) / ((var(--list-length) - 1) * 2) + 6px);
text-align: right;
}
<input type="range" min="1" max="9" id="my-range" list="my-datalist"/>
<datalist id="my-datalist" style="--list-length: 9;"><!--
---><option>1</option><!--
---><option>2</option><!--
---><option>3</option><!--
---><option>A</option><!--
---><option>B</option><!--
---><option>C</option><!--
---><option>Four</option><!--
---><option>Five</option><!--
---><option>Six</option><!--
---></datalist>
如果要对范围输入使用自定义样式,则可以使用以下样式。 --thumb-width
变量包含拇指的with,用于正确的计算。
// change thumb-width variable on input change
var tw = document.getElementById('thumb-width');
var mr = document.getElementById('my-range');
var ml = document.getElementById('my-datalist');
tw.onchange = () => {
mr.style.setProperty('--thumb-width', tw.value + 'px');
ml.style.setProperty('--thumb-width', tw.value + 'px');
}
/* set thumb width */
input[type=range], input[type=range] + datalist { --thumb-width: 8px; }
/* style range */
input[type=range] {
-webkit-appearance: none; /* hide track and thumb */
width: 100%;
max-width: 100%;
margin-left: 0;
}
/* style datalist */
input[type=range] + datalist {
display: block;
margin-top: -4px;
}
input[type=range] + datalist option {
display: inline-block;
width: calc((100% - var(--thumb-width)) / (var(--list-length) - 1));
text-align: center;
}
input[type=range] + datalist option:first-child {
width: calc((100% - var(--thumb-width)) / ((var(--list-length) - 1) * 2) + var(--thumb-width) / 2);
text-align: left;
}
input[type=range] + datalist option:last-child {
width: calc((100% - var(--thumb-width)) / ((var(--list-length) - 1) * 2) + var(--thumb-width) / 2);
text-align: right;
}
/* style Firefox range and thumb */
input[type=range]::-moz-range-track {
background: #eee;
cursor: pointer;
height: 2px;
border: 1px solid #888;
border-radius: 1px;
}
input[type=range]::-moz-range-thumb {
background: #eee;
box-sizing: border-box;
width: var(--thumb-width);
height: 20px;
cursor: pointer;
border: 1px solid #888;
border-radius: 3px;
}
/* style Chrome range and thumb */
input[type=range]::-webkit-slider-runnable-track {
background: #eee;
cursor: pointer;
height: 2px;
border: 1px solid #888;
border-radius: 1px;
}
input[type=range]::-webkit-slider-thumb {
background: #eee;
box-sizing: border-box;
width: var(--thumb-width);
height: 20px;
cursor: pointer;
border: 1px solid #888;
}
<label>Thumb width:</label>
<input type="number" id="thumb-width" min="4" max="60" step="4" value="10"/>
<br><br>
<input type="range" min="1" max="9" id="my-range" list="my-datalist"/>
<datalist id="my-datalist" style="--list-length: 9;"><!--
---><option>1</option><!--
---><option>2</option><!--
---><option>3</option><!--
---><option>A</option><!--
---><option>B</option><!--
---><option>C</option><!--
---><option>Four</option><!--
---><option>Five</option><!--
---><option>Six</option><!--
---></datalist>
答案 4 :(得分:0)
我已经开发了自己的轻量级组件,该组件仅通过使用CSS变量( AKA “自定义属性”)使用具有linear-gradient
background
属性的CSS来显示刻度。 / p>
不幸的是,需要一个wrapper元素,但这是我想出的最简单的HTML修改,它可以带来结果。
不幸的是,也需要范围输入的属性和托管变量的包装器元素的style
属性之间的手动同步。
body {
height: 100vh;
display: grid;
place-items: center;
}
.range {
--ticksThickness: 2px;
--ticksHeight: 30%;
--ticksColor: silver;
display: inline-block;
background: silver;
background: linear-gradient(to right, var(--ticksColor) var(--ticksThickness), transparent 1px) repeat-x;
background-size: calc(100%/((var(--max) - var(--min)) / var(--step)) - .1%) var(--ticksHeight);
background-position: 0 bottom;
position: relative;
}
/* min / max labels at the edges */
.range::before, .range::after {
font: 12px monospace;
content: counter(x);
position: absolute;
bottom: -2ch;
}
.range::before {
counter-reset: x var(--min);
transform: translateX(-50%);
}
.range::after {
counter-reset: x var(--max);
right: 0;
transform: translateX(50%);
}
.range > input {
width: 300px;
margin: 0 -6px; /* Critical adjustment */
}
<div class="range" style="--step:10; --min:20; --max:100">
<input type="range" min="20" max="100" step="10" value="30">
</div>