首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >同一套 UI,三种写法:Bootstrap / Bulma / Tailwind 三框架横评

同一套 UI,三种写法:Bootstrap / Bulma / Tailwind 三框架横评

原创
作者头像
夏末浅笑
修改于 2026-10-16 13:14:14
修改于 2026-10-16 13:14:14
70
举报

三份可直接双击打开的案例页、一个同屏对比页、一批本机实测数据——聊聊三种 CSS 框架的设计哲学、样式能力、交互成本和选型边界。

Bootstrap / Bulma / Tailwind
Bootstrap / Bulma / Tailwind

一、这篇文章从哪来

手上有三份"讲同一件事"的页面:它们都演示布局、排版、表单、组件、工具类、暗黑模式这几块内容,但分别用 Bootstrap、Bulma、Tailwind CSS 实现。既然内容对等,就正好可以当成一次控制变量的横评。

为了对比方便,我又做了两件事:

  • 把三份页面塞进同一个 index.html:三栏 iframe 并排/堆叠、可缩放、可按章节跳转、可同步滚动,样式互不污染;
  • 把结论写成这篇文章,并附上可复现的测量方法(见文末)。

文件清单如下。

文件

框架与版本

说明

index.html

—

同屏对比页:三栏 iframe + 功能矩阵 + 代码对照(不含本文,本文单独成页)

bootstrap-showcase.html

Bootstrap 5.3.8

组件全家桶,交互由官方 bundle 驱动,含 icons 与暗黑模式

bulma-showcase.html

Bulma 1.0.4

纯 CSS,交互为 183 行自写 JS,含 v1 的 grid 与 skeleton

tailwind-showcase.html

Tailwind 4.3.3

原子化工具类拼装,交互为 197 行自写 JS

三份页面结构上刻意对齐,覆盖的模块数量如下:

页面

章节

行数

自写 JS

自定义 CSS

Bootstrap

布局 / 排版 / 图片表格 / 组件 / 表单 / 工具

1088

80 行

43 行

Bulma

布局 / 元素 / 组件 / 表单 / 辅助 / 特性

1306

183 行

57 行

Tailwind

布局 / 排版 / 颜色 / 按钮 / 表单 / 组件 / 工具

873

197 行

3 行 + 314 处 dark:

最后一行已经剧透了三个框架的性格:Bootstrap 用别人的 JS,Bulma 用别人的 CSS,Tailwind 什么都不给你但什么都能写。

二、三种设计哲学:你买到的"交付物"不一样

Bootstrap:把组件当一等公民。 它交付的是一套完整的 UI 套件——按钮、卡片、模态框、下拉、轮播、Toast、Offcanvas、Tooltip……每个组件既有样式也有行为,行为由官方 JS 插件驱动。你用 data-bs-toggle 写声明,剩下的(焦点陷阱、ESC 关闭、滚动锁、ARIA 状态同步)框架全包。

Bulma:把语义化类名当一等公民。 它只交付 CSS,一个字节 JS 都没有。类名高度可读(button is-primary is-outlined、has-text-danger、is-size-3),v1 之后全面变量化(--bulma-*),顺带内置了暗黑模式的变量切换和 is-skeleton 骨架屏。代价是:交互、图标、Toast 这类"行为"要你自己接。

Tailwind:把设计 token + 原子类当一等公民。 它交付的是一台编译器:你写 px-4 py-2 rounded-lg bg-sky-600,它按需生成对应的 CSS。没有"按钮"这个概念,只有零件。好处是产物最小、约束最统一;代价是模板变长、组件体系要自己长出来(或引入 shadcn/Headless UI 这类无样式组件库)。

三、同一个按钮,三种写法

