Visual Studio Code 中的 Emmet
Visual Studio Code 内置了对 Emmet 代码片段和展开功能的支持,无需安装任何扩展。Emmet 2.0 支持大多数 Emmet 操作,包括展开 Emmet 缩写和代码片段。
如何展开 Emmet 缩写和代码片段
Emmet 缩写和代码片段展开功能在 html、haml、pug、slim、jsx、xml、xsl、css、scss、sass、less 和 stylus 文件中默认启用,同时适用于任何继承自上述语言的文件,例如 handlebars 和 php。

当你开始输入 Emmet 缩写时,你会在建议列表中看到该缩写。如果你打开了建议文档浮窗,你会在输入时看到展开后的预览效果。如果你在样式表文件中,展开后的缩写会与其它 CSS 建议一起排序在列表中。
使用 Tab 键进行 Emmet 展开
如果你想使用 Tab 键来展开 Emmet 缩写,请添加以下设置:
"emmet.triggerExpansionOnTab": true
当文本不是 Emmet 缩写时,此设置允许将 Tab 键用于缩进。
在禁用 quickSuggestions 时的 Emmet
如果你禁用了 editor.quickSuggestions 设置,则在输入时不会看到建议。你仍然可以通过按下 ⌃Space (Windows, Linux Ctrl+Space) 手动触发建议并查看预览。
在建议中禁用 Emmet
如果你根本不想在建议中看到 Emmet 缩写,请使用以下设置:
"emmet.showExpandedAbbreviation": "never"
你仍然可以使用命令 Emmet: Expand Abbreviation 来展开缩写。你也可以将任何键盘快捷键绑定到命令 ID editor.emmet.action.expandAbbreviation。
Emmet 建议排序
为了确保 Emmet 建议始终位于建议列表的顶部,请添加以下设置:
"emmet.showSuggestionsAsSnippets": true,
"editor.snippetSuggestions": "top"
在其他文件类型中使用 Emmet 缩写
要在默认不支持 Emmet 的文件类型中启用 Emmet 缩写展开,请使用 emmet.includeLanguages 设置。确保映射的两侧都使用 语言标识符,右侧必须是 Emmet 支持的语言的标识符(参见上面的列表)。
例如
"emmet.includeLanguages": {
"javascript": "javascriptreact",
"razor": "html",
"plaintext": "pug"
}
Emmet 不识别这些新语言,因此在非 HTML/CSS 上下文中可能会显示 Emmet 建议。为避免这种情况,可以使用以下设置。
"emmet.showExpandedAbbreviation": "inMarkupAndStylesheetFilesOnly"
注意:如果你以前使用过 emmet.syntaxProfiles 来映射新的文件类型,从 VS Code 1.15 版本开始,你应该改用 emmet.includeLanguages 设置。 emmet.syntaxProfiles 仅用于 自定义最终输出。
多光标下的 Emmet
你也可以在多光标模式下使用大多数 Emmet 操作。

