Emmet(原Zen Coding)文档

本文由清尘发表于2015-10-15 12:47最后修改于2020-04-20属于HTML/CSS分类

Emmet (即之前著名的 Zen Coding) 是一个网页开发者工具,可以大大地提高你的 HTML & CSS 开发效率。

基本上当下大多数文本编辑器可以重用常用的代码块,称为“代码片断”( snippets )。代码片断是提高生产效率的好办法,不过所有的实现都有共同的缺陷:要先定义代码片断并且不能实时展开。

Emmet 将代码片断的思想提升到全新的高度:书写类似于CSS的表达式,然后实时解析展开。Emmet 是为了HTML/XML与CSS而开发,也最适合用于它们,不过也能与编程语言一块使用。

缩写是 Emmet的核心:这些特殊的表达式被实时的解析转化为代码块。缩写的语法类似于 CSS 选择器,每个网页开发者都知道怎么用。

例如这个缩写:

#page>div.logo+ul#navigation>li*5>a{Item $}
<div id="page">
    <div class="logo"></div>
    <ul id="navigation">
        <li><a href="">Item 1</a></li>
        <li><a href="">Item 2</a></li>
        <li><a href="">Item 3</a></li>
        <li><a href="">Item 4</a></li>
        <li><a href="">Item 5</a></li>
    </ul>
</div>
div[class="title" id="title$"]*5>{title $}
<div class="title" id="title1">title 1</div>
<div class="title" id="title2">title 2</div>
<div class="title" id="title3">title 3</div>
<div class="title" id="title4">title 4</div>
<div class="title" id="title5">title 5</div>

许多编辑器(比如 Eclipse, Sublime Text 2, Espresso 等) 的插件也生成插入占位,使用 Tab 键可以快捷在这些重要的地方跳转。

缩写最适合于生成 HTML/XML,但是不限于此。下面开始学习语法来了解 Emmet 缩写的强大。

缩写语法

Emmet 使用类似于 CSS 选择器的语法来描述元素的结构与属性。


使用元素的名字,比如 div、 p 来生成 HTML 标签。 Emmet 没有预定义标签集合,所以可以用任意单词来生成对应的标签:div → 
, foo →

嵌套操作符
Child: > 子元素

div>ul>li
<div>
    <ul>
        <li></li>
    </ul>
</div>

Sibling: + 兄弟元素

div+p+bq
<div></div>
<p></p>
<blockquote></blockquote>

Climb-up: ^ 返回上层

> 操作符加深结构层次:

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>

Multiplication: * 乘法

ul>li*5
<ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
</ul>

Grouping: () 分组

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>

可以将分组当作 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>

使用分组后,可以用一个缩写来生成整个页面,不过不要这么做。

Attribute operators 属性操作符
ID and CLASS

Emmet 使用类似于 CSS 选择器的语法给元素添加属性:

div#header+div.page+div#footer.class1.class2.class3
<div id="header"></div>
<div class="page"></div>
<div id="footer" class="class1 class2 class3"></div>

Custom attributes 自定义属性

td[title="Hello world!" colspan=3]
<td title="Hello world!" colspan="3"></td>
    方括号内属性数量不限。
    没有指定值的属性将生成插入占位(需要编辑器支持)。
    属性值使用单引号或双引号。
    属性值如果不包含空格可以省略引号。

Item numbering: $ 编号

* 操作符可以生成重复元素,而 $ 可以对元素编号。将 $ 放在元素名、属性名或属性值中:

ul>li.item$*5
<ul>
    <li class="item1"></li>
    <li class="item2"></li>
    <li class="item3"></li>
    <li class="item4"></li>
    <li class="item5"></li>
</ul>

多个连写的 $ 可以生成带有前导零的编号:

ul>li.item$$$*5
<ul>
    <li class="item001"></li>
    <li class="item002"></li>
    <li class="item003"></li>
    <li class="item004"></li>
    <li class="item005"></li>
</ul>

