2019-06-10 | 网摘分享 | UNLOCK

高效输入:Emmet使用手册

在前端开发的过程中,很大一部分工作是写HTML,CSS代码。数量繁多的标签、属性、尖括号、标签闭合等,往往导致开发过程十分繁琐且效率不高。

Emmet(前身为Zen Coding)是一套面向文本编辑器的插件,它允许通过内容辅助高速度的编写和编辑HTML、XML、XSL和其他结构化的代码格式,是一个能大幅提高前端开发效率的工具。它使用特定的语法来展开小段代码,类似CSS选择器,使其成为完整的HTML结构或CSS代码。

Emmet官方提供多编辑器支持,具体安装使用方法可参考官网介绍。我个人习惯使用VS Code,当前版本已内置Emmet语法,无需安装插件。本文仅介绍部分常用语法,完整API列表可参考官方文档

HTML缩写

缩写(Abbreviations)是Emmet工具包的核心:这些特殊表达式在运行时解析并转换为结构化代码块,例如HTML。缩写的语法看起来像CSS选择器,具有一些特定于代码生成的扩展。

元素(Elements)

你可以使用元素的名字,如divp来生成HTML标签。Emmet没有预定义的可用标签名称集,所以你可以编写任何单词并将其转换为标签:div<div></div>foo<foo></foo>依此类推。

嵌套操作符(Nesting operators)

嵌套操作符用于在生成的树中定位缩写元素:是否应将其放置在context元素的内部或附近。

子级(Child): >

通过>可生成嵌套子级元素,可以配合元素属性进行连写。

1
2
3
4
5
6
7
div>ul>li

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

同级(Sibling): +

通过+连接元素,可生成同级元素。

1
2
3
4
5
div+p+bq

<div></div>
<p></p>
<blockquote></blockquote>

父级(Climb-up): ^

^用于生成父级元素的同级元素,从这个^字符所在位置开始,查找左侧最近的元素的父级元素并生成其兄弟元素。

1
2
3
4
5
6
7
div+div>p>span+em^bq

<div></div>
<div>
<p><span></span><em></em></p>
<blockquote></blockquote>
</div>

可以使用任意数量的^操作符,每个操作符将向上移动一级。

1
2
3
4
5
6
7
div+div>p>span+em^^^bq

<div></div>
<div>
<p><span></span><em></em></p>
</div>
<blockquote></blockquote>

乘法(Multiplication): *

使用*可定义重复项,后跟一个正整数表示重复次数。

1
2
3
4
5
6
7
8
9
ul>li*5

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

分组(Group): ()

使用()可对复杂缩写中的子树分组。在下面这个例子中,如果不加括号进行分组,footer将作为a的同级元素生成。

1
2
3
4
5
6
7
8
9
10
11
12
13
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>

属性操作符(Attribute operators)

属性运算符用于修改输出元素的属性。例如,在HTML和XML中,你可以快速向生成的元素添加class属性。

ID和CLASS

在Emmet中,可以使用elem#idelem.class将这些属性添加到指定的元素上。

1
2
3
4
5
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)

可以使用[attr]表示法向元素添加自定义属性。

1
2
3
td[title="Hello world!" colspan=3]

<td title="Hello world!" colspan="3"></td>

自动计数(Item numbering)

使用*操作符生成重复元素时,可以加上$对它们进行编号。将$操作符放在元素的名称,属性的名称或属性的值中,以输出重复元素的当前数量。

1
2
3
4
5
6
7
8
9
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>

可以使用多个连续$用零填充数字:

1
2
3
4
5
6
7
8
9
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>

同时,也可以使用@修改器更改编号方向(升序或降序)和基础值(例如起始值)。例如,如果要修改编号方向,可以在$后添加@-

1
2
3
4
5
6
7
8
9
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,N为正整数,表示基础值:

1
2
3
4
5
6
7
8
9
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>

文本操作符(Text): {}

可以使用花括号向元素添加文本。

1
2
3
a{Click me}

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

主要注意的是,{text}被用作同时也被解析为独立的元素(类似divp),但当置于元素右侧时具有特殊含义。例如,a{click}并且a>{click}会产生相同的输出,但a{click}+b{here}a>{click}+b{here}并不会:

1
2
3
4
5
<!-- a{click}+b{here} -->
<a href="">click</a><b>here</b>

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

HTML文档初始结构

每个HTML文档都包含一些固定的标签,像htmlheadbody等。在Emmet中,输入!或者html:5,按下Tab键,可以快速生成HTML文档初始结构。

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>

</body>
</html>

隐式标签

隐式标签意味着,多数情况下,Emmet允许你省略某些标签名。例如,如果想要生成一个类名为contentdiv元素,可以将div.content简单地写为.content,结果同样会生成<div class="content"></div>

此外,Emmet会根据父元素判定将要生成的标签,例如,输入ul>.item$*5将会生成如下结构:

1
2
3
4
5
6
7
<ul>
<li class="item1"></li>
<li class="item2"></li>
<li class="item3"></li>
<li class="item4"></li>
<li class="item5"></li>
</ul>

下面是一些解析的方式:

  • li用于ulol
  • tr用于tabletbodytheadtfoot
  • td用于tr
  • option用于selectoptgroup

生成测试文本(Lorem Ipsum)

Lorem Ipsum是一段用于测试排版效果的占位文字,没有实际含义。在Emmet中,可以通过lorem快速生成,同时还可以指定生成单词的个数。例如lorem10,将生成:

1
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Alias, neque?

缩写格式(不要有空格)

以上为Emmet的基本缩写语法,需要注意的是在Emmet中,空格会被当做停止符号,如果你的缩写中含有空格,Emmet会停止缩写解析,举个例子,下面的缩写是不起作用的:

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

CSS缩写

属性缩写

Emmet允许将值直接注入缩写,如果你想要得到margin: 10px,可以简单的输入m10。如果有多个属性值,可以用连字符-分割多个属性值,例如,m10-20可以扩展为:

1
margin: 10px 20px;

如果需要负值,可在属性值前多加一个横杠-。例如,m-10--20可生成:

1
margin: -10px -20px;

默认情况下,当使用整数值展开缩写时,Emmet会以px作为单位输出:m10margin: 10px;。如果使用浮点数值扩展缩写,则以em单位输出:m1.5margin: 1.5em

如果想要明确地指出单位名称,只需要将其放置在值之后:

1
2
m1.5exmargin: 1.5ex;
m10foomargin: 10foo;

如果已明确地定义单位,则不需要使用连字符来分隔值:

1
2
m10ex20emmargin: 10ex 20em;
m10ex-5margin: 10ex -5px;

单位别名

Emmet提供一些常用值的别名,可以使用别名而不是完整单位。

  • p%
  • eem
  • xex
1
2
w100pwidth: 100%
m10p30e5xmargin: 10% 30em 5ex

颜色值

Emmet支持十六进制颜色值,如下所示:c#3color: #333;。该#是值分隔符,因此不需要使用连字符来分隔。例如,bd5#0s展开为border: 5px #000 solid#符号分隔颜色值和5,因为s(别名solid)不是十六进制字符,它可以在没有-值分隔符的情况下使用。

在Emmet中,可以将1个,2个,3个,6个字符写为颜色值:

1
2
3
#1#111111
#e0#e0e0e0
#fc0#ffcc00

无单位属性

一些CSS属性是没有单位的,例如:

1
2
lh2line-height: 2;
fw400font-weight: 400;

!important语法

可以在任何CSS缩写的末尾加上!以生成!important

1
2
3
4
/* p!+m10e! */

padding: !important;
margin: 10em !important;

供应商前缀

CSS3的新特性为前端开发带来了很多便利,可以用少量代码实现复杂功能,但由于其还没有作为规范兼容所有浏览器,致使我们不得不编写大量冗余代码,在属性前加上不同前缀以兼容不同浏览器。

在Emmet中,我们可以通过在属性名或者其缩写前加上连字符-来自动创建此属性的带前缀代码。例如,输入-bdrs可生成:

1
2
3
-webkit-border-radius: ;
-moz-border-radius: ;
border-radius: ;

此外,你还可以显式地控制具体生成哪几个浏览器前缀或者先后顺序。假如你只想生成transform属性的webkitmoz前缀,这种情况下,可以输入-wm-trf,将会生成:

1
2
3
-webkit-transform: ;
-moz-transform: ;
transform: ;

Emmet中支持的单字母供应商前缀为:

  • wwebkit
  • mmoz
  • sms
  • oo

渐变背景

CSS3中新增加了一条属性linear-gradient用于制作出渐变的效果。但由于该属性的参数比较复杂,而且需要添加前缀,无疑需要生成大量代码。在Emmet中使用lg()指令即可快速生成,例如:使用lg(left, #fff 50%, #000)可以直接生成:

1
2
3
4
5
background-image: -webkit-gradient(linear, 0 0, 100% 0, color-stop(0.5, #fff), to(#000));
background-image: -webkit-linear-gradient(left, #fff 50%, #000);
background-image: -moz-linear-gradient(left, #fff 50%, #000);
background-image: -o-linear-gradient(left, #fff 50%, #000);
background-image: linear-gradient(left, #fff 50%, #000);

模糊匹配

如果有些缩写你不确定,Emmet会根据你的输入匹配最接近的语法,比如输入ov:hov-hovhoh,生成的结果是相同的:

1
overflow: hidden

定制

如果Emmet现有的功能仍不能满足你的需求,还可以选择定制插件:

  1. 添加新缩写或覆盖现有缩写,可修改snippets.json文件
  2. 更改Emmet操作和解析程序的行为,可修改preferences.json文件
  3. 定义如何生成HTML或XML代码,可修改syntaxProfiles.json文件

评论加载中