聊一个常见问题:很多人在用Bootstrap 5时,都想改掉输入框聚焦时默认的蓝色阴影。直接改 `$primary` 变量往往不奏效,这个蓝色阴影到底从哪儿来的?怎么改才能彻底控制它?下面拆开讲。
Bootstrap 5 中 `:focus` 蓝色阴影由 `box-shadow` 控制,不是颜色变量直接控制
Bootstrap 5 默认用 `box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25)` 来实现聚焦高亮。这里的 `rgba(13, 110, 253, 0.25)` 是主色 `$primary` 的半透明版本,但它本质上是一段**阴影的叠加效果**,并不是一个叫“蓝色阴影颜色”的独立属性。
* 这个阴影值直接写在 `.form-control:focus` 等多个选择器的 CSS 规则里,不是靠一个 CSS 变量来统一开关。
* 要改它,必须覆盖原始规则。光改 `$primary` 变量不行——那会让按钮、链接等其他元素跟着变色。
* 如果你用的是 Bootstrap 官方 CDN 或预编译的 CSS,修改时大概率躲不开 `!important`。
覆盖默认聚焦阴影的两种可靠方式
推荐优先用 CSS 自定义属性(Custom Properties)方式,兼容性好、维护也方便。如果需要更精细的控制,或用兼容旧版的场景,再使用传统覆盖。
方式一(推荐):重设 `--bs-form-control-focus-box-shadow` 变量
在全局样式中加这段就好:
```css
:root {
--bs-form-control-focus-box-shadow: 0 0 0 0.25rem rgba(52, 152, 219, 0.4);
}
```
注意:这个变量只影响 `.form-control`、`.form-select` 这类原生表单控件,对 `.btn` 是完全无效的。
方式二(兜底):直接覆盖选择器
```css
.form-control:focus,
.form-select:focus,
.was-validated .form-control:valid:focus,
.was-validated .form-select:valid:focus {
box-shadow: 0 0 0 0.25rem rgba(52, 152, 219, 0.4) !important;
}
```
这里的 `!important` 必须加,否则很容易被 Bootstrap 原始样式的权重压住。
为什么改了 `$primary` 却没生效?
这背后是 Bootstrap 5 的 SCSS 编译逻辑。`$primary` 只负责生成初始调色板和部分组件的基础色,而聚焦阴影是通过 `box-shadow` 函数单独计算的。默认它会调用 `rgba($primary, .25)`,但这个计算**发生在编译时**,不是运行时动态读取变量。
* 如果你用的是已经编译好的 `bootstrap.min.css`,那改 SCSS 变量自然毫无作用。
* 就算你自建 SCSS 构建流程,也必须确保 `$enable-important-utilities: true`,或者手动重写 `form-control.scss` 中的 `:focus` 规则。
* 最简单的验证方法:打开浏览器开发者工具,检查 `.form-control:focus` 的 computed `box-shadow`,看它到底有没有被你的样式覆盖。
别忽略表单验证状态下的聚焦样式
这部分是很多人踩坑的地方。Bootstrap 对 `.was-validated .form-control:valid:focus` 和 `:invalid:focus` 有独立的阴影规则,它们默认使用 `$success` / `$danger` 颜色,**完全不收 `--bs-form-control-focus-box-shadow` 变量的影响**。
* 要统一风格,必须额外覆盖这些选择器。比如:
```css
.was-validated .form-control:valid:focus,
.was-validated .form-select:valid:focus {
box-shadow: 0 0 0 0.25rem rgba(46, 204, 113, 0.4) !important;
}
```
* 或者,你也可以直接禁用验证状态的聚焦覆盖(不推荐):
```css
.was-validated .form-control:valid:focus { box-shadow: none; }
```
实际项目里,验证态和普通聚焦态的阴影经常被当成一回事处理,结果上线后才发现:输入正确时阴影变绿、错误时变红——这是最容易被忽略的视觉断层点。