首页
/ Bulma 0.9.2 新特性解析:用 `.icon-text` 让图标与文字保持完美对齐

Bulma 0.9.2 新特性解析:用 `.icon-text` 让图标与文字保持完美对齐

2026-09-05 09:42:22作者:尤峻淳Whitney

.icon-text 是 Bulma 自 0.9.2 版本起引入的轻量级组件,用于把 .icon 图标元素与文字组合在一起,并保证两部分在垂直方向上的正确对齐。本文基于仓库中的功能公告博文 icon-text 新特性博文,结合 sass/elements/icon.scss 源码实现与 Cypress 测试用例,完整讲解这一特性的用法、底层 CSS 原理、可定制变量以及验证方式,读完即可在自己的项目中正确使用并自定义 .icon-text

为什么需要 .icon-text

Bulma 的 .icon 元素从项目诞生之初就存在,它本质上是任何图标字体(icon font)的简单容器。由于 .icon 拥有固定的正方形尺寸,它能在图标字体加载完成的等待期内预先占住空间,避免页面出现布局跳动。

但当开发者想让一个图标紧挨着文字出现时(例如“🏠 Home”这样的标签),直接把 .icon 和文字拼在一起往往会出现基线错位的问题——图标容器的高度、行高与文字的行高不一致,视觉上就"漂"了。

从 Bulma 0.9.2 版本开始,CHANGELOG 中明确记录了这一新增特性:

New icon-text component, to combine an icon with text on its side

icon-text 的设计目的只有一个:在图标与文字的组合中保持二者正确的对齐,让开发者不必再手写 margin 或 vertical-align 去"找平"。

基本用法:一个图标加一段文字

最基础的用法是把一个 .icon 和一段文字一起包在 .icon-text 中,结构如下(即博文中的第一个示例):

<span class="icon-text">
  <span class="icon">
    <i class="fas fa-home"></i>
  </span>
  <span>Home</span>
</span>

关键点在于:文字部分必须单独包裹在自己的 <span> 里,不能直接裸露在 .icon-text 下。这一约束在官方文档 icon 元素文档 中同样被强调:"as long as all text inside is wrapped in its own span element"。

进阶用法:连续串联多个图标与文字

.icon-text 并不限于"一图标一文字",可以在其中串联任意多个图标与文字交替排列的序列。博文给出的完整示例如下——一条从巴黎到伊斯坦布尔的"列车路线":

<span class="icon-text">
  <span class="icon">
    <i class="fas fa-train"></i>
  </span>
  <span>Paris</span>
  <span class="icon">
    <i class="fas fa-arrow-right"></i>
  </span>
  <span>Budapest</span>
  <span class="icon">
    <i class="fas fa-arrow-right"></i>
  </span>
  <span>Bucharest</span>
  <span class="icon">
    <i class="fas fa-arrow-right"></i>
  </span>
  <span>Istanbul</span>
  <span class="icon">
    <i class="fas fa-flag-checkered"></i>
  </span>
</span>

官方文档中还展示了更多组合场景,例如把 icon-text 直接嵌进 .content 的段落文字中间(利用 inline-flex 特性实现行内插入),或者用 div 版本配合 has-text-infohas-text-successhas-text-warninghas-text-danger 等颜色修饰类做状态提示行。完整的 .icon-text 用法说明参见 icon 文档的 Icon text 一节

源码解析:对齐是如何实现的

打开 sass/elements/icon.scss.icon-text 的完整实现位于第 50–67 行,非常精炼:

.#{iv.$class-prefix}icon-text {
  align-items: flex-start;
  color: inherit;
  display: inline-flex;
  flex-wrap: wrap;
  gap: cv.getVar("icon-text-spacing");
  line-height: cv.getVar("icon-dimensions");
  vertical-align: top;

  .#{iv.$class-prefix}icon {
    flex-grow: 0;
    flex-shrink: 0;
  }
}

div.#{iv.$class-prefix}icon-text {
  display: flex;
}

逐条理解这几行声明,就能明白 Bulma 是怎么"免费"解决对齐问题的:

声明 作用
display: inline-flex icon-text 本身是行内级弹性容器,可以像普通文本一样插入到任意段落中;同时容器内部用 Flexbox 布局,图标与文字天然基线可控
line-height: $icon-dimensions(默认 1.5rem 把文字部分的行高固定为与图标容器相同的高度(默认 1.5rem),这是对齐成立的核心——图标高 1.5rem,文字行高也是 1.5rem,两者顶部自然齐平
align-items: flex-start 子项(图标与文字)顶部对齐,而不是默认的居中对齐
gap: $icon-text-spacing(默认 0.25em 图标与文字之间、以及连续多个子项之间自动保留 0.25em 的间距,开发者无需手写 margin
vertical-align: top 在行内文本流中,让整个 icon-text 与周围文字的顶部对齐
color: inherit 图标与文字继承父级颜色,方便通过父级或自身的 has-text-* 修饰类统一着色
flex-wrap: wrap 允许内容在窄容器中换行
子选择器 .icon { flex-grow: 0; flex-shrink: 0 } 锁定 .icon 的固有正方形尺寸,既不被拉伸也不被压缩
div.icon-text { display: flex } 当使用 div 而非 span 承载 icon-text 时(例如做整行的状态提示),自动升级为块级 flex 布局,占满整行

此外,.icon.icon-text 共用一组 CSS 变量注册(见 icon.scss 第 10–21 行),这为下面的自定义打下了基础。

尺寸变量与自定义:从 Sass 变量到 CSS 变量

iconicon-text 相关的 SASS 变量及其默认值定义在 sass/elements/icon.scss 第 4–8 行,并在 docs/_data/variables/elements/icon.json 中同步登记:

变量名 默认值 对应 CSS 变量 说明
$icon-dimensions 1.5rem --icon-dimensions 默认图标容器宽高
$icon-dimensions-small 1rem --icon-dimensions-small is-small 尺寸
$icon-dimensions-medium 2rem --icon-dimensions-medium is-medium 尺寸
$icon-dimensions-large 3rem --icon-dimensions-large is-large 尺寸
$icon-text-spacing 0.25em --icon-text-spacing 图标与文字之间的 gap

两种定制途径:

  1. 编译期(Sass 变量):在编译 Bulma 之前覆盖带 !default 的变量即可,例如把图标与文字的间距加大:

    $icon-text-spacing: 0.5em; // 覆盖默认 0.25em
    @import "bulma";
    
  2. 运行期(CSS 变量):由于 icon.scss 通过 cv.register-vars 把上述值注册为 CSS 变量,直接编译好的 bulma.css 也可以在运行时覆盖:

    .icon-text {
      --icon-text-spacing: 0.5em;
    }
    

    这一机制与仓库中 customize 文档 描述的"用 CSS 变量定制 Bulma"方式一致。

尺寸修饰类则作用于内部的 .iconis-small / is-medium / is-large 分别把图标容器设为 1rem / 2rem / 3rem(见 icon.scss 第 33–47 行)。注意 .icon-text 的行高取自 $icon-dimensions 而非具体某个尺寸档,因此在 icon-text 中使用特大号图标时,文字行高仍以默认档为准,实际排版效果可结合测试页 docs/cyp/elements/icon.html 验证。

测试佐证:Cypress 如何校验 icon-text

仓库自带的 E2E 测试 docs/cypress/e2e/elements/icon.spec.js.icon-text 的行为做了断言,正好印证了上面源码解析中的关键点:

it("has correct Icon Text elements", () => {
  cy.get("#icon-text").then(($) => {
    const cs = window.getComputedStyle($[0]);
    expect(cs.display).to.equal("inline-flex");
  });

  cy.get("#icon-text > .icon").then(($) => {
    const cs = window.getComputedStyle($[0]);
    expect(cs.marginRight).to.equal("4px");
  });

  cy.get("#icon-text-div").then(($) => {
    const cs = window.getComputedStyle($[0]);
    expect(cs.display).to.equal("flex");
  });
});

对应测试页面 docs/cyp/elements/icon.html 提供了 span#icon-textdiv#icon-text-div 两种形态。断言含义:span.icon-text 计算样式为 inline-flexdiv.icon-text 升级为 flex——与源码中 div.#{prefix}icon-text { display: flex } 的分支一一对应。(测试中对子图标 marginRight: 4px 的断言来自 0.9.2 早期以 margin 实现间距的版本,当前主干已改用 gap0.25em 在 16px 根字号下同样折约为 4px 的视觉间距。)同文件中的尺寸断言还顺带覆盖了图标四档尺寸:16px / 24px / 32px / 48px,即 is-small / 默认 / is-medium / is-large(见 icon.spec.js 第 18–42 行)。

编译产物中也能确认该特性已进入官方 CSS:css/bulma.css 中包含 .icon-text.icon-text .icondiv.icon-text 三条规则。

小结

  • .icon-text 自 Bulma 0.9.2 版本可用,是"图标 + 文字"组合的标准容器,核心价值是自动对齐inline-flex 布局 + 与图标同高的 line-height(默认 1.5rem)+ gap 间距(默认 0.25em)三管齐下。
  • 结构约束:文字必须各自包在 <span> 中;支持任意多个图标与文字串联;div 形态自动切换为整行 flex
  • 可定制点集中在 $icon-text-spacing$icon-dimensions* 五个 SASS 变量,编译后可通过同名 CSS 变量在运行时覆盖。
  • 实际行为可由 Cypress 测试测试页面 复现验证,深入用法参见 icon 官方文档
登录后查看全文
热门项目推荐
相关项目推荐