缩略语法
Emmet用了类似于CSS选择器的方式来表示元素在树状结构中的的位置以及元素的属性。
元素
可以用元素名生成HTML标签,例如div
或者p
。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>
分组操作符: ()
圆括号用来构造复杂缩略语:
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 class="page"></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="">
,如果编辑器支持的话,每个空属性里面都会有Tab热点(tabstop) - 属性值可以用单引号也可以用双引号包裹
- 不必带上引号,除非属性值含有空格,
td[title=hello colspan=3]
这样的代码完全可以
计数: $
用乘法操作符*
可以生成重复元素,而用$
可以计数。把$
操作符放在元素名、属性名或者属性值里面可以输出当前重复元素的序号:
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>
可以改变计数开始的基数和方向
用@
修饰符可以改变计数方向(升序或者降序)和基数(e.g. 开始值)。
例如在$
后面添上@-
即可改变计数方向:
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>
文本: {}
可以用花括号给元素添加文本:
a{Click me}
...会生成
<a href="">Click me</a>
注意{text}
只能用于单个元素(比如div
, p
等等),写在元素右边时才有特殊含义(作为左边元素内部的文本节点,且不会改变context)。例如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
元素的话就没有必要,因为<a>
元素只有here
内容,不需要改变父元素上下文环境。
作为对比,给出不用子选择器>
操作符实现的缩略式:
p{Click }+a{here}+{ to continue}
...生成
<p>Click </p>
<a href="">here</a> to continue
注意缩略式的格式
熟悉了Emmet的缩略语法后,你可能想用一些格式化来增强缩略式的可读性,例如,用空格隔开元素和操作符:
(header > ul.nav > li*5) + footer
但这么做就不行了,因为空格是结束符(stop symbol),Emmet遇到空格就会停止对缩略式的解析。
很多用户误以为每个缩略式都应该另起一行,但他们也错了:可以在任意位置输入并展开缩略式:
所以Emmet需要一些指示符(比如空格),它会在任何不需要解析的地方停止解析,如果还是觉得复杂缩略式需要通过格式化来增强其可读性:
- 缩略式不是模版语言,不需要非常好的可读性,只要能快速展开和移除就好。
- 不需要写非常复杂的缩略式,不要觉得“键入”是Web开发中最慢的环节。你很快就会发现构造一条复杂缩略式要比键入几条更短的缩略式更慢更容易出错。