【翻译】Emmet(Zen Coding)官方文档 之五 CSS 过滤器
【说明】本系列博文是依据 Emmet 官方文档翻译的,原文地址为:http://docs.emmet.io/,部分内容已经在博主之前的博文中节选过,为方便已经收藏过之前博文的朋友,没有删除这些博文,仅将其完整的收录于本系列中。
过滤器
过滤器是在将缩写展开输出到编辑前进行编辑的特殊的提交处理器。为了更好地理解示过滤器如何工作,我们制作了一个简单的教程。
下面的编辑器中输入并展开了:#content>p.title
正像所期望的那样,展开的结果是如下的 HTML 代码:
<div id="content"> <p class="title"></p> </div>
现在,再来看展开: #content>p.title|e
。将得到稍有不同的结果:
<div id="content"> <p class="title"></p> </div>
只是通过在标签名添加管道符应用了 e
(转码) 过滤器。这个过滤器在 Emmet 将输出传递给编辑器前,将所有的非 XML 安全的符号转码为实体符号。如果展开:#content>p.title|e|e,将得到:
&lt;div id="content"&gt; &lt;p class="title"&gt;&lt;/p&gt; &lt;/div&gt;
这是一段双转码的代码 (例如,应用了两次 e
过滤器)。正如所展示的那样,我们可以按我们想要的次数在缩写上应用多个我们想要使用的过滤器。
还有更多有趣的事可做。尝试编写: #content>p.title|haml
#content
%p.title
是不是漂亮? 竟然可以按照 HAML 模板展开缩写!
如上所示,过滤器是 Emmet 的关键概念。用浏览器的 DOM 模型打个比方,每次展开缩写,首先要做的是是获取转换成的树,然后逐步过虑每个树结点并编辑输出结果。过滤器能够做任何事:从为 CSS 规则末尾添加空格到输出高语法的输出结果等复杂任务。甚至将 HTML 输出定义成 html
过滤器。
隐式调用过滤器
通过向缩写后附加管道符,可以显式地为缩写应用过滤器。但过滤器也可以隐式调用,这依赖于当前编辑的文档的类型。是否不想每次都在 HAML 文档中的缩写后添加 |haml?
默认的过滤器定义在 snippets.json 文件中每个语法的 filters
一节:
{
...
"html": {
...
"filters": "html"
}
}
如果没有这一节,默认应用 html
过滤器。如果想要在默认情况下应用多个过滤器,可以在 filters
一节为写下以逗号或管理符间隔的过滤器列表:
{
...
"html": {
...
"filters": "html, e"
}
}
现在,在 HTML 文档中,每次展开缩写,html
和 e
过滤器都将被应用。
小心! snippets.json
文件中,必须将 html
或 haml 语法过滤器放在默认过滤器的第一位,否则,就会得到空白的输出,这是因为语法过滤器被定义为主输出结果。
可用的过滤器
HAML 语法: haml
HAML 语法过滤器:按 HAML 模板输出缩写。它是 HAML 文件的默认过滤器。
HTML 语法: html
HTML 语法过滤器:按 HTML/XML 标签输出缩写。除了 HAML 文件以外所有地方的默认过滤器。
转码: e
对非 XML 安全的字符进行转码,如: <
、 >
和 &。
例如: div#header|e
将展开成 <div id="header"></div>
。这个过滤器对技术博客/技术作家极为有用,因为他们想要在 web 站点中展示代码片段(当然,需要在 CMS 中添加 Emmet 支持)。
注释标签: c
为重要的标签添加环绕注释。默认的, “重要标签” 是指那些带有 id
和/或 class 属性的标签。
div>div#page>p.title+p|c
将展开为:
<div> <div id="page"> <p class="title"></p> <!-- /.title --> <p></p> </div> <!-- /#page --> </div>
这个过滤器有几个可以重定义的选项:
filter.commentTrigger:可以触发注释输出的属性。默认是
id、class。
filter.commentAfter:
: 即将被放在“重要标签”后面的 ERB-模板风格 的注解。默认值是\n<!-- /<%= attr("id", "#") %><%= attr("class", ".") %> -->
filter.commentBefore:即将被放在“重要标签”前面的
ERB-模板 风格的注解。默认为空。
XSL 调整: xsl
这个过滤器在 <xsl:variable>
和 <xsl:with-param>
标签包含子节点时从中删除 select
属性。例如:
ap>wp
将展开成:
<xsl:apply-templates select="" mode=""> <xsl:with-param name="" select=""/> </xsl:apply-templates>
而
ap>wp>call
将输出
<xsl:apply-templates select="" mode=""> <xsl:with-param name=""> <xsl:call-template name=""/> </xsl:with-param> </xsl:apply-templates>
默认应用于 XSL 文件。
单行: s
将缩写展开成单选代码。在 JavaScript、Python、Ruby 等编程语言中编写模板字符串时有用。例如:
ul>li*4|s
将展开成:
<ul><li></li><li></li><li></li><li></li></ul>
删除行标记:t
仅在包围缩写中有用:从被包围的行中删除行标记,参见 “Wrap with Abbreviation” 动作。
Yandex BEM/OOCSS
如果以特定的 OOCSS-风格、 Yandex’s BEM 风格编写 HTML 和 CSS 代码,就肯定会喜欢这个过滤器。它提供了一些别名,并且自动在 class 中插入注释块和注释名。
简言之,BEM 引入了三种类型的 CSS class:块、元素和修饰符。块是是 HTML 页中语言部分的命名空间,例如 search-form
。元素是其中的一段,例如 serch-form__query-string
。修饰符定义了块变量和元素变量: search-form_wide
或 search-form_narrow
。class 名中的元素使用 __
(两个下划线)分隔,修饰符用 _
(一个下划线分隔)。
BEM/OOCSS 是维护和复用 CSS 的好办法。即使在 Emmet 缩写的帮助下,在普通的 HTML 中编写这些类名仍然可能很乏味。必须在每个缩写元素中重复书写相同的块和元素名:
form.search-form.search-form_wide>input.search-form__query-string+input:s.search-form__btn.search-form__btn_large
bem
过滤器允许制造一个缩写分拣器:
form.search-form._wide>input.-query-string+input:s.-btn_large|bem
它是如何工作的呢?
BEM 过滤器引入了几个 class 名前缀的概念类型: __
或 -
作为元素前缀,而 _
则是修饰符前缀。任何时候遇到带有这些前缀的类名,过滤器都将处理如下的事情:
- 如果 class 名带有元素前缀,过滤器将从从父节点中解析块名;
- 如果 class 名带有修饰符前缀,过滤器将从当前节点或父节点中解析块名、元素名;
- 如果同时带有块和修饰符前缀,过滤器将从父节点中解析块名,并输出元素上的所有 “未修饰的” 和 “已修饰的” class;
- 如果使用多个元素修饰,过滤器将从 nth 父节点中解析块名。
下面是几个示例:
Abbreviation | Output |
---|---|
.b_m |
|
.b_m1._m2 |
|
.b>._m |
|
.b1>.b2_m1>.-e1+.--e2_m2 |
|
记住,要让 bem
过滤器总是 HTML 语法过滤器的第一个。