代码语言:javascript
复制
<!-- Bootstrap:语义类组合,改颜色改尺寸都只是换类名 -->
<button type="button" class="btn btn-primary">主要按钮</button>
<button type="button" class="btn btn-outline-primary btn-sm">描边小按钮</button>
<button type="button" class="btn btn-primary" disabled>禁用</button>
代码语言:javascript
复制
<!-- Bulma:读起来最像英文句子 -->
<button class="button is-primary">主要按钮</button>
<button class="button is-outlined is-small">描边小按钮</button>
<button class="button is-primary" disabled>禁用</button>
代码语言:javascript
复制
<!-- Tailwind:一次写完所有细节,复用要靠组件化 -->
<button class="rounded-lg bg-sky-600 px-4 py-2 text-sm font-medium text-white
               transition hover:bg-sky-500 disabled:cursor-not-allowed disabled:opacity-50">
  主要按钮
</button>

三行代码背后是三种维护模型:Bootstrap 改一次 --bs-primary 全局生效;Bulma 改一次 --bulma-primary 全局生效;Tailwind 要靠设计 token 和组件封装,否则你会在一个项目里看到 7 种蓝色。

四、样式能力:栅格、间距、颜色、排版

对比项

Bootstrap

Bulma

Tailwind

栅格

12 列 flex 栅格,offset/order/gutter 齐全

columns(12 等分 flex)+ v1 grid(CSS Grid)

原生 Grid/Flex 任意拼装,grid-cols-12、gap-4

间距刻度

m/p-0~5 六档 + auto

m/p-0~6 七档

0.25rem 基准的任意倍数,p-13 也合法

颜色

8 个语义色 + subtle/emphasis/rgb 变体

6 个语义色 + light/dark/invert/on-* 派生

22+ 色板 × 11 阶,支持任意值

排版

display-*、lead、fs-*、fw-*

title、subtitle、is-size-*

text-*、font-*、leading-*、tracking-*

圆角阴影

够用

偏少,常需自定义

全套 + 任意值

写一套新皮肤

低(SCSS / CSS 变量)

低(--bulma-* 变量)

中(要自己定义并贯穿 token)

一句话总结:Bootstrap 提供"够用的刻度",Bulma 提供"好读的刻度",Tailwind 提供"没有刻度的尺子"。 刻度少的好处是设计一致性天然更好;刻度自由的好处是不用为了 13px 的间距去写一个自定义类。

五、组件覆盖:这是最大的分水岭

我把三份页面里演示过的组件整理成 24 类,逐个核对:

组件

Bootstrap

Bulma

Tailwind

按钮 / 按钮组

✅ 内置

✅ 内置

⚠️ flex 拼装

卡片

✅

✅

⚠️

模态框

✅ + 官方 JS

✅ 结构 + 自写 JS

⚠️ 自绘 + 自写 JS

下拉菜单

✅ 官方 JS

✅ + 自写 JS

⚠️ + 自写 JS

标签页

✅ 官方 JS

✅ + 自写 JS

⚠️ role=tablist 自写

手风琴 / 折叠

✅

⚠️ 自写

⚠️ 自写

轮播

✅

❌

⚠️ 自写

Toast 通知

✅

⚠️ 只有静态 notification

⚠️ 自写 + aria-live

进度条

✅ 含条纹/动画

✅

⚠️

分页

✅

✅ 含 ellipsis

⚠️

面包屑

✅

✅ 含 is-arrowed

⚠️

徽章 / 标签

✅

✅ 可删除 tag

⚠️

列表组 / 面板 / 消息块

✅ list-group

✅ panel / message / menu

⚠️

侧滑面板

✅ offcanvas

❌

⚠️

提示 / 气泡

✅ tooltip + popover

❌

⚠️

骨架屏

✅ placeholder

✅ is-skeleton(v1)

⚠️ animate-pulse

导航栏(含汉堡)

✅ 官方 JS

✅ + 自写 JS

⚠️

表格

✅

✅

⚠️

表单校验态

✅

✅

⚠️ 自绘

浮动标签

✅ form-floating

⚠️ 自写

⚠️ peer 技巧

输入组 / 前后缀

✅

✅ 图标型

⚠️

开关 switch

✅

⚠️