使用过滤器
过滤器是特殊的后处理器,用于在输出到编辑器之前修改展开后的缩写。有两种使用过滤器的方法:通过 emmet.syntaxProfiles 设置全局应用,或直接在当前的缩写中应用。
下面是第一种方法的示例,使用 emmet.syntaxProfiles 设置为 HTML 文件中的所有缩写应用 bem 过滤器。
"emmet.syntaxProfiles": {
"html": {
"filters": "bem"
}
}
要仅为当前缩写提供过滤器,请将过滤器附加到你的缩写后面。例如,div#page|c 将对 div#page 缩写应用 comment 过滤器。
BEM 过滤器 (bem)
如果你使用 Block Element Modifier (BEM) 方式编写 HTML,那么 bem 过滤器对你来说非常方便。要了解有关如何使用 bem 过滤器的更多信息,请阅读 Emmet 中的 BEM 过滤器。
你可以通过 bem.elementSeparator 和 bem.modifierSeparator 首选项自定义此过滤器,如 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、filter.commentAfter 和 filter.commentBefore 首选项自定义此过滤器,如 Emmet 首选项中所述。
VS Code Emmet 2.0 中 filter.commentAfter 首选项的格式有所不同。
例如,与其使用:
"emmet.preferences": {
"filter.commentAfter": "\n<!-- /<%= attr('id', '#') %><%= attr('class', '.') %> -->"
}
在 VS Code 中,你只需要使用更简单的:
"emmet.preferences": {
"filter.commentAfter": "\n<!-- /[#ID][.CLASS] -->"
}
修剪过滤器 (t)
此过滤器仅在使用 Emmet: Wrap with Abbreviation 命令提供缩写时适用。它会 删除换行标记 中的列表标记。
使用自定义 Emmet 代码片段
自定义 Emmet 代码片段需要在名为 snippets.json 的 JSON 文件中定义。 emmet.extensionsPath 设置应包含此文件所在目录的路径。
下面是此 snippets.json 文件内容的示例。
{
"html": {
"snippets": {
"ull": "ul>li[id=${1} class=${2}]*2{ Will work with html, pug, haml and slim }",
"oll": "<ol><li id=${1} class=${2}> Will only work in html </ol>",
"ran": "{ Wrap plain text in curly braces }"
}
},
"css": {
"snippets": {
"cb": "color: black",
"bsd": "border: 1px solid ${1:red}",
"ls": "list-style: ${1}"
}
}
}
在 Emmet 2.0 中通过 snippets.json 文件创建自定义代码片段的方法与旧方式相比有几点不同:
| 主题 | 旧版 Emmet | Emmet 2.0 |
|---|---|---|
| 代码片段 vs 缩写 | 支持两个独立的属性,分别称为 snippets 和 abbreviations |
两者已合并为一个名为 snippets 的属性。请查看默认的 HTML 代码片段 和 CSS 代码片段 |
| CSS 代码片段名称 | 可以包含 : |
定义代码片段名称时请勿使用 :。当 Emmet 尝试将给定的缩写模糊匹配到一个代码片段时,它使用 : 来分隔属性名称和值。 |
| CSS 代码片段值 | 可以以 ; 结尾 |
不要在代码片段值的末尾添加 ;。Emmet 将根据文件类型(css/less/scss vs sass/stylus)或为 css.propertyEnd、sass.propertyEnd、stylus.propertyEnd 设置的 Emmet 首选项添加末尾的 ;。 |
| 光标位置 | 可以使用 ${cursor} 或 | |
仅使用 Textmate 语法(如 ${1})来定义制表符停止位和光标位置 |
HTML Emmet 代码片段
HTML 自定义代码片段适用于所有其他标记语言(如 haml 或 pug)。当代码片段的值是缩写而不是实际的 HTML 时,可以应用适当的转换,根据语言类型获得正确的输出。
例如,对于带有列表项的无序列表,如果代码片段的值是 ul>li,你可以在 html、haml、pug 或 slim 中使用同一个代码片段;但如果代码片段的值是 <ul><li></li></ul>,则它仅在 html 文件中有效。
如果你想要一个纯文本的代码片段,请用 {} 包围文本。
CSS Emmet 代码片段
CSS Emmet 代码片段的值应该是一个完整的属性名和值对。
CSS 自定义代码片段适用于所有其他样式表语言(如 scss、less 或 sass)。因此,不要在代码片段值的末尾包含 ;。Emmet 会根据语言是否需要它来决定是否添加。
不要在代码片段名称中使用 :。: 用于分隔属性名和值,以便 Emmet 尝试将缩写模糊匹配到其中一个代码片段。
自定义代码片段中的制表符停止位和光标
自定义 Emmet 代码片段中的制表符停止位语法遵循 Textmate 代码片段语法。
- 使用
${1}、${2}作为制表符停止位,使用${1:placeholder}作为带有占位符的制表符停止位。 - 以前,使用
|或${cursor}来表示自定义 Emmet 代码片段中的光标位置。这不再被支持,请改用${1}。
Emmet 配置
以下是你可以用来在 VS Code 中自定义 Emmet 体验的 设置。
-
emmet.includeLanguages
使用此设置添加你选择的语言与 Emmet 支持的语言之一之间的映射,以通过后者的语法在前者中启用 Emmet。确保映射的两侧都使用语言 ID。
例如
"emmet.includeLanguages": { "javascript": "javascriptreact", "plaintext": "pug" } -
emmet.excludeLanguages
如果你在某种语言中不想看到 Emmet 展开,请将其添加到此设置中,该设置接收语言 ID 字符串的数组。
-
emmet.syntaxProfiles
请参阅 Emmet 自定义输出配置文件 以了解如何自定义 HTML 缩写的输出。
例如
"emmet.syntaxProfiles": { "html": { "attr_quotes": "single" }, "jsx": { "self_closing_tag": true } } -
emmet.variables
自定义 Emmet 代码片段使用的变量。
例如
"emmet.variables": { "lang": "de", "charset": "UTF-16" } -
emmet.showExpandedAbbreviation
控制出现在建议/完成列表中的 Emmet 建议。
设置值 描述 never从不在任何语言的建议列表中显示 Emmet 缩写。 inMarkupAndStylesheetFilesOnly仅针对基于标记和样式表的语言('html', 'pug', 'slim', 'haml', 'xml', 'xsl', 'css', 'scss', 'sass', 'less', 'stylus')显示 Emmet 建议。 always在所有 Emmet 支持的模式以及在 emmet.includeLanguages 设置中具有映射的语言中显示 Emmet 建议。 注意:在
always模式下,新的 Emmet 实现不具备上下文感知能力。例如,如果你正在编辑 JavaScript React 文件,你不仅在编写标记时会获得 Emmet 建议,在编写 JavaScript 时也会获得。 -
emmet.showAbbreviationSuggestions
将可能的 Emmet 缩写显示为建议。默认值为
true。例如,当你输入
li时,你会获得所有以li开头的 Emmet 代码片段的建议,如link、link:css、link:favicon等。这有助于学习那些除非熟记 Emmet 速查表 否则从未发现的 Emmet 代码片段。在样式表中或当 emmet.showExpandedAbbreviation 设置为
never时不适用。 -
emmet.extensionsPath
提供存放
snippets.json文件的目录位置,该文件包含你的自定义代码片段。 -
emmet.triggerExpansionOnTab
将其设置为 true 以启用使用 Tab 键展开 Emmet 缩写。我们使用此设置提供适当的回退,以便在没有可展开缩写时提供缩进。
-
emmet.showSuggestionsAsSnippets
如果设置为
true,则 Emmet 建议将与其它代码片段分组在一起,允许你根据 editor.snippetSuggestions 设置对其进行排序。将此项设置为true并将 editor.snippetSuggestions 设置为top,以确保 Emmet 建议始终显示在其他建议的顶部。 -
emmet.preferences
你可以使用此设置按照 Emmet 首选项中的文档自定义 Emmet。目前支持以下自定义:
css.propertyEndcss.valueSeparatorsass.propertyEndsass.valueSeparatorstylus.propertyEndstylus.valueSeparatorcss.unitAliasescss.intUnitcss.floatUnitbem.elementSeparatorbem.modifierSeparatorfilter.commentBeforefilter.commentTriggerfilter.commentAfterformat.noIndentTagsformat.forceIndentationForTagsprofile.allowCompactBooleancss.fuzzySearchMinScore
Emmet 2.0 中
filter.commentAfter首选项的格式有所不同且更简单。例如,与旧格式不同:
"emmet.preferences": { "filter.commentAfter": "\n<!-- /<%= attr('id', '#') %><%= attr('class', '.') %> -->" }你应该使用:
"emmet.preferences": { "filter.commentAfter": "\n<!-- /[#ID][.CLASS] -->" }
后续步骤
Emmet 只是 VS Code 中出色的 Web 开发功能之一。继续阅读以了解关于:
故障排除
自定义标签不会在建议列表中展开
当自定义标签用于 MyTag>YourTag 或 MyTag.someclass 这样的表达式时,它们会显示在建议列表中。但当它们单独使用(如 MyTag)时,它们不会出现在建议列表中。这是为了避免建议列表中的噪声,因为每个单词都可能是潜在的自定义标签。
添加以下设置以启用使用 Tab 键展开 Emmet 缩写,这将支持在所有情况下展开自定义标签。
"emmet.triggerExpansionOnTab": true
我的以 + 结尾的 HTML 代码片段无法工作
不支持来自 Emmet 速查表 中类似 select+ 和 ul+ 的以 + 结尾的 HTML 代码片段。这是 Emmet 2.0 中的一个已知问题 问题:emmetio/html-matcher#1。解决方法是为这种情况创建你自己的 自定义 Emmet 代码片段。
缩写展开失败
首先,检查你是否使用了自定义代码片段(如果存在通过 emmet.extensionsPath 设置加载的 snippets.json 文件)。自定义代码片段的格式在 VS Code 1.53 版本中发生了变化。请使用 ${1}、${2} 等标记来代替 | 来表示光标位置。来自 emmetio/emmet 仓库的 默认 CSS 代码片段文件 展示了新的光标位置格式示例。
如果缩写仍然展开失败
- 检查 内置扩展 以查看 Emmet 是否被禁用。
- 尝试通过在 命令面板 中运行 Developer: Restart Extension Host (
workbench.action.restartExtensionHost) 命令来重启扩展宿主。
在哪里可以设置 Emmet 首选项 中记录的所有首选项?
你可以使用 emmet.preferences 设置来配置首选项。只有 Emmet 首选项 中记录的部分首选项可以进行自定义。请阅读 Emmet 配置 下的首选项部分。
有什么技巧和窍门吗?
当然!
- 在 CSS 缩写中,当你使用
:时,左侧部分用于与 CSS 属性名进行模糊匹配,右侧部分用于与 CSS 属性值进行匹配。通过使用像pos:f、trf:rx、fw:b等缩写来充分利用这一点。 - 探索 Emmet 操作 文档中记录的所有其他 Emmet 功能。
- 请随时创建你自己的 自定义 Emmet 代码片段。