What Is Emmet and Why Should You Use It?
Emmet (formerly known as Zen Coding) is a plugin for text editors that dramatically speeds up HTML and CSS workflow. Instead of typing out every tag manually, you write a short abbreviation and press Tab to expand it into full, valid markup. It ships built-in with VS Code, Sublime Text, Atom, and virtually every modern editor — meaning zero setup for most developers.
The productivity gains are real. A single Emmet expression like ul>li*5>a expands into a five-item unordered list where every list item contains an anchor tag — something that would otherwise require 15 lines of typing. Once muscle memory kicks in, your hands barely leave the keyboard.
Whether you're building layouts in the Live HTML/CSS/JS Editor or working in a local project, understanding Emmet's full syntax is one of the highest-ROI skills a front-end developer can acquire.
The Emmet Operator Syntax at a Glance
Emmet uses a CSS-selector-like syntax to describe document structure. Here are the core operators:
>(Child) — nests an element inside another+(Sibling) — places an element next to another at the same level^(Climb-up) — moves the context up one level in the tree*(Multiplication) — repeats an element N times()(Grouping) — groups sub-expressions for repeating complex structures.class— adds a class attribute#id— adds an id attribute[attr]— adds custom attributes{text}— inserts text content$and@— numbering with counter control
HTML Abbreviation Operators in Depth
Child Operator: >
The > operator nests elements. Think of it exactly like a CSS descendant combinator in reverse — you're describing structure, not selecting it.
nav>ul>li>a
Expands to:
<nav>
<ul>
<li><a href=""></a></li>
</ul>
</nav>
Sibling Operator: +
The + operator places elements side-by-side at the same nesting level.
header+main+footer
Expands to:
<header></header>
<main></main>
<footer></footer>
Climb-up Operator: ^
After descending into a child, ^ climbs back up one level so you can add siblings to a parent element.
div>p>span^aside
Expands to:
<div>
<p><span></span></p>
<aside></aside>
</div>
Use multiple ^^ to climb multiple levels at once.
Multiplication Operator: *
Repeat elements any number of times with *N.
ul>li*3
<ul>
<li></li>
<li></li>
<li></li>
</ul>
Grouping Operator: ()
Grouping lets you multiply or chain complex sub-trees.
(header>nav>ul>li*4)+main+footer
This produces a full page scaffold with a nav containing four list items, followed by main and footer siblings — all in one keystroke.
Attributes: Classes, IDs, and Custom Attributes
Classes and IDs
Emmet borrows CSS shorthand for classes (.class) and IDs (#id). When applied to a plain abbreviation with no tag name, Emmet infers div.
.container#main>h1.title+p.lead
<div class="container" id="main">
<h1 class="title"></h1>
<p class="lead"></p>
</div>
You can stack multiple classes: p.text-lg.text-center.font-bold.
Custom Attributes: []
Square brackets let you specify any HTML attribute.
a[href="https://example.com" target="_blank"]{Visit Site}
<a href="https://example.com" target="_blank">Visit Site</a>
This is especially useful for input elements:
input[type="email" placeholder="Enter email" required]
<input type="email" placeholder="Enter email" required>
Text Content: {}
Curly braces insert text content directly into an element.
p{This is a paragraph.}+p{And another one.}
<p>This is a paragraph.</p>
<p>And another one.</p>
Numbering with $ and @ Counter
The $ sign inside a class name, id, or text is replaced by an incrementing counter when used with multiplication.
ul>li.item$*4{Item $}
<ul>
<li class="item1">Item 1</li>
<li class="item2">Item 2</li>
<li class="item3">Item 3</li>
<li class="item4">Item 4</li>
</ul>
Use $$ for zero-padded numbering (01, 02…). The @counter modifier controls the starting number and direction:
li.item$@3*3
This starts the counter at 3, producing item3, item4, item5. Use @- to count down.
The Emmet ! HTML Boilerplate
One of the most-used Emmet shortcuts is simply ! — typing it in an empty HTML file and pressing Tab expands the full HTML5 boilerplate:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
This alone saves dozens of keystrokes every time you start a new project.
Emmet CSS Abbreviations
Emmet isn't just for HTML — it has a powerful CSS abbreviation system too. In a CSS file, short aliases expand to full property declarations.
Common CSS Abbreviations
/* Type this: Expands to: */
m10 → margin: 10px;
p20 → padding: 20px;
w100 → width: 100px;
h50 → height: 50px;
fz16 → font-size: 16px;
fw700 → font-weight: 700;
lh1.5 → line-height: 1.5;
bgc#fff → background-color: #fff;
c#333 → color: #333;
d:f → display: flex;
pos:r → position: relative;
ov:h → overflow: hidden;
bd+ → border: 1px solid #000;
Emmet CSS Unit Suffixes
You can control the unit by appending it directly:
m2em → margin: 2em;
p10% → padding: 10%;
w50vw → width: 50vw;
Without a suffix, Emmet defaults to px for most properties. For unitless values like opacity, it omits the unit automatically.
Emmet in VS Code: Tips and Settings
VS Code ships with Emmet built in. Here are key configuration tips to get the most out of it:
Enable Emmet in JSX / TSX Files
By default, Emmet doesn't activate in .jsx or .tsx files. Add this to your settings.json:
{
"emmet.includeLanguages": {
"javascript": "javascriptreact",
"typescript": "typescriptreact"
}
}
Trigger Emmet with Tab
{
"emmet.triggerExpansionOnTab": true
}
Exclude Emmet in Certain Contexts
{
"emmet.excludeLanguages": ["markdown"]
}
Useful Emmet Actions in VS Code
- Wrap with Abbreviation — Select text, open command palette, type "Emmet: Wrap with Abbreviation"
- Balance (inward/outward) — Expand or shrink your selection to enclosing tags
- Remove Tag — Delete the surrounding tag while keeping its children
- Update Tag — Rename open and close tags simultaneously
- Toggle Comment — Quickly wrap in HTML comment tags
Real-World Emmet Workflows
Building a Card Component
.card>.card__image+.card__body>h2.card__title{Card Title}+p.card__text{Lorem ipsum}+a.btn[href="#"]{Read More}
Expands to a complete BEM-style card in one line — image wrapper, heading, paragraph, and button — ready to style.
Building an HTML Form
form[action="/submit" method="post"]>
(div.form-group>label[for="name"]{Name}+input#name[type="text" placeholder="Your name"])+
(div.form-group>label[for="email"]{Email}+input#email[type="email"])+
button[type="submit"]{Submit}
Building a Navigation Bar
nav.navbar>div.container>a.brand[href="/"]{MySite}+ul.nav__links>li*4>a[href="#"]{Link $}
Implicit Tag Names
Emmet is smart about default tags. When you omit a tag name, Emmet picks the most appropriate one based on context:
- Inside
<ul>or<ol>— defaults to<li> - Inside
<table>— defaults to<tr> - Inside
<tr>— defaults to<td> - Inside
<select>— defaults to<option> - Otherwise — defaults to
<div>
table>tr*3>.col$*4
Creates a 3×4 table with auto-inferred td elements.
Lorem Ipsum Generation
Emmet includes a built-in Lorem Ipsum generator. Type lorem and press Tab for a full paragraph, or lorem10 for exactly 10 words.
p*3>lorem30
This creates three paragraphs each containing 30 words of placeholder text — perfect for layout prototyping. You can try this instantly in the Live HTML/CSS/JS Editor.
Summary: Emmet Operator Quick Reference
!— HTML5 boilerplateE>N— child elementE+N— sibling elementE^N— climb up one levelE*N— repeat N times(E)— groupingE.class— add classE#id— add idE[attr]— add attributeE{text}— add text contentE$— counter in nameslorem— lorem ipsum text
Combine these operators and within a week of practice you'll find yourself writing full page scaffolds in seconds. Use the HTML Formatter to clean up any generated code, and test your work live in the Live HTML/CSS/JS Editor.