- 前端
- UI组件
【免费下载链接】BOOTSTRA.386
A vintage 1980s DOS inspired Twitter Bootstrap theme
导读
本文以 BOOTSTRA.386 仓库 v5.3.1 目录下官方文档 components/buttons.md 为核心,系统讲解 Bootstrap 5 按钮组件的基础类、语义变体、尺寸与禁用态、区块布局以及 toggle 按钮插件,并结合仓库内 scss/_buttons.scss、scss/mixins/_buttons.scss 与 js/src/button.js 等源码,深入剖析其底层 CSS 变量机制与 Sass 混入生成原理。读完本文,你将能够在 BOOTSTRA.386 复古 DOS 主题下熟练使用、扩展与自定义按钮,掌握从data-bs-toggle声明式用法到编程式 API 的完整技能。
BOOTSTRA.386 是一款以 1980 年代 DOS 界面为灵感、横跨 Bootstrap v2/v3/v4/v5 的主题;本文内容基于仓库中的 v5.3.1 版本目录,所有路径均以仓库根目录为基准。
Base class:.btn基础类
Bootstrap 为按钮提供了一个基础类.btn,负责设置内边距、内容对齐等基础样式。默认情况下,.btn控件的边框和背景色都是透明的,并且没有显式的 focus 与 hover 样式:
<button type="button" class="btn">Base class</button>从源码看,这些默认值正是通过 CSS 变量在 scss/_buttons.scss 中声明的:
.btn { --#{$prefix}btn-padding-x: #{$btn-padding-x}; --#{$prefix}btn-padding-y: #{$btn-padding-y}; --#{$prefix}btn-font-family: #{$btn-font-family}; @include rfs($btn-font-size, --#{$prefix}btn-font-size); --#{$prefix}btn-font-weight: #{$btn-font-weight}; --#{$prefix}btn-line-height: #{$btn-line-height}; --#{$prefix}btn-color: #{$btn-color}; --#{$prefix}btn-bg: transparent; --#{$prefix}btn-border-width: #{$btn-border-width}; --#{$prefix}btn-border-color: transparent; --#{$prefix}btn-border-radius: #{$btn-border-radius}; --#{$prefix}btn-hover-border-color: transparent; --#{$prefix}btn-box-shadow: #{$btn-box-shadow}; --#{$prefix}btn-disabled-opacity: #{$btn-disabled-opacity}; --#{$prefix}btn-focus-box-shadow: 0 0 0 #{$btn-focus-width} rgba(var(--#{$prefix}btn-focus-shadow-rgb), .5); }.btn类被设计为与各种按钮变体类配合使用,或者作为你自定义样式的起点。官方文档特别给出了一条 warning 提示:
如果单独使用
.btn类,请务必至少定义一些显式的:focus和/或:focus-visible样式。
这是因为裸.btn没有内置焦点可见样式,键盘可达性是自定义按钮时需要自行补齐的底线。
Variants:语义变体
Bootstrap 内置了多种按钮变体,每种变体服务于各自的语义用途:
<button type="button" class="btn btn-primary">Primary</button> <button type="button" class="btn btn-secondary">Secondary</button> <button type="button" class="btn btn-success">Success</button> <button type="button" class="btn btn-danger">Danger</button> <button type="button" class="btn btn-warning">Warning</button> <button type="button" class="btn btn-info">Info</button> <button type="button" class="btn btn-light">Light</button> <button type="button" class="btn btn-dark">Dark</button> <button type="button" class="btn btn-link">Link</button>以上示例中的主题色循环对应官方文档中的{{ range $theme-colors }}模板写法,渲染结果即上面的完整变体集。
从源码看,变体类并不是手写的,而是由 Sass 循环批量生成的。在 scss/_buttons.scss 的btn-variant-loops代码块中:
@each $color, $value in $theme-colors { .btn-#{$color} { @if $color == "light" { @include button-variant( $value, $value, $hover-background: shade-color($value, $btn-hover-bg-shade-amount), $hover-border: shade-color($value, $btn-hover-border-shade-amount), $active-background: shade-color($value, $btn-active-bg-shade-amount), $active-border: shade-color($value, $btn-active-border-shade-amount) ); } @else if $color == "dark" { @include button-variant( $value, $value, $hover-background: tint-color($value, $btn-hover-bg-tint-amount), $hover-border: tint-color($value, $btn-hover-border-tint-amount), $active-background: tint-color($value, $btn-active-bg-tint-amount), $active-border: tint-color($value, $btn-active-border-tint-amount) ); } @else { @include button-variant($value, $value); } } }注意其中的细节:light变体的 hover/active 使用shade-color()(加深),dark变体使用tint-color()(提亮),其余颜色走默认分支。这保证了深色与浅色按钮在交互态下都能保持足够的对比度。
官方文档还附带一条关于无障碍的提示:部分按钮样式的前景色相对较浅,只应在深色背景上使用,以保证足够的对比度(assistive technologies 提示原文见 buttons.md 中的 callout)。
禁用文本换行
如果不想让按钮文本换行,可以给按钮追加.text-nowrap工具类。在 Sass 中,则可以通过设置$btn-white-space: nowrap来全局禁用按钮文本换行。
对应的 Sass 变量定义位于 scss/_variables.scss:
$btn-white-space: null !default; // Set to `nowrap` to prevent text wrapping默认值为null(即允许换行),在 scss/_buttons.scss 中以white-space: $btn-white-space;的形式注入.btn基础类。
Button tags:在<a>与<input>上使用按钮类
.btn类设计上主要面向<button>元素,但同样可以用于<a>或<input>元素(部分浏览器渲染效果可能略有差异):
<a class="btn btn-primary" href="#" role="button">Link</a> <button class="btn btn-primary" type="submit">Button</button> <input class="btn btn-primary" type="button" value="Input"> <input class="btn btn-primary" type="submit" value="Submit"> <input class="btn btn-primary" type="reset" value="Reset">官方文档特别强调:当把按钮类用在<a>元素上、且该链接用于触发页内功能(如折叠内容)而非跳转到新页面时,应当为链接添加role="button",以便屏幕阅读器等辅助技术正确理解其语义。
Outline buttons:描边按钮
如果你需要按钮但又不想要厚重的背景色,可以把默认的修饰类替换为.btn-outline-*系列,它们会移除按钮上的所有背景图片和背景颜色,只保留描边与文字色:
<button type="button" class="btn btn-outline-primary">Primary</button> <button type="button" class="btn btn-outline-secondary">Secondary</button> <button type="button" class="btn btn-outline-success">Success</button> <button type="button" class="btn btn-outline-danger">Danger</button> <button type="button" class="btn btn-outline-warning">Warning</button> <button type="button" class="btn btn-outline-info">Info</button> <button type="button" class="btn btn-outline-light">Light</button> <button type="button" class="btn btn-outline-dark">Dark</button>描边变体同样由 Sass 循环生成(见 scss/_buttons.scss):
@each $color, $value in $theme-colors { .btn-outline-#{$color} { @include button-outline-variant($value); } }配套的button-outline-variant()混入定义在 scss/mixins/_buttons.scss,它通过重写 CSS 变量实现透明背景 + 彩色描边,并在 hover 时填充背景色:
@mixin button-outline-variant( $color, $color-hover: color-contrast($color), $active-background: $color, $active-border: $color, $active-color: color-contrast($active-background) ) { --#{$prefix}btn-color: #{$color}; --#{$prefix}btn-border-color: #{$color}; --#{$prefix}btn-hover-color: #{$color-hover}; --#{$prefix}btn-hover-bg: #{$active-background}; --#{$prefix}btn-hover-border-color: #{$active-border}; --#{$prefix}btn-focus-shadow-rgb: #{to-rgb($color)}; --#{$prefix}btn-active-color: #{$active-color}; --#{$prefix}btn-active-bg: #{$active-background}; --#{$prefix}btn-active-border-color: #{$active-border}; --#{$prefix}btn-active-shadow: #{$btn-active-box-shadow}; --#{$prefix}btn-disabled-color: #{$color}; --#{$prefix}btn-disabled-bg: transparent; --#{$prefix}btn-disabled-border-color: #{$color}; --#{$prefix}gradient: none; }Sizes:按钮尺寸
想用更大或更小的按钮?追加.btn-lg或.btn-sm即可:
<button type="button" class="btn btn-primary btn-lg">Large button</button> <button type="button" class="btn btn-secondary btn-lg">Large button</button> <button type="button" class="btn btn-primary btn-sm">Small button</button> <button type="button" class="btn btn-secondary btn-sm">Small button</button>底层实现同样不复杂——scss/_buttons.scss 只是调用button-size()混入:
.btn-lg { @include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-border-radius-lg); } .btn-sm { @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-border-radius-sm); }除了内置尺寸,你还可以用 CSS 变量完全自定义按钮尺寸,无需重写整段样式:
<button type="button" class="btn btn-primary" style="--bs-btn-padding-y: .25rem; --bs-btn-padding-x: .5rem; --bs-btn-font-size: .75rem;"> Custom button </button>这得益于button-size()混入同样只设置 CSS 变量(scss/mixins/_buttons.scss):
@mixin button-size($padding-y, $padding-x, $font-size, $border-radius) { --#{$prefix}btn-padding-y: #{$padding-y}; --#{$prefix}btn-padding-x: #{$padding-x}; @include rfs($font-size, --#{$prefix}btn-font-size); --#{$prefix}btn-border-radius: #{$border-radius}; }提示:
.btn-lg/.btn-sm中字号部分使用了 RFS(Responsive Font Size)机制,字号会随视口宽度平滑缩放;该机制由 scss/_variables.scss 中的$enable-rfs: true控制。
Disabled state:禁用状态
给<button>元素加上disabled布尔属性即可让按钮呈现禁用外观。禁用按钮被应用了pointer-events: none,hover 与 active 状态都不会触发:
<button type="button" class="btn btn-primary" disabled>Primary button</button> <button type="button" class="btn btn-secondary" disabled>Button</button> <button type="button" class="btn btn-outline-primary" disabled>Primary button</button> <button type="button" class="btn btn-outline-secondary" disabled>Button</button>在 scss/_buttons.scss 中,禁用态通过以下选择器实现,同时支持fieldset:disabled场景:
&:disabled, &.disabled, fieldset:disabled & { color: var(--#{$prefix}btn-disabled-color); pointer-events: none; background-color: var(--#{$prefix}btn-disabled-bg); background-image: if($enable-gradients, none, null); border-color: var(--#{$prefix}btn-disabled-border-color); opacity: var(--#{$prefix}btn-disabled-opacity); @include box-shadow(none); }默认的禁用透明度为$btn-disabled-opacity: .65(见 scss/_variables.scss)。
用于<a>的禁用按钮行为差异
使用<a>元素的禁用按钮表现略有不同,官方文档列出了 4 个要点:
<a>元素不支持disabled属性,因此必须添加.disabled类才能使其在视觉上呈现禁用状态;- 内置了一些面向未来的样式,用于禁用锚点按钮上的所有
pointer-events; - 使用
<a>的禁用按钮应添加aria-disabled="true"属性,向辅助技术表明元素状态; - 使用
<a>的禁用按钮不应包含href属性。
<a class="btn btn-primary disabled" role="button" aria-disabled="true">Primary link</a> <a class="btn btn-secondary disabled" role="button" aria-disabled="true">Link</a>链接功能未完全禁用的隐患(Link functionality caveat)
有些场景下你必须在禁用链接上保留href属性。此时.disabled类依靠pointer-events: none试图禁用<a>的链接功能。需要注意:该 CSS 属性目前还不是 HTML 标准的一部分(尽管所有现代浏览器都支持);更重要的是,即便在支持pointer-events: none的浏览器中,键盘导航仍然不受影响——视力正常的键盘用户和辅助技术用户依然能够激活这些链接。
因此官方文档给出的稳妥做法是:除aria-disabled="true"外,再为这些链接添加tabindex="-1"阻止其获得键盘焦点,并使用自定义 JavaScript 彻底禁用其功能:
<a href="#" class="btn btn-primary disabled" tabindex="-1" role="button" aria-disabled="true">Primary link</a> <a href="#" class="btn btn-secondary disabled" tabindex="-1" role="button" aria-disabled="true">Link</a>Block buttons:块级按钮
通过 display 工具类与 gap 工具类的组合,可以像 Bootstrap 4 那样创建响应式全宽"块按钮"。相比按钮专用类,工具类方案在间距、对齐和响应式行为上拥有更大的控制力。
基础的全宽堆叠按钮:
<div class="d-grid gap-2"> <button class="btn btn-primary" type="button">Button</button> <button class="btn btn-primary" type="button">Button</button> </div>响应式变体:按钮在md断点以下垂直堆叠,在md断点及以上用.d-md-block替换.d-grid,从而抵消gap-2工具类,使按钮变为水平排布:
<div class="d-grid gap-2 d-md-block"> <button class="btn btn-primary" type="button">Button</button> <button class="btn btn-primary" type="button">Button</button> </div>调整块按钮宽度:配合网格列宽工具类。例如做一个半宽块按钮用.col-6,再用.mx-auto水平居中:
<div class="d-grid gap-2 col-6 mx-auto"> <button class="btn btn-primary" type="button">Button</button> <button class="btn btn-primary" type="button">Button</button> </div>更多工具类可微调水平排列时的对齐:下面的示例在之前响应式示例基础上,叠加 flex 工具类与 margin 工具类,让按钮在不再堆叠时右对齐:
<div class="d-grid gap-2 d-md-flex justify-content-md-end"> <button class="btn btn-primary me-md-2" type="button">Button</button> <button class="btn btn-primary" type="button">Button</button> </div>Button plugin:开关(toggle)按钮插件
按钮插件允许你创建简单的开/关切换按钮。官方文档特别指出:视觉上这些 toggle 按钮与 复选框切换按钮(checkbox toggle buttons)完全一致,但二者在辅助技术上传达的信息不同:复选框切换按钮会被屏幕阅读器播报为"已勾选/未勾选"(因为其本质仍是 checkbox),而插件 toggle 按钮会被播报为"按钮/按钮已按下"。选择哪种方案,取决于你的切换场景对用户以"复选框"还是"实际按钮"播报更有意义。
Toggle states
给按钮添加data-bs-toggle="button"即可切换其active状态。如果按钮需要预置为激活态,必须手动同时添加.active类和aria-pressed="true",以确保辅助技术能正确传达状态:
<p class="d-inline-flex gap-1"> <button type="button" class="btn"><p class="d-inline-flex gap-1"> <a href="#" class="btn" role="button">EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => { event.preventDefault() const button = event.target.closest(SELECTOR_DATA_TOGGLE) const data = Button.getOrCreateInstance(button) data.toggle() })核心的toggle()方法只有几行,它切换active类,并同步aria-pressed属性为切换后的布尔值(js/src/button.js):
toggle() { // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE)) }Methods
你可以通过按钮构造函数创建按钮实例:
const bsButton = new bootstrap.Button('#myButton')插件提供以下方法(详见 js/src/button.js):
| 方法 | 描述 |
|---|---|
dispose | 销毁元素的按钮实例(移除 DOM 元素上存储的数据) |
getInstance | 静态方法,获取与 DOM 元素关联的按钮实例,用法:bootstrap.Button.getInstance(element) |
getOrCreateInstance | 静态方法,返回与 DOM 元素关联的按钮实例;若未初始化则创建一个新实例,用法:bootstrap.Button.getOrCreateInstance(element) |
toggle | 切换按压状态,让按钮呈现"已被激活"的外观 |
例如,批量切换页面上所有按钮:
document.querySelectorAll('.btn').forEach(buttonElement => { const button = bootstrap.Button.getOrCreateInstance(buttonElement) button.toggle() })插件同样通过
defineJQueryPlugin(Button)注册了 jQuery 接口(若项目同时引入 jQuery),并支持data-toggle风格的调用(见 js/src/button.js)。
CSS:变量、Sass 变量、混入与循环
CSS 变量(自 5.2.0 引入)
作为 Bootstrap 持续演进 CSS 变量方案的一部分,按钮现在使用.btn上的局部 CSS 变量实现实时定制。这些 CSS 变量的值由 Sass 设置,因此 Sass 定制依然可用。.btn上声明的整套变量见上文"Base class"一节的源码片段。
每个.btn-*修饰类都会更新对应的 CSS 变量,从而以最少的 CSS 规则实现样式差异——这得益于button-variant()、button-outline-variant()和button-size()三个混入。
以下是官方文档演示的、构建自定义.btn-*修饰类的完整示例(完整定义见 site/assets/scss/_buttons.scss):
.btn-bd-primary { --bs-btn-font-weight: 600; --bs-btn-color: var(--bs-white); --bs-btn-bg: var(--bd-violet-bg); --bs-btn-border-color: var(--bd-violet-bg); --bs-btn-hover-color: var(--bs-white); --bs-btn-hover-bg: #{shade-color($bd-violet, 10%)}; --bs-btn-hover-border-color: #{shade-color($bd-violet, 10%)}; --bs-btn-focus-shadow-rgb: var(--bd-violet-rgb); --bs-btn-active-color: var(--bs-btn-hover-color); --bs-btn-active-bg: #{shade-color($bd-violet, 20%)}; --bs-btn-active-border-color: #{shade-color($bd-violet, 20%)}; }使用它时只需:
<button type="button" class="btn btn-bd-primary">Custom button</button>这种"重写 CSS 变量"的定制方式不需要任何额外样式规则,hover、active、focus 等状态全部自动生效。
Sass 变量
按钮相关的全部 Sass 变量集中在 scss/_variables.scss 的btn-variables代码块中,要点如下:
| 变量 | 默认值 | 说明 |
|---|---|---|
$btn-color | var(--#{$prefix}body-color) | 按钮文字颜色 |
$btn-padding-y/$btn-padding-x | 继承自$input-btn-* | 基础内边距(BOOTSTRA.386 中$input-btn-padding-y/x均为0) |
$btn-font-size/$btn-font-weight | $input-btn-font-size/$font-weight-normal | 字号与字重 |
$btn-white-space | null | 设为nowrap可禁用文本换行 |
$btn-border-width/$btn-border-radius | $input-btn-border-width/var(--#{$prefix}border-radius) | 边框与圆角 |
$btn-disabled-opacity | .65 | 禁用态透明度 |
$btn-box-shadow | inset 0 1px 0 rgba($white, .15), 0 1px 1px rgba($black, .075) | 基础阴影 |
$btn-active-box-shadow | inset 0 3px 5px rgba($black, .125) | 激活态阴影 |
$btn-link-color/$btn-link-hover-color/$btn-link-disabled-color | 链接相关变量 | Link 变体的三态颜色 |
$btn-hover-bg-shade-amount | 15% | hover 背景加深比例 |
$btn-hover-border-shade-amount | 20% | hover 边框加深比例 |
$btn-active-bg-shade-amount/$btn-active-border-shade-amount | 20%/25% | 激活态加深比例 |
$btn-hover-bg-tint-amount/$btn-active-bg-tint-amount | 15%/20% | hover/active 提亮比例 |
值得注意的 BOOTSTRA.386 特色:在 scss/_variables.scss 中,$input-btn-padding-y与$input-btn-padding-x被设为0,这与 Bootstrap 官方的默认值不同——它服务于主题扁平、紧凑的 DOS 复古视觉风格。
Sass 混入
按钮相关共有三个混入(全部定义在 scss/mixins/_buttons.scss):
button-variant()(L7-L35):实心变体混入,基于$theme-colors生成.btn-*。它只负责写 CSS 变量——包括--bs-btn-color、--bs-btn-bg、--bs-btn-border-color以及 hover/active/disabled 全套状态变量;hover/active 背景默认通过color-contrast()判断前景色后,选择shade-color()或tint-color()生成。button-outline-variant()(L38-L61):描边变体混入,用于.btn-outline-*,额外设置--#{$prefix}gradient: none以去除渐变背景。button-size()(L63-L69):尺寸混入,只写padding、font-size(经 RFS)与border-radius三个 CSS 变量,供.btn-lg/.btn-sm及自定义尺寸复用。
Sass 循环
常规与描边两种按钮变体分别在 scss/_buttons.scss 的btn-variant-loops代码块中,用各自对应的混入配合$theme-colorsmap 批量生成修饰类。这样,当你在自己的主题中向$theme-colors增删颜色时,.btn-*与.btn-outline-*会同步生成或消失,无需手工维护。
小结与进一步阅读
BOOTSTRA.386 v5 的按钮组件完整继承了 Bootstrap 5.3 的设计体系:.btn基础类 + CSS 变量定制、$theme-colors驱动的变体与描边变体、.btn-lg/.btn-sm尺寸、禁用态的无障碍规范、工具类组合的块按钮布局,以及基于 Data API 的 toggle 插件。理解 scss/_buttons.scss、scss/mixins/_buttons.scss 与 js/src/button.js 三份源码,是你在复古 DOS 主题下定制按钮的最短路径。
相关文档可继续深入:
- 按钮组 button-group:按钮的水平分组与工具栏用法;
- 复选框与单选按钮切换(toggle buttons):与按钮插件视觉一致但语义不同的表单切换按钮;
- 项目根目录 README.md:了解 BOOTSTRA.386 各版本概况与全局
_386配置。
- 前端
- UI组件
【免费下载链接】BOOTSTRA.386
A vintage 1980s DOS inspired Twitter Bootstrap theme
相关推荐
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考