使用 @ 修饰符,可以改变编号的方向(升序或降序)及起点。

例如改变方向,将 @- 放在 $ 后:

ul>li.item$@-*5
<ul>
    <li class="item5"></li>
    <li class="item4"></li>
    <li class="item3"></li>
    <li class="item2"></li>
    <li class="item1"></li>
</ul>

改变起点,将 @N 放在 $ 后:

ul>li.item$@3*5
<ul>
    <li class="item3"></li>
    <li class="item4"></li>
    <li class="item5"></li>
    <li class="item6"></li>
    <li class="item7"></li>
</ul>

混合使用这几种修饰符:

ul>li.item$@-3*5
<ul>
    <li class="item7"></li>
    <li class="item6"></li>
    <li class="item5"></li>
    <li class="item4"></li>
    <li class="item3"></li>
</ul>

Text: {} 文本

使用大括号为元素添加文本(译注:类似于模板的插入符)

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,不用改变父元素上下文,所以不需要这样做。
下面不用 > 做下对比:

p{Click }+a{here}+{ to continue}
<p>Click </p>
<a href="">here</a> to continue

Notes on abbreviation formatting 格式化缩写注意事项
当熟悉 Emmet 的缩写语法后,你可能为了可读性而去格式化缩写。比如在元素与操作符之间插入空格:

(header > ul.nav > li*5) + footer

但是这时 Emmet 失效,因为 Emmet 遇到空格后停止解析缩写。
许多用户错误地认为缩写应该新起一行,但是这是错的:可以在文本的任意位置书写并展开缩写。
这便是为什么 Emmet 需要指示符(比如空格)来停止解析缩写。如果你仍然认为对于复杂的缩写,为了可读性必须格式化:

    缩写不是模板语言,不需要可读性,即写即用。
    你真的没必要书写复杂的缩写。停止这样的认识:书写是网页开发中最慢的过程。你将很快发现书写一个复杂的缩写比起使用多个简短缩写,要慢得多并且容易出错。

厂商前缀

新的 CSS3 特性是开发者的福音:几行代码可以做到几年前几乎做不到的事。但是同时也给我们带来一个痛苦:一个属性需要为不同的浏览器重复写几遍。

Emmet 的 CSS 解析器提供一个不错的功能,可以大大提高你的 CSS3 开发体验。在属性前或缩写前放一个连字符,Emmet 会自动给这个属性添加厂商前缀。例如缩写 -bdrs 将展开为:

-webkit-border-radius: ;
-moz-border-radius: ;
border-radius: ;

而且对于支持插入占位的编辑器(Eclipse, Sublime Text 2, Espresso 等),Emmet 将创建关联的属性值占位,输入一次将自动插入到所有生成的属性中。

渐变

另一个难写的 CSS3 特性是渐变,需要重复写几遍带有不同厂商前缀的属性。而且如果想覆盖所有支持渐变的浏览器,得使用三种写法:旧版 Webkit、当前支持的 (linear-gradient(top, …)) 及 W3C 标准 (linear-gradient(to bottom, …))。

通常用户喜欢使用第三方 GUI 程序来生成渐变,但是在编辑器里面做得更快。
Emmet 有一个 CSS3 渐变生成器替你做这些重活:

如你所见,可以输入函数 lg(…) (或 linear-gradient(…)) 函数,并且像缩写一样展开。如果用做属性值,Emmet 将使用属性名来生成新的属性。

Fallback value 向后兼容

在配置里启用选项 css.gradient.fallback 后可以生成向后兼容的 background-color。
这个选项默认关闭,因为它生成的 background-color 总是需要手工更新,以确保在这个背景色上可以阅读。如果你不关心旧浏览器,可以启用这个选项。

功能

展开缩写

“Expand Abbreviation” (Tab key)

如果你的编辑器(Eclipse, Sublime Text 2, Espresso 等)支持插入占位,生成的代码包括多个插入占位,这样可以用 Tab 键在它们之间快速移动。
一些编辑器(Eclipse, Sublime Text 2, CodeMirror),可以用 Tab 键触发 “展开缩写”功能。

