As you write HTML, typing the same symbols over and over—<, >, closing tags—gradually gets tedious. That’s where Emmet comes in. Type a short keyword and press Tab, and it snaps into a long tag for you—it’s magic. And since it’s built into VSCode from the start, you can use it right away without installing anything.
Start with this! The HTML boilerplate in one shot
In a new .html file, type just a single half-width ! and press Tab. Then—
! → Tab<!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>From <!DOCTYPE html> through <html>, <head>, and <body>, the whole “frame” of HTML comes out. The boilerplate you used to write by hand every time is complete with just one character.
The inner text, too
Text you write inside {} becomes the content of the tag as is.
h1{My first heading}→<h1>My first heading</h1>a{See more}→<a href="">See more</a>
Connect and combine them
Emmet’s real strength is being able to “assemble” tags with symbols.
| Symbol | Meaning | Example |
|---|---|---|
> | Child (put inside) | ul>li |
+ | Sibling (line up beside) | h1+p |
* | Repeat | li*3 |
() | Group | (li>a)*3 |
For example, type ul>li*3 and press Tab:
ul>li*3 → Tab<ul>
<li></li>
<li></li>
<li></li>
</ul>The list box and its three items are all there in an instant.
You can add classes and IDs with symbols too
Using the same notation as CSS, you can specify class and id along with it.
| Symbol | Meaning | Example |
|---|---|---|
. | class | div.card |
# | id | div#header |
div.card → Tab<div class="card"></div>You can combine . and #, too. div.card#main gives you <div class="card" id="main"></div> in one shot. You can also omit the tag name—typing just .card gives the same result as div.card.
You can write attributes with [] too
Attributes like href and type go inside [].
a[href="https://example.com"]{Practice site} → Tab<a href="https://example.com">Practice site</a>Like input[type="checkbox"] → <input type="checkbox">, it’s handy for making form parts too. By the way, for img you don’t have to write attributes one by one—just type img and it expands to <img src="" alt="">, with the frames for the needed attributes.
Combine symbols to make “one chunk”
All the symbols so far can be mixed together. For example, a whole card part in a single line.
div.card>h2{Title}+p{Some description text} → Tab<div class="card">
<h2>Title</h2>
<p>Some description text</p>
</div>The trick is that you can write the structure “inside a box, a heading and a paragraph” in the very order you thought of it. As you get used to it, you’ll be able to drop the blueprint in your head straight into one line.
It actually works in CSS too
Emmet isn’t just for HTML. Inside a CSS file too, you can use property shorthands.
| Type | Expands to |
|---|---|
m10 | margin: 10px; |
p20 | padding: 20px; |
df | display: flex; |
tac | text-align: center; |
c | color: #000; |
The way to remember it is simple: the first letters of the property name + the value. You don’t have to memorize them all—type something plausible and suggestions come up, so just try something and treat a hit as a bonus.
Add sequential numbers and mass-produce at once
Using $, you can assign sequential numbers within a repeat.
li.item$*3 → Tab<li class="item1"></li>
<li class="item2"></li>
<li class="item3"></li>You no longer need to retype the same class name one by one. Making it $$ (doubling the $) gives zero-padded numbers like item01.
Summary
!→Tabgets you the HTML boilerplate in one shot- You can write the
h1{...}content and thea[href="…"]attributes together - You can assemble tags with
>and*, likeul>li*3 div.card#maingets classes and IDs, andli.item$*3gets sequential numbers, all in one shot- In CSS too, you can use shorthands like
m10→margin: 10px;
When typing out tags takes less effort, you can focus that much more on “what to make.”