Emmet: 文本 `{text}` 与多 `$` 编号补零:文案填充与多位补零

前 8 课你学会了 Emmet 的 8 个 HTML 结构操作符(> + ^ * () .class #id [attr])和 1 个编号操作符($)。但有两类"语义"场景没解决——"按钮里塞 'Click me'"和"10 张卡片每张文案带 001、002"。前者靠 {text} 文本填充,后者靠$ 补零。本课把这两个操作符组合起来,让你的简写从"造结构"升级到"造内容"。

1. 你将学到


2. 一个前端开发者的真实故事

(1) 痛点:标签造完了,文案还是要逐字手敲

Alice 在做产品落地页的"特性展示"区,需要 6 张卡片,每张卡片包含图标、标题、描述、按钮。她先用第 06 课的 () 和隐式标签写好了卡片结构:

TEXT 📖 仅展示
section.features>(.card*6>i.icon+h3+p+button.btn)

结构 1 行就搞定了,Emmet 展开 6 张 card,每张含 icon、h3、p、button。但接下来 Alice 要给每张卡片写文案:标题"高性能"、"易用"、"可扩展"、"安全"、"跨平台"、"开源",描述每张 30 字,按钮文案"了解更多"重复 6 次。

Alice 一开始是手敲——展开后的 HTML 30+ 行空白标签,她逐个填文案。光填标题就花了 5 分钟,描述又 10 分钟,最后按钮"了解更多"敲了 6 遍(直接复制粘贴)。

更要命的是分页页码:100 页产品列表,每页底部有 <li>第 1 页</li><li>第 100 页</li>,Alice 写完 30 行就崩溃了。她试着用 $(ul.pagination>li>a{第 $ 页})*100——展开后是 第 1 页第 100 页,但前 9 页都是"第 1 页"、"第 2 页"这种单字符数字,看起来像 bug。她想要"01"、"02"、...、"99"、"100"——必须前 9 页两位补零、最后 10 页正常显示。

(2) {text} 与多 $ 补零的解法

Emmet 提供两个互补机制解决 Alice 的问题:

文本填充 {text}:把花括号内的内容作为标签的文本节点插入。Alice 的 6 张卡片可以这么写:

TEXT 📖 仅展示
section.features>(.card*6>(i.icon)+h3{高性能}+p{这是第一张描述}+button.btn{了解更多})

但 6 张卡片每张文案不同,*6 不能简单重复文案——这时需要循环模板,配合 $ 编号使用。

编号 $ 与多位补零$ 是当前序号,$$ 补零到 2 位,$$$ 补零到 3 位。Alice 的分页页码可以这么写:

TEXT 📖 仅展示
(ul.pagination>li>a{第 $$ 页})*100

展开后是 第 01 页第 02 页、...、第 99 页第 100 页——前 9 页自动补零到 2 位,第 10 页起正常显示。

Alice 用一行简写重写整个特性区:

TEXT 📖 仅展示
section.features>(h2{产品特性})+((.card>(i.icon)+h3{特性 $}+p{这是第 $ 个特性,共 6 个}+button.btn{了解更多})*6)

100 行分页:

TEXT 📖 仅展示
(ul.pagination>li>a{第 $$ 页})*100

Alice 验证之后惊呼:"6 张卡片的文案从 30 行手写降到 1 行,100 行分页从 200 行降到 1 行。Emmet 在'批量造内容'场景的提效是 50 倍以上。"

(3) 收益

{text} 和多 $ 补零是 Emmet 处理"文案工厂化"的核心。前者让你在简写里直接写文案(不用展开后再填),后者让重复元素的序号自动跑、补零、起始、倒序。学完本课,Alice 写 6 张特性卡片只要 15 秒,100 行分页只要 10 秒;同时这一课也是 Phase 3 的第一课——下一课将进入 Lorem Ipsum 占位文案与隐式标签细节。


3. 文本填充 {text} 的定义

{text} 是 Emmet 给标签插入文本节点的语法。写在花括号内的内容会原样成为标签内部的文本——可以是任意字符(包括中文、空格、标点)。

(1) 简写规则

简写 展开结果 说明
a{Click me} <a href="">Click me</a> 单标签 + 单段文案
p{Hello world} <p>Hello world</p> p 标签 + 文案
button{提交} <button>提交</button> 中英文案均可
a{<strong>bold</strong>} <a href="">&lt;strong&gt;bold&lt;/strong&gt;</a> < > 自动转义为 HTML 实体
📌 重点: {text} 中的特殊字符(< > &)会被 Emmet 自动转义为 HTML 实体(&lt; &gt; &amp;)。这是 HTML5 安全要求——避免用户输入的尖括号破坏文档结构。如果你想插入真正的 HTML 标签(如让 <strong> 被解析为标签而非文本),需要用第 13 课的"过滤器"或直接展开后手动修改。

(2) {text} 在标签内的位置

位置 简写 展开
紧跟标签名 a{Click me} <a href="">Click me</a>
配合 > 嵌套 p>{Click }+a{here} <p>Click <a href="">here</a></p>
单独 {text} { to continue} to continue(裸文本,作为独立元素)
配合 $ 编号 li{item $}*3 <li>item 1</li><li>item 2</li><li>item 3</li>

4. {text} 的两种位置:紧邻父级 vs 嵌套

这是 Emmet 文本填充最精妙的设计。{text} 紧跟标签名时,不改变父级上下文;但 >{text} 会把上下文推进一层。两者的区别是新手最常踩的坑。

(1) 紧邻模式 a{click}+b{here}

{text} 紧跟在标签名(无 > 前缀)后,文本被视为该标签的直接子节点,但不改变父级上下文——这意味着后续的 + 兄弟元素仍然和当前标签在同一层。

HTML
a{click}+b{here}
HTML
<a href="">click</a><b>here</b>

(2) 嵌套模式 a>{click}+b{here}

{text} 前加 > 时,Emmet 把 > 后的 {text} 视为子元素,并且把父级上下文推进到 a 内部——后续的 + 兄弟元素在 a 内部追加。

HTML
a>{click}+b{here}
HTML
<a href="">click<b>here</b></a>

(3) 多元素混合文本 p{Click }+a{here}+{ to continue}

这个官方文档的经典案例展示两种模式的差异:

HTML
p{Click }+a{here}+{ to continue}
HTML
<p>Click </p>
<a href="">here</a> to continue
HTML
p>{Click }+a{here}+{ to continue}
HTML
<p>Click <a href="">here</a> to continue</p>
📌 重点: 第一个简写(紧邻模式)产生了 3 个根级元素(p、a、裸文本),而第二个(嵌套模式)把"Click here to continue"完整放进 <p> 内。差异来自 >:第一版的 {Click } 让 p 变成"有 click 文案的 p"(不再下钻),第二版的 >{Click } 让上下文从 p 推进到 p 内部,后续 +a{here}+{ to continue} 都在 p 内部追加。

▶ 示例:基础文本填充 a{Click me}(难度⭐)

Emmet 官方文档的首个文本填充案例——给 a 标签加一段文案。

缩写:

HTML
a{Click me}

展开:

HTML
<a href="">Click me</a>

输出:

TEXT 📖 仅展示
解析:a 是标签名(默认带 href=""),{Click me} 是文本节点。Emmet 自动为 a 添加 href="" 属性(HTML5 默认行为),文本 "Click me" 作为 a 的子节点。注意:a 标签后的 {text} 不会改变父级上下文——如果后面接 +b{some},b 会与 a 平级,而不是 a 的子节点。

▶ 示例:多元素混合文本 p>{Click }+a{here}+{ to continue}(难度⭐⭐)

用嵌套模式把"Click here to continue"完整放进 <p> 内。

缩写:

HTML
p>{Click }+a{here}+{ to continue}

展开:

HTML
<p>Click <a href="">here</a> to continue</p>

输出:

TEXT 📖 仅展示
解析:p>{Click } 让上下文推进到 p 内部,"Click " 是 p 的第一个文本子节点;+a{here} 在 p 内部追加一个带 "here" 文案的 a;+{ to continue} 在 p 内部追加裸文本 " to continue"。最终 p 内有 3 个子节点:文本 "Click "、a 标签、文本 " to continue"。如果不写 >(即 p{Click }+a{here}+{ to continue}),p 就只含 "Click ",a 和裸文本会成为根级兄弟——结果是 <p>Click </p> 后跟 <a>here</a> 和裸文本。

5. 编号 $ 与多位补零

$ 是 Emmet 的编号占位符(第 08 课已介绍)。本课扩展它的两个高阶用法:多位补零起始/反向控制

(1) 多位补零 $$ $$$ $$$$

第 08 课用单 $ 生成 1、2、3。当数字范围超过 9 时(如 100 行表格的序号),单 $ 会显示为 1、2、...、9、10、11(混合位数)。多位 $ 让编号自动补零到指定位数

$ 展开形态(*5 适用场景
$ 1, 2, 3, 4, 5 简单列表
$$ 01, 02, 03, 04, 05 小型列表、月份
$$$ 001, 002, 003, 004, 005 订单号、表格行 ID
$$$$ 0001, 0002, ... 千行以上表格、章节号
📌 重点: $ 的个数决定补零的最小位数。如果实际数字超过这个位数,Emmet 不截断——*12$$ 会展开为 01, 02, ..., 09, 10, 11, 12(前 9 个补零,后 3 个正常)。这是"补零位数 = 最小宽度"的语义。

(2) 起始值 $@N 与反向 $@-

默认编号从 1 升序。用 @N 改为从 N 开始,用 @- 改为降序:

修饰符 含义 示例(*5
$(默认) 升序,从 1 1, 2, 3, 4, 5
$@3 升序,从 3 开始 3, 4, 5, 6, 7
$@- 降序(迭代次数 → 1) 5, 4, 3, 2, 1
$@-3 降序,从 3 开始倒推 *5 → 7, 6, 5, 4, 3(按 @-3 起始值 3 + 降序,迭代次数叠加)
⚠️ 注意: $@-3 在 Emmet 1.2+ 支持;常见组合是 $@N(起始值)和 $@-(降序起始于迭代次数)。@N 中 N 是起始值,不是结束值。

▶ 示例:编号 + 文本 ul>li{item $}*3(难度⭐)

$ 嵌入 {text} 文本,让每个 li 文案带自动编号。

缩写:

HTML
ul>li{item $}*3

展开:

HTML
<ul>
  <li>item 1</li>
  <li>item 2</li>
  <li>item 3</li>
</ul>

输出:

TEXT 📖 仅展示
解析:li{item $} 是"li 标签 + 一段文本(item + 当前编号)",*3 让这个模板重复 3 次。每次重复,$ 被替换为当前迭代编号(1、2、3)。最终 3 个 li 各自包含一段 "item N" 文案。这是 Emmet 在"待办清单"、"特性列表"、"FAQ 序号"等场景的核心模式。注意:item 后有一个空格,这是文本的一部分(不是操作符)。

▶ 示例:补零 ul>li{$$}*5(难度⭐)

2 位补零——前 9 个元素自动补零,超过 9 正常显示。

缩写:

HTML
ul>li{$$}*5

展开:

HTML
<ul>
  <li>01</li>
  <li>02</li>
  <li>03</li>
  <li>04</li>
  <li>05</li>
</ul>

输出:

TEXT 📖 仅展示
解析:$$ 表示"当前编号用 2 位数字显示"。*5 让 li 重复 5 次,每次的 $ 值是 1、2、3、4、5——经过 2 位补零后变成 01、02、03、04、05。如果 *12,会展开为 01、02、...、09、10、11、12——前 9 个补零,后 3 个超过 2 位则正常显示(不截断)。补零场景:分页页码、月份、产品 SKU 编号。

▶ 示例:起始值 + 反向 ol>li{Step $@3}*5(难度⭐⭐)

从 3 开始升序的 5 步流程——用 $@3 控制起始值。

缩写:

HTML
ol>li{Step $@3}*5

展开:

HTML
<ol>
  <li>Step 3</li>
  <li>Step 4</li>
  <li>Step 5</li>
  <li>Step 6</li>
  <li>Step 7</li>
</ol>

输出:

TEXT 📖 仅展示
解析:$@3 表示"当前编号从 3 开始"。ol>li 让 li 成为 ol 的有序子项;{Step $@3} 是文本模板,"Step " 是固定字符串,$@3 是从 3 开始的当前编号。*5 让 li 重复 5 次,编号依次为 3、4、5、6、7。这是 Emmet 在"分页页码从某页开始"、"产品章节从第 3 章开始"、"步骤编号不从 1 开始"等场景的标准模式。如果想反向(从 5 降到 1),改用 $@-(基于迭代次数自动倒推)。

6. 完整示例:分页器 + 编号 + 文本填充

{text}、多 $ 补零、$@N 起始值组合起来——一个有 100 页的分页器,每页用 2 位补零显示。

▶ 示例:100 页分页器(难度⭐⭐)

缩写:

HTML
(ul.pagination>li.page$$>a{第 $$ 页})*100

展开(节选):

HTML
<ul class="pagination">
  <li class="page01"><a href="">第 01 页</a></li>
  <li class="page02"><a href="">第 02 页</a></li>
  <li class="page03"><a href="">第 03 页</a></li>
  <!-- ... -->
  <li class="page09"><a href="">第 09 页</a></li>
  <li class="page10"><a href="">第 10 页</a></li>
  <li class="page11"><a href="">第 11 页</a></li>
  <!-- ... -->
  <li class="page99"><a href="">第 99 页</a></li>
  <li class="page100"><a href="">第 100 页</a></li>
</ul>

输出:

TEXT 📖 仅展示
解析:本例综合了本课全部操作符——{} (文本填充)、$ (编号)、$$ (2 位补零)、() (分组)、* (乘法)、.class、> (嵌套)。外层括号让整个 li 模板成为可重复单元;li.page$$ 同时在 class 名和 {text} 中使用 $$,确保 class 和文案编号一致;a 标签作为 li 的子节点,文案是"第 XX 页"。注意:100 页分页的实际 HTML 有 100 个 li,本节选只展示前 3、9-11、99-100。补零位数 = 2:前 9 页是 01-09,第 10 页起超过 2 位则正常显示(10、11、...)。如果想要 3 位补零(001-100),改用 $$$。

❓ 常见问题

Q {text} 中写尖括号 < > 会被怎么处理?
A Emmet 自动转义为 HTML 实体——<&lt;>&gt;&&amp;。这是 HTML5 安全要求,避免用户输入破坏文档结构。所以 a{<strong>bold</strong>} 展开为 <a href="">&lt;strong&gt;bold&lt;/strong&gt;</a>(尖括号变成实体字符,浏览器显示为纯文本 "<strong>bold</strong>",不会解析为标签)。如果想插入真正的 HTML 标签,需要用过滤器或手动修改。
Q a{click}+b{here}a>{click}+b{here} 展开后有什么关键区别?
A 前者(紧邻模式)产生两个根级兄弟 <a>click</a><b>here</b>;后者(嵌套模式)把 <b> 嵌入 <a> 内:<a>click<b>here</b></a>。关键差异在 >:紧邻模式不改变父级上下文,嵌套模式把上下文推进一层。判断口诀——"花括号前有 > 就进一层,没有就保持原层"。这是 Emmet 文本填充最精妙的设计,新手必须掌握的边界。
Q $ 同一个 {text} 块内能多次出现吗?多个 $ 是同一编号还是不同编号?
A 可以多次出现,且同一个 {text} 块内的所有 $ 共享同一个编号(即当前迭代计数)。例如 li{item $: 第 $ 个}*3 展开为 <li>item 1: 第 1 个</li><li>item 2: 第 2 个</li><li>item 3: 第 3 个</li>。多个 $ 主要用于补零位数控制($ 显示原始编号、$$ 2 位补零、$$$ 3 位补零)。如果想让同一元素内的不同 $ 显示不同编号(如 i=1, j=2),需要嵌套多个 * 重复结构。
Q $@N 的 N 可以是负数吗?N=0 是什么意思?
A N 可以是负数或 0。$@-5*3 表示从 -5 开始升序(-5、-4、-3);$@0*3 表示从 0 开始升序(0、1、2)。但实际开发中很少用负数或 0 作为起始值(HTML 中负数序号无意义,0 作为起始会跳过 1)。常见用法:$@1 显式从 1 开始(与默认行为等价,但代码更明确)、$@100 从 100 开始(分页深页场景)。反向用 $@-,不要混用 $@-N

📖 小节


📝 作业

  1. 基础题(难度⭐):用一行 Emmet 简写分别展开为:(a) 一个 button{Sign Up} 标签;(b) 一个 <strong> 标签带文案 "Warning";(c) 一个 p>lorem 段落(即 <p>Lorem ipsum...</p>,本课不涉及,下课展开 Lorem)。
  2. 进阶题(难度⭐⭐):写一个 12 项"月份列表" ol>li{第 $$ 月}*12,验证展开结果(应为"第 01 月"到"第 12 月")。然后改写为"季度列表" ol>li{第 $ 季度}*4,验证编号为 1-4。再写一个"产品特性区",包含 5 张卡片,每张卡片有 <h3>Feature $</h3><p>Description for feature $</p>,要求完全用一行 Emmet 简写。
  3. 挑战题(难度⭐⭐⭐):编写一个 100 页分页器,每页用 3 位补零(第 001 页第 100 页)。要求:(a) class 用 page$$$(3 位补零);(b) 文本用 第 $$$ 页(3 位补零);(c) 起始页用 $@1(与默认行为一致但显式声明)。用一行 Emmet 简写验证展开结果,并解释为什么 $$$ 在超过 99 时不会截断为 3 位(提示:Emmet 补零 = 最小宽度,不是最大宽度)。
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