⚠️

文件上传

✅

✅ 组件较完整

⚠️

滑块 / 多选下拉

✅

⚠️

⚠️

统计结果:Bootstrap 24 类全部开箱即用;Bulma 16 类有现成样式(5 类要自己拼、3 类没有);Tailwind 一类都没有。

这就是三个框架最本质的差别:Bootstrap 卖组件,Bulma 卖样式,Tailwind 卖零件。如果你的页面里塞满了模态框、下拉、轮播、Toast,选 Bootstrap 省下的工作量是以"天"计算的;如果页面基本是内容展示,Bulma 的语义化类名会让 HTML 好读很多。

六、交互:谁在替你写 JavaScript

交互成本

Bootstrap

Bulma

Tailwind

交互实现者

官方 bundle(79 KB / gzip 23.3 KB)

你自己

你自己

案例页自写 JS

80 行(基本只有主题切换)

183 行

197 行

声明式交互

✅ data-bs-toggle="modal"

❌

❌

ARIA 状态同步

插件自动

手写

手写

键盘支持(ESC / Tab / 方向键)

框架内置

手写

手写

有个很直观的对照:三份页面里都有"下拉菜单、标签页、模态框、导航栏汉堡菜单、主题切换"这五组交互。

  • Bootstrap 版只写了 80 行 JS,其中大部分还是主题切换——因为交互全部由插件接管;
  • Bulma 版和 Tailwind 版分别写了 183 行和 197 行,因为连 aria-expanded 和 is-active 的切换都得自己来。

判断法则:如果页面里超过 5 个交互组件,Bootstrap 的 79 KB JS 是划算的;如果只有一两个(比如一个移动端菜单),那 190 行自写 JS 换来的"零 JS 依赖"更干净。

七、暗黑模式:三条完全不同的路线

路线

Bootstrap

Bulma

Tailwind

机制

data-bs-theme="dark"

data-theme="dark" 覆盖 --bulma-*

.dark class + dark: 变体

切换代码

一行 setAttribute

一行 setAttribute

一行 classList.toggle

逐元素适配

不需要

不需要(自定义组件用变量即可)

314 处 dark:

可控粒度

整套变量

整套变量

任意元素

主要坑

自定义 CSS 要用 --bs-* 变量

v0 没有变量体系,v1 才补齐

class 变长,token 不统一就会花

暗黑模式其实是判断一个框架"是否设计系统化"的试纸。Bootstrap 和 Bulma 的做法是"换一套变量",你写业务样式时只要用变量,切换就是零成本;Tailwind 的做法是"每个元素写两遍",控制力最强,但三份页面里它是唯一需要 314 处额外类名的那份——这不是 Tailwind 的缺陷,而是它的模型:它把主题决策的负担从框架转移到了你的模板和团队约定上。

八、体积:真实数字

以下数据在本机实测(方法见文末),原始体积按 CDN 上的 min 版本统计,gzip 为 level 9。

资源

原始

gzip

Bootstrap 5.3.8 CSS

227 KB

30.0 KB

Bootstrap 5.3.8 bundle JS

79 KB

23.3 KB

Bootstrap Icons CSS(另有字体文件)

84 KB

12.9 KB

Bulma 1.0.4 CSS

662 KB

63.5 KB

Tailwind 4.3.3 浏览器版运行时

276 KB

72.1 KB

Tailwind 为案例页按需生成的 CSS

53 KB

8.4 KB

同上,minify 后(≈生产产物)

42 KB

7.8 KB

Bootstrap CSS + JS + 图标合计

390 KB

66.2 KB

