如何实现符合Figma设计稿要求的自定义Range Slider组件?
自定义Range Slider 精准还原实现方案
以下实现无第三方依赖,完全匹配设计稿的双滑块区间选择样式,支持鼠标/触控拖拽,自带选中值提示。
核心实现特性
- 视觉完全对齐设计:6px圆角轨道、蓝色选中态区间、22px圆形白边蓝框滑块、滑块阴影效果、顶部蓝色数值气泡
- 内置滑块最小间隔校验,避免两个滑块重叠错位
- 兼容PC端鼠标操作、移动端触控操作
- 样式、取值范围、最小间隔均可通过参数快速调整
完整实现代码
HTML结构
<div class="range-slider"> <div class="slider-track"> <div class="slider-range"></div> </div> <input type="range" min="0" max="100" value="20" class="slider-thumb thumb-min"> <input type="range" min="0" max="100" value="80" class="slider-thumb thumb-max"> <div class="value-tips"> <span class="tip-min"></span> <span class="tip-max"></span> </div> </div>
CSS样式
.range-slider { position: relative; width: 400px; height: 70px; padding: 30px 10px 0; box-sizing: border-box; } /* 底部灰色轨道 */ .slider-track { position: absolute; top: 35px; width: calc(100% - 20px); height: 6px; border-radius: 3px; background-color: #e5e7eb; } /* 蓝色选中区间 */ .slider-range { position: absolute; height: 100%; border-radius: 3px; background-color: #2563eb; } /* 原生滑块重置 */ .slider-thumb { position: absolute; top: 35px; width: calc(100% - 20px); height: 6px; background: transparent; pointer-events: none; -webkit-appearance: none; appearance: none; margin: 0; z-index: 2; } /* 滑块手柄样式 */ .slider-thumb::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 22px; height: 22px; border-radius: 50%; background: #fff; border: 3px solid #2563eb; box-shadow: 0 2px 8px rgba(0,0,0,0.12); pointer-events: auto; cursor: pointer; transition: transform 0.15s ease; } .slider-thumb::-moz-range-thumb { width: 22px; height: 22px; border-radius: 50%; background: #fff; border: 3px solid #2563eb; box-shadow: 0 2px 8px rgba(0,0,0,0.12); pointer-events: auto; cursor: pointer; transition: transform 0.15s ease; } /* 拖拽时手柄放大反馈 */ .slider-thumb:active::-webkit-slider-thumb { transform: scale(1.12); } .slider-thumb:active::-moz-range-thumb { transform: scale(1.12); } /* 数值提示气泡 */ .value-tips span { position: absolute; top: -28px; padding: 4px 9px; border-radius: 4px; background: #2563eb; color: #fff; font-size: 12px; line-height: 1; transform: translateX(-50%); }
JS交互逻辑
const minThumb = document.querySelector('.thumb-min'); const maxThumb = document.querySelector('.thumb-max'); const rangeBar = document.querySelector('.slider-range'); const minTip = document.querySelector('.tip-min'); const maxTip = document.querySelector('.tip-max'); const MIN_GAP = 5; // 两个滑块允许的最小间隔,可按需修改 // 初始化 updateRange(); minThumb.addEventListener('input', updateRange); maxThumb.addEventListener('input', updateRange); function updateRange(e) { let min = Number(minThumb.value); let max = Number(maxThumb.value); // 间隔校验,防止滑块交叉 if (max - min < MIN_GAP) { if (e?.target === minThumb) { min = max - MIN_GAP; minThumb.value = min; } else { max = min + MIN_GAP; maxThumb.value = max; } } // 更新选中条位置 rangeBar.style.left = `${min}%`; rangeBar.style.right = `${100 - max}%`; // 更新提示气泡位置和数值 minTip.style.left = `${min}%`; minTip.textContent = min; maxTip.style.left = `${max}%`; maxTip.textContent = max; }
自定义调整说明
- 修改两个
input标签的min、max属性,可自定义滑块的取值范围,修改value可设置初始选中区间 - 调整
MIN_GAP常量可修改两个滑块的最小允许间隔 - 色值、尺寸、圆角参数直接修改CSS对应属性即可,不需要改动逻辑代码
- 如果需要获取选中值,直接读取
minThumb.value和maxThumb.value即可,也可在updateRange函数中添加自定义回调
内容的提问来源于stack exchange,提问作者Akash AR
相关产品推荐
相关产品推荐