匹配标签

“Match Pair Outward” (Ctrl+D)
“Match Pair Inward (Shift+Ctrl+D)

从插入符所在位置开始查找标签及标签内容,并选中它。当多次调用时将向外扩展或向内收缩选择。由于实现上的问题,不是所有的编辑器同时支持这两种操作,多数编辑器只支持向外扩展选择。

Emmet 的匹配标签功能很独特。不像其它实现,Emmet 从插入符所在位置而不是从文档的开头开始搜索标签,这意味着可以在非 HTML 文档使用这个功能。

    注意如果标签是由拼接的字符定义,像这样:var cell = '',不能匹配标签。

跳转到配对标签

“Go to Matching Pair” (Ctrl+T)

这个功能在内部调用 匹配标签 功能,所以非 HTML 语法也可以用。

包裹缩写

这是 Emmet 的一个强大工具,展开缩写,并将选中的内容放在最后生成的元素内。如果没有选择,则调用匹配标签功能,包裹匹配的元素。

“Wrap with Abbreviation” (Shift+Ctrl+A)

跳转到编辑点

这个功能适用于 HTML 代码块,可以在要点之间跳转:

between tags 标签之间
empty attributes 空标签
newlines with indentation 缩进的新行

“Next Edit Point” (Ctrl+Alt+→)
“Previous Edit Point” (Ctrl+Alt+←)

切换注释

这个功能,如名字所示,注释或取消注释选中内容。几乎所有的程序员编辑器都有这样的功能,但是这个不同。当没有选择时,编辑器切换当前行的注释,而 Emmet 切换当前上下文的注释。对于 HTML 是整个标签内容,对于 CSS 是一条规则或整个属性。

“Toggle Comment” (Ctrl+/)

分割合并标签

这个功能分割合并标签,例如将 转换为 ,或逆操作。对于 XML/XSL 开发很有用。

“Split/Join Tag” (Ctrl+J)
这个功能在内部调用 匹配标签 功能,所以非 HTML 语法也可以用。

删除标签

“Remove Tag” (Ctrl+K)

快速删除标签,并调整缩进。这里的标签是在插入符所在位置由 匹配标签 功能查找的标签。

合并行

“Merge Lines” (Shift+Ctrl+M)

许多编辑器有类似功能:将选中的多行合并为单行。不过如果没有选择,Emmet 将匹配所在 HTML 标签。

更新图片尺寸

“Update Image Size” (Shift+Ctrl+U)

许多开发者忘记给 标签添加 width 与 height 属性,这样对用户体验不好。这个功能自动帮你搞定:将插入符放在 标签内,然后调用此功能,就可以添加或更新 width 与 height 属性。

对于 CSS,将插入符放在属性值 url() 内,然后调用此功能,就可以添加或更新 width 与 height 属性。

注意此功能对绝对 URL 路径也适用:从宿主文件所在目录开始查找文件,然后沿着目录结构向上查找。

计算数学表达式
“Evaluate Math Expression” (Shift+Ctrl+Y)
计算简单的数学表达式,比如2*4 或 10/2,并输出结果。\ 操作符结果同 round(a/b)。

当数字值频繁改变时这个比较很有用。

重构 CSS 值
“Reflect CSS Value” (Ctrl+B)
对 CSS 开发很实用的功能: 将插入符所在的 CSS 属性值复制给带厂商前缀的属性中。

编码/解码图像为 data:URL

“Encode/Decode Image to data:URL” (Shift+Ctrl+I)

HTML 与 CSS 可以用 data:URL 插入外部资源。通常用在线服务或第三方软件将图像转换为 base64。
但是这些工具有缺点:在线工具要花费额外的时间,或者不能控制图片是否应该转换为 base64。
使用 Emmet 在编辑器里就可以将图像转换为 base64,或者相反操作。