三点解读:

  1. gzip 之后,Bootstrap 全家桶(66 KB)和 Bulma 单个 CSS(63.5 KB)几乎同级,但 Bootstrap 多送 24 类可交互组件。Bulma 的 662 KB 原始体积来自 v1 把 light/dark 两套配色变量全量吐出——网络成本能接受,但 CSS 解析不是免费的,移动端低端机要留意。
  2. Tailwind 浏览器版是体验工具,不是生产方案:276 KB 的运行时要在浏览器里现场编译,首次渲染会闪一下,而且需要较新的浏览器(Chrome 111+ / Safari 16.4+)。生产环境应当走构建流程,只为用到的类生成 CSS——本案例页按需生成 53 KB,minify 后 42 KB(gzip 仅 7.8 KB),这才是 Tailwind 真正的体积形态:同样的页面,CSS 网络成本只有 Bootstrap 全家桶的约 1/8、Bulma 的约 1/8。
  3. 三份案例页自身的 HTML 都在 60 KB 左右(1088 / 1306 / 873 行),因为大头是中文示例文案和表格内容,框架差异被内容淹没了——这也是个好提醒:框架体积焦虑要先看内容体积。

九、响应式与断点

框架

断点档位

写法

Bootstrap

6 档:576 / 768 / 992 / 1200 / 1400

col-12 col-md-6 col-lg-4,断点内建在栅格类里

Bulma

5 档:769 / 1024 / 1216 / 1408(+ mobile)

columns is-multiline + 修饰类,或 v1 的 grid

Tailwind

5 档:640 / 768 / 1024 / 1280 / 1536,可自定义

前缀即断点:grid-cols-1 md:grid-cols-2 lg:grid-cols-3

写起来最顺手的是 Tailwind(任何工具类都能加断点前缀,不必是"栅格专属");最省心的是 Bootstrap(栅格类自带断点,不需要你记断点数值);Bulma 的断点基于 min-width,从 tablet 才开始生效,写移动优先时需要适应一下它的心智模型。

十、可访问性:框架替你做了多少

  • Bootstrap:插件会自动维护 aria-expanded、aria-selected、aria-controls,模态框有焦点陷阱、ESC 关闭、滚动锁,还有 visually-hidden、RTL 支持。这一栏它领先得最多。
  • Bulma / Tailwind:框架只提供样式,ARIA 全凭自觉。不过我核对过三份案例页——Bulma 版补了 aria-expanded、aria-selected、aria-hidden 与 focus-visible 描边;Tailwind 版手写了 role="tablist"、role="dialog"、aria-modal、aria-live、role="switch" + aria-checked。也就是说两份都补齐了,差别在于"谁保证不漏":Bootstrap 是框架保证,另两个是代码评审保证。

如果你在做面向公众、有合规要求的项目,把可访问性检查写进 CI(例如 axe-core),比选哪个框架更重要。

十一、工程化与长期维护

对比项

Bootstrap

Bulma

Tailwind

是否必须构建

否

否

生产建议构建

按需裁剪

需自行用 SCSS 编译

需自行用 Sass 编译

天生按需生成

主题定制入口

SCSS 变量 / --bs-*

Sass 变量 / --bulma-*

@theme 设计 token

大版本升级风险

4 → 5 有破坏性变更

0.x → 1.0 变更较大

3 → 4 改为 CSS-first 配置

生态

极大(后台模板、企业项目多)

中等

极大(Headless UI / Radix / shadcn)

代码可读性

好,模板干净

最好

一般,需要组件化约束

学习曲线

低

低

中

AI / 脚手架友好度

高

中

高(但依赖团队 token 约定)

两个容易被忽略的点:

  1. Bootstrap 的"约定"既是资产也是负债。它的类名体系让新人一天就能上手,但也让所有 Bootstrap 站点长得像亲戚;想彻底摆脱"Bootstrap 味",你得改 SCSS 变量、重写圆角阴影,成本并不低。
  2. Tailwind 的长期成本在约定,不在语法。它没有帮你做任何设计决策:色板要选、间距刻度要定、组件要封装(cva、clsx、@apply 或 React 组件)。没有这层约定,半年后的模板会变成一堵 class 墙。

十二、选型建议

场景

推荐

理由

后台管理系统、内部工具

Bootstrap

组件最多,表格/表单/模态框一次到位,交付最快

