Emmet教程:快速编写HTML的缩写语法详解
缩写语法
Emmet 使用类似于 CSS 选择器的语法来描述生成的树结构中元素的位置以及元素的属性。
元素
你可以使用像 div 或 p 这样的元素名称来生成 HTML 标签。Emmet 没有预定义可用的标签名称集,你可以编写任何单词并将其转换为标签:div → <div></div>,foo → <foo></foo>,依此类推。
嵌套运算符
嵌套运算符用于定位生成树中缩写元素的位置:它应该被放置在上下文元素内部还是其旁边。
子元素:>
你可以使用 > 运算符将元素嵌套在彼此内部
div>ul>li
...将产生
<div> <ul> <li></li> </ul></div>
兄弟元素:+
使用 + 运算符将元素放置在彼此旁边,处于同一层级
div+p+bq
...将输出
<div></div><p></p><blockquote></blockquote>
向上跳出:^
使用 > 运算符,你是在向生成的树结构下方深入,所有后续兄弟元素的位置都将基于最深处的元素来解析
div+div>p>span+em
...将被展开为
<div></div><div> <p><span></span><em></em></p></div>
使用 ^ 运算符,你可以向树结构上方跳出一层,并更改后续元素应出现的上下文位置
div+div>p>span+em^bq
...输出为
<div></div><div> <p><span></span><em></em></p> <blockquote></blockquote></div>
你可以根据需要使用任意数量的 ^ 运算符,每个运算符都会向上移动一层
div+div>p>span+em^^^bq
...将输出为
<div></div><div> <p><span></span><em></em></p></div><blockquote></blockquote>
乘法:*
使用 * 运算符,你可以定义元素应输出多少次
ul>li*5
...输出为
<ul> <li></li> <li></li> <li></li> <li></li> <li></li></ul>
分组:()
圆括号被 Emmet 的高级用户用于在复杂的缩写中对子树进行分组
div>(header>ul>li*2>a)+footer>p
...展开为
<div> <header> <ul> <li><a href=""></a></li> <li><a href=""></a></li> </ul> </header> <footer> <p></p> </footer></div>
如果你是在处理浏览器的 DOM,你可以将分组视为文档片段(Document Fragments):每个组包含缩写子树,并且所有后续元素都插入到与该组第一个元素相同的层级。
你可以将组嵌套在一起,并结合乘法 * 运算符使用
(div>dl>(dt+dd)*3)+footer>p
...产生
<div> <dl> <dt></dt> <dd></dd> <dt></dt> <dd></dd> <dt></dt> <dd></dd> </dl></div><footer> <p></p></footer>
通过分组,你甚至可以用一个缩写写出完整的页面标记,但请尽量不要这样做。
属性运算符
属性运算符用于修改输出元素的属性。例如,在 HTML 和 XML 中,你可以快速向生成的元素添加 class 属性。
ID 和 CLASS
在 CSS 中,你使用 elem#id 和 elem.class 表示法来访问具有指定 id 或 class 属性的元素。在 Emmet 中,你可以使用完全相同的语法来添加这些属性到指定的元素
div#header+div.page+div#footer.class1.class2.class3
...将输出
<div id="header"></div><div></div><div id="footer" class="class1 class2 class3"></div>
自定义属性
你可以使用 [attr] 表示法(类似于 CSS)向元素添加自定义属性
td[title="Hello world!" colspan=3]
...输出
<td title="Hello world!" colspan="3"></td>
你可以在方括号内放置任意数量的属性。
你不必指定属性值:
td[colspan title]将产生<td colspan="" title="">,并在每个空属性内包含制表位(如果你的编辑器支持的话)。你可以使用单引号或双引号来引用属性值。
如果属性值不包含空格,则无需加引号:
td[title=hello colspan=3]即可工作。
项目编号:$
使用乘法 * 运算符可以重复元素,而使用 $ 则可以对它们进行编号。将 $ 运算符放在元素名称、属性名称或属性值中,以输出重复元素的当前编号
ul>li.item$*5
...输出为
<ul> <li></li> <li></li> <li></li> <li></li> <li></li></ul>
你可以连续使用多个 $ 来对数字进行补零
ul>li.item$$$*5
...输出为
<ul> <li></li> <li></li> <li></li> <li></li> <li></li></ul>
更改编号基数和方向
使用 @ 修饰符,你可以更改编号方向(升序或降序)和基数(例如起始值)。
例如,要更改方向,请在 $ 后面添加 @-
ul>li.item$@-*5
…输出为
<ul> <li></li> <li></li> <li></li> <li></li> <li></li></ul>
要更改计数器基数值,请在 $ 后面添加 @N 修饰符
ul>li.item$@3*5
…转换为
<ul> <li></li> <li></li> <li></li> <li></li> <li></li></ul>
你可以同时使用这些修饰符
ul>li.item$@-3*5
…转换为
<ul> <li></li> <li></li> <li></li> <li></li> <li></li></ul>
文本:{}
你可以使用花括号将文本添加到元素中
a{Click me}...将产生
<a href="">Click me</a>
请注意,{text} 被用作并解析为一个单独的元素(像 div, p 等),但在紧跟元素之后编写时具有特殊含义。例如,a{click} 和 a>{click} 将产生相同的输出,但 a{click}+b{here} 和 a>{click}+b{here} 则不会
<!-- a{click}+b{here} --><a href="">click</a><b>here</b><!-- a>{click}+b{here} --><a href="">click<b>here</b></a>在第二个示例中,<b> 元素被放置在 <a> 元素内部。这就是区别:当 {text} 写在元素后面时,它不会改变父级上下文。这里有一个更复杂的示例展示了为什么这很重要
p>{Click }+a{here}+{ to continue}...产生
<p>Click <a href="">here</a> to continue</p>
在这个示例中,为了在 <p> 元素内部写入 Click here to continue,我们需要在 p 后面显式地使用 > 运算符向下移动树结构;但在 a 元素的情况下,我们不需要这样做,因为我们只需要包含单词 here 的 <a> 元素,而不改变父级上下文。
作为比较,这是不使用子元素 > 运算符编写的相同缩写
p{Click }+a{here}+{ to continue}...产生
<p>Click </p><a href="">here</a> to continue
关于缩写格式的说明
当你熟悉了 Emmet 的缩写语法后,你可能想使用一些格式来使缩写更具可读性。例如,在元素和运算符之间使用空格,像这样
(header > ul.nav > li*5) + footer
但这行不通,因为空格是 Emmet 停止解析缩写的停止符号。
许多用户错误地认为每个缩写都应该写在单独的一行,但他们错了:你可以在文本中的任何位置输入并展开缩写
Play againTry it yourself
<body></body>
这就是为什么 Emmet 需要一些指示符(如空格)来标记停止解析的位置,以免展开你不想要的内容。如果你仍然认为这种格式对于复杂缩写是必需的,以使它们更易读
缩写不是模板语言,它们不需要“可读”,它们需要的是“快速展开和删除”。
你其实并不需要编写复杂的缩写。不要认为“打字”是 Web 开发中最慢的过程。你很快就会发现,构建一个复杂的单个缩写要比构建并输入几个简短的缩写慢得多,且更容易出错。