概览
原生的<input type="range">很难进行样式化,并且仅使用CSS无法以一致的跨浏览器方式显示填充轨道——只有Firefox提供::-moz-range-progress,而CSS无法读取输入的值。因此,我们的范围是一个小型的JavaScript组件:将<input class="form-range-input">包装在.form-range中,插件会保持--bs-range-fill自定义属性(0–1)同步,CSS使用它来绘制填充、数值气泡和刻度。
.form-range 包装器拥有组件的令牌,因此输入和任何装饰都会继承它们。页面上的每个 .form-range 都会自动初始化。
<label for="range1" class="form-label">Example range</label>
<div class="form-range">
<input type="range" class="form-range-input" id="range1">
</div>主题颜色
通过将 .theme-{color} 类添加到 .form-range 包装器来修改范围的外观。这将把轨道填充和滑块颜色设置为主题颜色。
<div class="form-range theme-primary">
<input type="range" class="form-range-input" aria-label="Example primary range">
</div>
<div class="form-range theme-accent">
<input type="range" class="form-range-input" aria-label="Example accent range">
</div>
<div class="form-range theme-success">
<input type="range" class="form-range-input" aria-label="Example success range">
</div>
<div class="form-range theme-danger">
<input type="range" class="form-range-input" aria-label="Example danger range">
</div>
<div class="form-range theme-warning">
<input type="range" class="form-range-input" aria-label="Example warning range">
</div>
<div class="form-range theme-info">
<input type="range" class="form-range-input" aria-label="Example info range">
</div>
<div class="form-range theme-inverse">
<input type="range" class="form-range-input" aria-label="Example inverse range">
</div>
<div class="form-range theme-secondary">
<input type="range" class="form-range-input" aria-label="Example secondary range">
</div>残疾
在输入框上添加disabled布尔属性,使其显示灰色外观,移除指针事件,并防止获得焦点。
<label for="disabledRange" class="form-label">Disabled range</label>
<div class="form-range">
<input type="range" class="form-range-input" id="disabledRange" disabled>
</div>最小值和最大值
范围输入分别对min和max—0和100具有隐式值。你可以使用min和max属性为它们指定新的值。
<label for="range2" class="form-label">Example range</label>
<div class="form-range">
<input type="range" class="form-range-input" min="0" max="5" id="range2">
</div>步骤
默认情况下,范围输入会“捕捉”到整数值。要更改此设置,你可以指定一个 step 值。在下面的示例中,我们通过使用 step="0.5" 将步骤数加倍。
<label for="range3" class="form-label">Example range</label>
<div class="form-range">
<input type="range" class="form-range-input" min="0" max="5" step="0.5" id="range3">
</div>价值气泡
添加 data-bs-bubble 到包装器以显示一个跟随拇指的数值气泡。该气泡重用我们的 工具提示 风格。
<label for="rangeBubble" class="form-label">Brightness</label>
<div class="form-range" data-bs-bubble>
<input type="range" class="form-range-input" min="0" max="100" value="60" id="rangeBubble">
</div>刻度标记
将 <datalist> 使用 list 属性链接到输入,插件会为每个 <option> 渲染一个勾号,位置对应其值(即使值分布不均)。<option> 的 label 显示在其勾号下方。
<label for="rangeTicks" class="form-label">Temperature</label>
<div class="form-range">
<input type="range" class="form-range-input" min="0" max="100" step="25" value="50" list="rangeTicksList" id="rangeTicks">
</div>
<datalist id="rangeTicksList">
<option value="0" label="Cold"></option>
<option value="25"></option>
<option value="50" label="Mild"></option>
<option value="75"></option>
<option value="100" label="Hot"></option>
</datalist>带表单字段
将 .form-range 包裹在 .form-field 中,以将其与标签和描述配对。
<div class="form-field">
<label for="rangeField" class="form-label">Volume</label>
<div class="form-range" data-bs-bubble>
<input type="range" class="form-range-input" id="rangeField">
</div>
<small class="form-text">Adjust the volume level.</small>
</div>用法
每个 .form-range 在页面加载时会自动初始化——该组件由 JavaScript 驱动,因此如果没有插件,填充将无法呈现。
通过数据属性
<div class="form-range" data-bs-bubble>
<input type="range" class="form-range-input" min="0" max="100" value="40">
</div>
通过 JavaScript
const element = document.querySelector('.form-range')
const range = new bootstrap.Range(element, {
bubble: true,
formatter: value => `${value}%`
})
依赖项
如果你从源代码构建 Bootstrap 的 JS,范围插件需要以下 JavaScript 文件:
| 文件 | 描述 |
|---|---|
js/src/range.ts | 主要范围组件 |
js/src/base-component.ts | 基础组件类 |
js/src/dom/data.ts | 元素数据存储 |
js/src/dom/event-handler.ts | 事件处理工具 |
js/src/dom/manipulator.ts | 数据属性操作 |
js/src/dom/selector-engine.ts | DOM选择器工具 |
js/src/util/config.ts | 配置基础类 |
js/src/util/index.ts | 核心工具函数 |
选项
| 名称 | 类型 | 默认值 | 描述 |
|---|---|---|---|
bubble | boolean | false | 在滑块上方显示值气泡。 |
formatter | function | null | (value) => string 用于气泡和刻度标签文本。 |
方法
| 方法 | 描述 |
|---|---|
update() | 从输入当前值重新计算填充。在以编程方式设置值后非常有用。 |
dispose() | 销毁实例并移除其创建的气泡和刻度标记。 |
getInstance() | 静态方法,用于获取与 .form-range 元素关联的实例。 |
getOrCreateInstance() | 静态方法,用于获取实例,如果不存在则创建一个。 |
事件
| 事件 | 描述 |
|---|---|
changed.bs.range | 在值更新时触发输入事件(在 input 和 change 时)。事件的 value 属性保存当前的数值。 |
const input = document.querySelector('.form-range-input')
input.addEventListener('changed.bs.range', event => {
console.log('Value:', event.value)
})
CSS
变量
Range 使用本地 CSS 变量在 .form-range 上进行实时自定义。CSS 变量的值由每个组件唯一的 Sass map生成,并应用到上述类上。
// stylelint-disable-next-line scss/dollar-variable-default
$range-tokens: defaults(
(
--range-track-width: 100%,
--range-track-height: .5rem,
--range-track-cursor: pointer,
--range-track-bg: var(--bg-3),
--range-track-border-radius: 1rem,
--range-track-fill-bg: var(--theme-bg, var(--primary-base)),
--range-track-disabled-bg: color-mix(in oklch, var(--bg-4), var(--fg-3)),
--range-thumb-width: 1rem,
--range-thumb-height: var(--range-thumb-width),
--range-thumb-bg: var(--theme-bg, var(--primary-base)),
--range-thumb-border: var(--range-thumb-bg) solid var(--border-color),
--range-thumb-border-radius: 1rem,
--range-thumb-box-shadow: "0 1px 2px rgb(0 0 0 / 7.5%), 0 2px 4px rgb(0 0 0 / 7.5%)",
--range-thumb-active-bg: color-mix(in oklch, var(--theme-bg, var(--primary-base)) 70%, var(--bg-body)),
--range-thumb-disabled-bg: var(--fg-3),
--range-thumb-transition-property: "background-color, border-color, box-shadow",
--range-thumb-transition-duration: .15s,
--range-thumb-transition-timing: ease-in-out,
--range-tick-width: var(--border-width),
--range-tick-height: .5rem,
--range-tick-bg: var(--border-color),
),
$range-tokens
);
Sass 混入
两个 mixin 会生成范围输入控件的轨道和滑块的特定于供应商的样式。请注意,WebKit 和 Firefox 中伪元素的选择器不能合并——每个必须在单独的 CSS 规则中使用,否则样式将无法应用。
@mixin range-thumb() {
width: var(--range-thumb-width);
height: var(--range-thumb-height);
appearance: none;
@include gradient-bg(var(--range-thumb-bg));
border: var(--range-thumb-border);
@include border-radius(var(--range-thumb-border-radius));
@include box-shadow(var(--range-thumb-box-shadow));
@include transition-props(
var(--range-thumb-transition-property),
var(--range-thumb-transition-duration),
var(--range-thumb-transition-timing)
);
&:active {
@include gradient-bg(var(--range-thumb-active-bg));
}
}
@mixin range-track() {
width: var(--range-track-width);
height: var(--range-track-height);
color: transparent;
cursor: var(--range-track-cursor);
// Fill (progress) up to the thumb. The Range plugin keeps `--range-fill` (0–1) in sync.
background-color: var(--range-track-bg);
background-image:
linear-gradient(
to right,
var(--range-track-fill-bg) calc(var(--range-fill, 0) * 100%),
transparent calc(var(--range-fill, 0) * 100%)
);
border-color: transparent;
@include border-radius(var(--range-track-border-radius));
@include box-shadow(var(--range-track-box-shadow));
}