bootstrap css 全局注入、无作用域、高复用、低特性,重置原生标签样式且变量定义在 :root,react 组件隔离无法阻止其反向穿透,构建工具不自动加作用域或树摇。

因为 Bootstrap 的 CSS 文件默认以全局方式注入,所有类名(如 .btn、.container、.row)不带任何作用域前缀,一旦加载就立即匹配整个页面的 DOM 节点。
Bootstrap 的 CSS 本质是“无边界”的设计产物
它诞生于 jQuery 时代,面向传统多页应用,天然假设自己是页面唯一 UI 框架。所有选择器都是扁平、高复用、低特异性的:
-
.btn不依赖父容器,也不加命名空间,只要 DOM 中有 class="btn" 就生效 - 重置样式(reboot.scss)直接作用于
html、body、p、h1等原生标签,覆盖浏览器默认行为和你已有的基础样式 - 变量(如
--bs-primary)定义在:root,全站可读可改,没有隔离机制
React 组件隔离不等于 CSS 隔离
即使你在某个组件里 import './MyComponent.css',或用 styled-components 写局部样式,这只能保护「你写的样式」不外溢;但无法阻止外部已加载的 Bootstrap CSS 反向穿透进来:
-
styled-components生成的.sc-a1b2c类不会影响.btn,但.btn会照常匹配你组件里的<button classname="btn"></button> - 如果组件用了
dangerouslySetInnerHTML渲染富文本,里面含<div class="alert alert-danger">,Bootstrap 的 <code>.alert规则立刻生效——你根本没显式引入它,只是它早已在里候着 - Shadow DOM 或 Vue 的
scoped在 React 中默认不启用,且对已注入的全局 CSS 无效 - 不会给每个选择器自动加上
.my-app-前缀 - 不会把
:root变量重写成#dashboard :root或.coreui-dashboard :root - 不会识别并跳过你不用的组件样式(tree-shaking 对纯 CSS 失效,除非用 Sass + 条件编译)
构建工具不会自动加作用域
Webpack/Vite 导入 bootstrap/dist/css/bootstrap.min.css,只是把整段 CSS 原样塞进 <style></style> 标签或提取为 <link>,不做任何转换:
真正麻烦的不是「能不能用 Bootstrap」,而是它的样式像水一样自然漫过所有边界——你得主动筑坝,而不是指望框架替你建。