官网、落地页、内容型页面

Bulma 或 Tailwind

页面以展示为主,Bootstrap 的 JS 用不上

有设计稿、要还原度、长期迭代的 C 端产品

Tailwind

token 化 + 任意值,最贴近设计系统

团队 CSS 弱、只想少写样式和 JS

Bulma

语义化类名 + 零 JS,读起来就像 HTML

快速原型 / Demo 给客户看

Bootstrap 或 Tailwind + shadcn

出效果最快

老项目增量改造

Bootstrap 单组件定制,或 Tailwind 局部引入

都能按模块引入,不必整体迁移

追求极致首屏性能的静态站

Tailwind 构建产物

只为用到的类生成 CSS,可压到最小

三条经验法则:

  • 交互组件数量决定 Bootstrap 的性价比——超过 5 个可交互组件,它几乎稳赢。
  • 设计独特性要求决定 Tailwind 的价值——如果产品必须"不像任何模板",Tailwind 的自由度就是刚需。
  • 团队 CSS 水平与维护周期决定 Bulma 是否够用——页面简单、人手少,它最省心;要长期演进的组件体系,它容易碰到天花板。

也可以混着用:Tailwind 写页面 + Headless UI/Radix 管交互;Bootstrap 只定制 SCSS 变量当组件库;Bulma 配少量自写 JS 做轻量站点。框架不是阵营,是成本结构。

十三、结论

三份页面演示的是同一批 UI,但把它们并排放在一起时,差别不在"哪个更好看",而在你把成本付给了谁:

  • Bootstrap 让你把成本付给体积和"同质化",换回组件与交互;
  • Bulma 让你把成本付给自写 JS 和自建组件,换回干净可读的 HTML;
  • Tailwind 让你把成本付给模板长度与团队约定,换回最小的产物和最大的设计自由。

如果今天要重做这套案例页:交互密集的管理后台我会选 Bootstrap;内容型站点选 Bulma;有设计系统、要长期演进的产品选 Tailwind。没有最好的框架,只有最合适的约束。

附:怎么复现

查看对比页

  1. 双击 index.html:三栏 iframe 会自动加载三份案例页(首次需联网拉 CDN)。
  2. 顶部工具栏可以切换「并排 / 堆叠」、勾选显示哪几个框架、缩放 50%~100%、切换本页暗黑模式。
  3. 每列下方是章节跳转按钮、刷新按钮和"新窗口打开"。
  4. 「同步滚动」需要同源环境:在 file:// 下浏览器禁止跨文档访问,页面会自动提示降级。用同目录的 启动本地服务.cmd 以 http://localhost:8931/ 打开即可启用同步滚动与章节即时跳转。

测量方法

  1. 体积:用 Node 从 jsdelivr 拉取对应版本文件,统计原始字节与 gzip(level 9)字节。
  2. Tailwind 生产形态:用 Edge 无头浏览器打开 tailwind-showcase.html,等浏览器端编译完成后提取注入的样式表,再用 lightningcss 压缩得到上面的数字。
  3. 行数 / dark: 计数:脚本统计三份 HTML 的行数与正则匹配数量。

数据采集于 2026-10-16,版本为当日 CDN 最新稳定版:Bootstrap 5.3.8、Bulma 1.0.4、Tailwind CSS 4.3.3,三者均为 MIT 许可。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、这篇文章从哪来
  • 二、三种设计哲学:你买到的"交付物"不一样
  • 三、同一个按钮,三种写法
  • 四、样式能力:栅格、间距、颜色、排版
  • 五、组件覆盖:这是最大的分水岭
  • 六、交互:谁在替你写 JavaScript
  • 七、暗黑模式:三条完全不同的路线
  • 八、体积:真实数字
  • 九、响应式与断点
  • 十、可访问性:框架替你做了多少
  • 十一、工程化与长期维护
  • 十二、选型建议
  • 十三、结论
  • 附:怎么复现
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档