我需要创建一个科学输入滑块。更准确地说:
模型:
注:
这不是 Ticks for type="range" HTML input 因为这 3 点。
浏览器支持:至少 Chrome
以下代码生成一个带刻度的 HTML 滑块,并且可以正常工作。但是,它不符合上述第二个和第三个标准。
input { width: 400px; }
<input type=range min=0 max=200 value=0 step=1 list=tickmarks>
<datalist id=tickmarks>
<option>0</option>
<option>20</option>
<option>40</option>
<option>60</option>
<option>80</option>
<option>100</option>
<option>120</option>
<option>140</option>
<option>160</option>
<option>180</option>
<option>200</option>
</datalist>
是否有 HTML
<input type="range">
的属性来启用这些“数字标记”刻度?
满足所有三个标准的实现是否可行?
您可以通过将 div 放在您划分为多个部分的范围下方来实现此目的。下面的代码只是一个概念验证,它已经可以工作了,但是当你真正将它集成到你的项目中时,你将需要使其可重用和可调整。
window.addEventListener("load", function() {
let div = document.getElementById("ranger-div");
let html = [];
for (let i = 0; i <= 200; i += 20) {
html.push(`<div><div style="with:100%;">|</div>${i}</div>`);
}
div.innerHTML = html.join("");
});
.ranger { width: 400px; }
#ranger-div {display: inline-flex; width: 440px;}
#ranger-div > div {
color: red;
width: 100%;
}
<input class="ranger" type=range min=0 max=200 value=0 step=1>
<div id="ranger-div"></div>
正如 Lajos Arpad 的回答所示,最好避免使用
datalist
,因为您的要求超出了它的能力范围。您需要手动创建带有数值的刻度。
以下代码使用与您问题中的原始代码相似的 HTML 布局,并具有适合的样式。请注意,宽度是在父元素上设置的,如果父元素太小,则刻度号将换行。为了解决这个问题,您可能需要减小刻度号的字体大小。
#input {
width: 400px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
#input input {
width: 100%;
margin: 0 10px;
position: relative;
z-index: 10;
}
#input span {
position: relative;
margin: 20px -5px 0 -5px;
flex-basis: 0;
flex-grow: 1;
text-align: center;
font-size: 0.85em;
user-select: none;
}
#input span::after {
content: "";
position: absolute;
width: 1px;
height: 15px;
left: 0;
right: 0;
margin: auto;
top: -20px;
background-color: #ccc;
}
<div id="input">
<input type=range min=0 max=200 value=0 step=1>
<span>0</span>
<span>20</span>
<span>40</span>
<span>60</span>
<span>80</span>
<span>100</span>
<span>120</span>
<span>140</span>
<span>160</span>
<span>180</span>
<span>200</span>
</div>
您可以使用带有
datalist
列表的 option
,但它需要您添加 label
文本,因为 value
不会用作刻度值。
通用设置(MDN:输入类型=“范围”,添加刻度线)
<input type="range" list="tickmark-list">
<datalist id="tickmark-list">
<option value=1 label="1"/>
<option value=N label="N"/>
</datalist>
对于标签,您有两种选择:
选项 1:使用
label
和文本
<option value="1" label="tickmark-value-1"/>
<option value="N" label="tickmark-value-N"/>
选项2:使用选项文本
<option value="1">tickmark-value-1</option>
<option value="N">tickmark-value-N</option>
同时使用
label
文本和选项文本时,后者将被忽略。对于我使用的片段 option 1.
刻度线
input type="range"
和 datalist
必须有相等的 width
。在代码片段中,我使用 CSS 自定义属性 --slider-width: 100%
来设置任一元素的宽度。datalist
作为带有 justify-content: space-between
的 Flexbox 行容器非常适合分发刻度标签。它将外部标签推到它们各自父级的左右边缘,同时将其余标签均匀分布在剩余空间上。width
。在片段中,我取了标签的宽度200
.text-align: center
。根据使用的标签文本,可能需要对
margin/padding
和/或 option:first-child
进行一些摆弄。Bonus 在代码片段中我添加了类 option:last-child
以展示如何使用
.vertical
和 flex-direction: column
轻松获得 90 度旋转的刻度标签。
writing-mode: vertical-lr
:root { --slider-width: 100% }
input, datalist {
width: var(--slider-width);
}
datalist {
display: flex;
flex-direction: row;
justify-content: space-between;
}
option {
text-align: center;
width: 1.78rem; /* ~width of label '200' */
}
.vertical {
flex-direction: column;
writing-mode: vertical-lr;
}
input[list="tickmarks2"] { margin: 0 }
.vertical option { text-align: right; width: 1.5rem }