如何正确 trim CSS 中输入范围轨道的边缘?
How to properly trim the edge of an input range track in CSS?
我正在尝试构建一个与此类似的滑块组件:
但是为了达到预期的效果,滑块拇指不会超出线条的边缘。
所以我用 width: calc(80% + 30px);
添加了一点额外的宽度,其中 30px 是拇指的宽度,并给我提供了拇指宽度的一半的悬垂。
但是当我尝试将可见轨道裁剪到 clip-path: polygon(15px -1000%, calc(100% - 15px) -1000%, calc(100% - 15px) 1000%, 15px 1000%);
的大小时,它也会裁剪拇指。
有没有办法在不剪切拇指的情况下正确剪切轨道?
这是我的代码(组织为 .svelte 组件)。
<script>
export let name;
let value = 3;
</script>
<style>
input[type=range] {
appearance: none;
position: relative;
background-color: #b3b3b3;
width: calc(80% + 30px);
height: 2px;
padding: 0;
top: -22px;
clip-path: polygon(15px -1000%, calc(100% - 15px) -1000%, calc(100% - 15px) 1000%, 15px 1000%);
border: none;
}
input[type=range]::-webkit-slider-thumb {
appearance: none;
width: 30px;
height: 30px;
border-radius: 50%;
background: yellowgreen;
}
span {
margin-left: calc(10% - 8px);
margin-right: calc(10% - 8px);
float: left;
width: 16px;
height: 16px;
padding: 0;
background: #b3b3b3;
border-radius: 50%;
}
.tick-container {
height: 16px;
padding: 0;
justify-content: left;
}
</style>
<h2>{name}</h2>
<div class="tick-container">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<input on:input={slider => value = slider.target.value} type="range" min="1" max="5" value={value}>
我可能会单独绘制凹槽而不是尝试让它像这样工作。
还有:
- 您可以
bind
输入 value
。
- 有一个容器元素用于指示整体大小会很有帮助
- Flexbox 结合
justify-content: space-between
可以轻松地 space 从一端到另一端的刻度。
- 我会尽量避免使用特定大小并尽可能使用百分比来减少依赖性。
这样一个滑块组件的草图:
<script>
export let value = 3;
</script>
<style>
.slider {
position: relative;
width: 300px;
height: 30px;
}
.track {
margin: auto;
width: calc(100% - 30px + 16px);
position: relative;
padding: 0;
top: 50%;
transform: translateY(-50%);
}
.ticks {
display: flex;
justify-content: space-between;
}
.tick {
width: 16px;
height: 16px;
background: #b3b3b3;
border-radius: 50%;
}
.groove {
height: 2px;
background: #b3b3b3;
position: absolute;
width: calc(100% - 16px);
left: 8px;
top: 50%;
transform: translateY(-50%);
}
input {
position: absolute;
appearance: none;
background: none;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
top: 0;
left: 0;
border: none;
}
input::-webkit-slider-thumb {
appearance: none;
width: 30px;
height: 30px;
border-radius: 50%;
background: yellowgreen;
}
</style>
<div class="slider">
<div class="track">
<div class="groove"></div>
<div class="ticks">
<span class="tick"></span>
<span class="tick"></span>
<span class="tick"></span>
<span class="tick"></span>
<span class="tick"></span>
</div>
</div>
<input type="range" min="1" max="5" bind:value>
</div>
这还可以improved/extended:
- 导出
min
/max
并通过 {#each}
生成报价
- 为刻度线和拇指colors/sizes使用自定义属性
- 与其他浏览器兼容(
::-webkit-slider-thumb
是 non-standard)
我正在尝试构建一个与此类似的滑块组件:
但是为了达到预期的效果,滑块拇指不会超出线条的边缘。
所以我用 width: calc(80% + 30px);
添加了一点额外的宽度,其中 30px 是拇指的宽度,并给我提供了拇指宽度的一半的悬垂。
但是当我尝试将可见轨道裁剪到 clip-path: polygon(15px -1000%, calc(100% - 15px) -1000%, calc(100% - 15px) 1000%, 15px 1000%);
的大小时,它也会裁剪拇指。
有没有办法在不剪切拇指的情况下正确剪切轨道?
这是我的代码(组织为 .svelte 组件)。
<script>
export let name;
let value = 3;
</script>
<style>
input[type=range] {
appearance: none;
position: relative;
background-color: #b3b3b3;
width: calc(80% + 30px);
height: 2px;
padding: 0;
top: -22px;
clip-path: polygon(15px -1000%, calc(100% - 15px) -1000%, calc(100% - 15px) 1000%, 15px 1000%);
border: none;
}
input[type=range]::-webkit-slider-thumb {
appearance: none;
width: 30px;
height: 30px;
border-radius: 50%;
background: yellowgreen;
}
span {
margin-left: calc(10% - 8px);
margin-right: calc(10% - 8px);
float: left;
width: 16px;
height: 16px;
padding: 0;
background: #b3b3b3;
border-radius: 50%;
}
.tick-container {
height: 16px;
padding: 0;
justify-content: left;
}
</style>
<h2>{name}</h2>
<div class="tick-container">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<input on:input={slider => value = slider.target.value} type="range" min="1" max="5" value={value}>
我可能会单独绘制凹槽而不是尝试让它像这样工作。
还有:
- 您可以
bind
输入value
。 - 有一个容器元素用于指示整体大小会很有帮助
- Flexbox 结合
justify-content: space-between
可以轻松地 space 从一端到另一端的刻度。 - 我会尽量避免使用特定大小并尽可能使用百分比来减少依赖性。
这样一个滑块组件的草图:
<script>
export let value = 3;
</script>
<style>
.slider {
position: relative;
width: 300px;
height: 30px;
}
.track {
margin: auto;
width: calc(100% - 30px + 16px);
position: relative;
padding: 0;
top: 50%;
transform: translateY(-50%);
}
.ticks {
display: flex;
justify-content: space-between;
}
.tick {
width: 16px;
height: 16px;
background: #b3b3b3;
border-radius: 50%;
}
.groove {
height: 2px;
background: #b3b3b3;
position: absolute;
width: calc(100% - 16px);
left: 8px;
top: 50%;
transform: translateY(-50%);
}
input {
position: absolute;
appearance: none;
background: none;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
top: 0;
left: 0;
border: none;
}
input::-webkit-slider-thumb {
appearance: none;
width: 30px;
height: 30px;
border-radius: 50%;
background: yellowgreen;
}
</style>
<div class="slider">
<div class="track">
<div class="groove"></div>
<div class="ticks">
<span class="tick"></span>
<span class="tick"></span>
<span class="tick"></span>
<span class="tick"></span>
<span class="tick"></span>
</div>
</div>
<input type="range" min="1" max="5" bind:value>
</div>
这还可以improved/extended:
- 导出
min
/max
并通过{#each}
生成报价
- 为刻度线和拇指colors/sizes使用自定义属性
- 与其他浏览器兼容(
::-webkit-slider-thumb
是 non-standard)