1. 为什么选择 BulmaFlexbox 的价值还原很多人第一次见到 Bulma第一反应是“又一个 CSS 框架”。但真正上手之后你会发现它和 Bootstrap 那套东西完全是两种思路。Bulma 的一切都建立在 Flexbox 之上意味着你不需要去记忆一大堆栅格偏移类名也不用为了一个垂直居中写三行 hack。我从 2017 年开始在几个中大型项目里使用 Bulma最直观的感受是它的布局思维非常接近开发者大脑的工作方式。1.1 Flexbox 在 Bulma 中的核心地位Flexbox 是一个一维布局模型它处理的是“一个方向上怎么排”的问题。Bulma 把 Flexbox 用到了极致columns是 flex 容器column是 flex 项目is-flex系列工具类直接暴露底层能力。对比传统 float 布局经常遇到的父元素塌陷问题、inline-block 带来的空格间隙Flexbox 天生没有这些毛病。.columns { display: flex; flex-wrap: wrap; margin-left: -0.75rem; margin-right: -0.75rem; } .column { flex: 1; padding-left: 0.75rem; padding-right: 0.75rem; }这段是 Bulma 栅格最核心的代码看似简单但背后的逻辑很值得琢磨。flex: 1是flex: 1 1 0%的缩写表示项目可以拉伸、可以收缩、初始尺寸为 0。这意味着所有.column默认平分容器宽度不需要你指定列数。如果你想让某个列占两倍宽度加一个is-half或者is-two-thirds修饰类即可。这种“默认等分 按需覆盖”的设计比 Bootstrap 那种“必须显式指定 col-md-6”要省心得多。注意margin-left: -0.75rem这个负边距很关键。栅格嵌套时如果你写过.columns套.columns的复杂布局会发现这个负边距能抵消最外层容器的 padding保证列间距始终一致。不建议私自去掉。1.2 对比其他方案的选型逻辑我用过 Bootstrap 4也用过 Tailwind CSS最后在部分项目里仍然坚持 Bulma核心原因是它站在了一个很好的中间位置。第一Bootstrap 是个“重框架”。它自带 jQuery 插件生态组件齐全但样式辨识度高改主题要覆盖大量 Sass 变量。Bulma 不捆绑任何 JavaScript组件只有样式层——Modal 的显隐你说了算Dropdown 的弹出逻辑你自己写。自由度大了很多。第二Tailwind CSS 是个“工具集”。它给你原子类比如flex、p-4、text-center组合自由度极高但同时意味着你需要在 HTML 里堆大量类名。Bulma 的类名是语义化的is-primary、is-large、is-rounded读代码时像在读英语句子理解成本低很多。第三Bulma 的响应式断点是移动优先的。它默认样式针对小屏幕然后通过is-tablet、is-desktop、is-widescreen逐级增强。这套体系和现代 CSS 的min-width媒体查询思路完全一致你写样式时不需要先考虑桌面再考虑手机反过来先做移动端反而更顺手。2. Bulma 核心设计解析从栅格到实用类2.1 栅格系统columns 的灵魂Bulma 的栅格没有.row和.col-md-6的分别只有一个.columns容器加无数个.column子元素。这种统一性带来一个极大好处嵌套布局的心理负担几乎为零。div classcolumns div classcolumn1/2/div div classcolumn1/2/div /div div classcolumns div classcolumn is-two-thirds2/3/div div classcolumn1/3/div /div如果你要控制具体列宽Bulma 提供的修饰类有十几种is-three-quarters、is-two-thirds、is-half、is-one-third、is-one-quarter、is-full以及is-narrow。其中is-narrow是很多新手容易忽略的——它让列宽度由内容决定而不是等分。这个类在处理侧边栏 主内容布局时特别好用侧边栏固定宽度主内容自动占满剩余空间。响应式层面columns默认在小屏幕上堆叠但你可以在列上单独指定断点is-half-tablet、is-one-third-desktop、is-one-quarter-widescreen。这样写出来的布局代码很像在描述一种“弹性分配规则”而不是写死一套网格模板。2.2 组件与修饰类的搭配节奏Bulma 的组件类名非常直白button、card、navbar、tabs、message、notification、modal。样式修饰几乎全部通过is-前缀完成颜色用is-primary、is-info、is-success、is-warning、is-danger尺寸用is-small、is-normal、is-medium、is-large。一个典型的操作是按钮与徽章的混合button classbutton is-success is-medium span classicon i classfas fa-check/i /span span保存设置/span span classtag is-light ml-2v2.1/span /buttonicon类和tag类是 Bulma 的比较讨巧的小设计因为这两个类自身不具备完整视觉样式需要配合其他类才能正确渲染。比如icon要放在button、field或navbar-item里才能借到继承的尺寸单独拿出来会显得突兀。这个特性看似简单却让整个组件体系的组合维度大大提升。另一个比较强大的实用工具是level组件。它专门处理横向对齐左侧一组元素、右侧一组元素中间用垂直间隔分开。div classlevel div classlevel-left div classlevel-item标题/div /div div classlevel-right div classlevel-item button classbutton is-primary导出/button /div /div /divlevel-item默认在水平方向等距排列在移动端自动堆叠。这套机制解决了导航栏、操作栏、页脚信息条这类高频场景的对齐需求而且代码量极低。2.3 视觉设计与定制思路Bulma 的默认视觉走的是极简路线大量留白、圆角适中、边框轻盈。这既是优点也是需要注意的地方。如果你直接套用页面会显得有点“素”。解决方式不是推翻重写而是利用 Sass 变量体系中丰富的配置项做定制。Bulma 的所有基础颜色、字体、尺寸、间距都定义成 Sass 变量。你可能需要修改的变量包括$primary、$navbar-background-color、$card-shadow、$radius、$family-sans-serif。用 Bulma 的官方定制页面导出一份自定义bulma.sass即可。// 你自己的 bulma.sass charset utf-8; $primary: #4a6cf7; $link: #3b82f6; $family-sans-serif: Inter, PingFang SC, Microsoft YaHei, sans-serif; $radius: 6px; import bulma/bulma.sass;这样的定制结果就是整个页面的颜色体系和字体统一但几乎所有布局能力都保留下来。你不必一个文件一个文件地写覆盖样式框架级别就完成了品牌化改造。3. 响应式开发实操从页面骨架到细节打磨3.1 快速搭建一个响应式页面骨架用一个真实案例来演示一个通用后台管理页要求顶部导航、左侧栏、右侧内容区、底部信息条并且在手机上自动折叠成单列。用 Bulma 写的话核心代码量非常少。!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title通用后台管理/title link relstylesheet hrefhttps://cdn.jsdelivr.net/npm/bulma1.0.2/css/bulma.min.css /head body nav classnavbar rolenavigation aria-labelmain navigation div classnavbar-brand a classnavbar-item href#strongAdminLite/strong/a a classnavbar-burger>div classnotification is-primary div classtitle>// 数字滚动动画 const counters document.querySelectorAll([data-target]); counters.forEach(counter { const target counter.dataset.target; const duration 1000; const start performance.now(); function update(now) { const progress Math.min((now - start) / duration, 1); counter.textContent String(Math.floor(progress * target)); if (progress 1) { requestAnimationFrame(update); } else { counter.textContent String(target); } } requestAnimationFrame(update); });这个效果背后的原理非常简单requestAnimationFrame按帧回调通过progress计算当前应显示的数字。页面性能不会受太大影响视觉效果却提升不少。第二个是图片和文字一行对齐。这个需求经常出现在卡片标题、列表项中。如果你不用工具类光靠 vertical-align 很容易踩坑。最稳妥的方案是给图文的公共父容器加display: flex并让文字部分用align-items: center。在 Bulma 里你直接用is-flex和is-align-items-center这两个工具类问题就解决了。div classis-flex is-align-items-center figure classimage is-48x48 mr-2 img srcavatar.png alt头像 /figure div p classis-size-5张三/p p classis-size-7 has-text-grey产品经理/p /div /div第三个是流光边框与涟漪光圈扩散。这两个效果都属于典型的视觉加分项实现也很简单。流光边框仅用 CSS 就能实现.card--shimmer { position: relative; overflow: hidden; } .card--shimmer::after { content: ; position: absolute; top: 0; left: -150%; width: 120%; height: 100%; background: linear-gradient( 100deg, transparent 20%, rgba(255, 255, 255, 0.4) 50%, transparent 80% ); animation: shimmer 2.5s infinite; } keyframes shimmer { from { left: -150%; } to { left: 150%; } }涟漪光圈扩散通常用在按钮点击反馈上.ripple { position: relative; overflow: hidden; } .ripple::after { content: ; position: absolute; width: 20px; height: 20px; border-radius: 50%; background: rgba(255, 255, 255, 0.6); opacity: 0; transform: scale(0); transition: transform 0.5s ease-out, opacity 0.5s ease-out; } .ripple:active::after { transform: scale(10); opacity: 1; transition: 0s; }这类小效果加在 Bulma 的button上只需要在原有类名基础上追加一个自定义类完全不影响 Bulma 本身的样式。这就是框架类与自定义工具类组合使用的优点你可以按需扩展。3.3 自定义字体与 CSS 样式的引入方式很多新手在引入外部 CSS 时纠结该用link还是import甚至困惑 CSS 文件里要不要写style标签。这里一次性讲清楚。CSS 文件本身就是纯样式表不需要也不能包含style标签。style是 HTML 里的标签用于在当前页面内直接写样式。当样式量少、且只在一个页面使用时直接写在style里是合适的。当样式需要在多个页面复用时就把它抽成独立.css文件然后用link引入。字体加载同理。你可以用link引入 Google Fonts 的样式表再在自己的 CSS 中指定字体族。以中文网站的常见做法为例link relpreconnect hrefhttps://fonts.googleapis.com link relpreconnect hrefhttps://fonts.gstatic.com crossorigin link hrefhttps://fonts.googleapis.com/css2?familyInter:wght400;500;700displayswap relstylesheetbody { font-family: Inter, PingFang SC, Microsoft YaHei, sans-serif; }这里要提醒一句中文字体文件体积很大不建议直接用font-face引入整个中文 woff2 文件那会让首屏加载变慢。通常做法是西文用网络字体中文用系统字体栈的兜底方案。4. 常见问题排查与避坑实录4.1 布局不生效的排查路径有不少人问“为什么我加了columns但它没有等分排列”。排查思路其实很标准。第一步检查 HTML 结构。.column必须直接放在.columns内中间不能插入别的标签因为flex容器只对直接子元素生效。第二步检查是否自己写了覆盖样式。有时候项目里混用了 Bootstrapdisplay: block把 flex 效果覆盖了。用浏览器开发工具看计算样式确认display是不是flex。第三步检查是否有未闭合标签。一个漏掉的/div会把 DOM 结构打乱导致 flex 布局完全失效。这是最常见的“看起来样式写对了就是没反应”的原因之一。第四步检查 CDN 版本。Bulma 0.9.x 和 1.0.x 之间有一些类名差异尤其是button的颜色系统。如果在 1.0 版本下用了老代码里常见的is-outlined你会发现样式对不上。建议统一锁定版本不要混用 CDN 来源。4.2 自定义样式与 Bulma 冲突的处理当你写了自定义 CSS 后发现 Bulma 的组件样式被意外覆盖或者反过来你写的样式被框架覆盖。这背后涉及 CSS 优先级和层叠规则。最直接的解决方案是提高选择器特异性而不是在后面拼命加!important。比如你想把某个.card的阴影调大不要写.card { box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); }因为它的特异性为 0,1,0。如果 Bulma 自己的.card规则特异性相同那后加载的样式可能会输给框架内部顺序。正确的做法是给目标区域加一个额外类名.card--featured { box-shadow: 0 10px 30px rgba(74, 108, 247, 0.3); }然后在 HTML 中写classcard card--featured特异性仍然是 0,2,0但语义更清晰也不容易误伤其他卡片。提示对 Mobile 和 Desktop 分别做视觉验证非常重要。Bulma 的is-hidden-mobile、is-hidden-tablet、is-hidden-desktop这些工具类可以灵活控制显示范围但不要用得太碎否则维护时会非常痛苦。我见过一个项目里同时出现is-hidden-tablet和is-hidden-desktop的条目意图模糊后期完全没人敢动。4.3 性能与构建优化Bulma 要按需引入才能在大型项目中保持体积可控。完整版 CSS 压缩后大约 200KB 左右对移动端来说还是偏大。一个常见优化是只引入部分 Sass 文件。// 按需加载 Bulma 模块 import bulma/sass/utilities/_all.sass; import bulma/sass/base/_all.sass; import bulma/sass/components/_all.sass; import bulma/sass/elements/_all.sass; import bulma/sass/form/_all.sass; import bulma/sass/grid/_all.sass; import bulma/sass/helpers/_all.sass; import bulma/sass/layout/_all.sass;如果你用 Webpack、Vite 这类构建工具建议只在业务代码里引入需要的组件模块。例如项目只用到了按钮、表单、导航栏那就可以只引这几个模块省掉卡片、模态框等无用的样式。另一方面压缩 CSS 文件是基础操作但也别忽视HTTP 缓存的策略。用 CDN 或带 hash 的静态资源文件名都能显著减少重复加载的带宽消耗。4.4 细节经验文本定位与删除线页面细节方面文本定位和装饰效果是高频需求。怎么调整 CSS 容器里的文本位置这个需求本质是理解盒模型居中。块级元素的水平居中用margin: 0 auto垂直方向用flex或line-height。文本自身的水平对齐用text-align行内元素之间的位置关系用vertical-align或 flex 的align-items。比如在一个卡片里让文字垂直居中.notification { display: flex; align-items: center; justify-content: center; min-height: 80px; }删除线在 Bulma 中可以直接用工具类has-text-strikethrough或者自定义 CSS.text-strikethrough { text-decoration: line-through; text-decoration-color: #e74c3c; text-decoration-thickness: 2px; }在展示原价与折扣价的场景中这种样式很实用。注意text-decoration-color可以让删除线和正文颜色有所区分视觉上更清晰。5. 最后的实操心得与扩展建议在实际项目里我最常遇到的场景不是“Bulma 不好用”而是团队对“是否引入框架”这件事纠结太久。这里我可以给出一点个人判断如果你的项目有大量定制化 UIBulma 会让你省力不少因为它的基础类非常克制定制空间大。但如果项目是纯组件化开发每个页面有大量独特交互可能 Tailwind 这类原子化方案更合适。选择框架不是选“最好的”而是选“最不碍事的”。Bulma 本身还在持续迭代社区生态虽不如 Bootstrap 庞大但胜在轻巧专注。它的文档质量也很高让你能快速找到组件示例。想要更进一步的话建议自己动手写一个纯 CSS 的 Flexbox 布局小项目不依赖任何框架去体会 Flexbox 的排列、对齐、空间分配规则。当你理解了flex到底在控制什么之后用 Bulma 就不仅仅是“会调用类名”而是真正掌握了它的底层逻辑。最后再分享一个小技巧把is-flex、is-align-items-center、is-justify-content-space-between这类高频实用类记熟能大幅减少自定义 CSS 的数量。在页面复杂度不高时甚至只需要组合这些类就能完成九成以上的布局需求。不要急于写自定义样式先用 Bulma 的现有能力凑齐布局再按需微调。你会发现这套流程既快又稳正是 Bulma 这类框架存在的真正价值。
阅读完成 · 觉得有帮助?