Emmet: Writing HTML at Speed

Type an abbreviation, press Tab, get a block of markup. Emmet is built into most editors and turns twenty keystrokes into three.

Concept

Emmet expands short abbreviations into full markup. It is built into VS Code and most other current editors with no installation - type the abbreviation and press Tab.

It is a genuine speed difference, and it is a small syntax to learn: the abbreviations are CSS selectors, read as structure.

The starting point

!

One character, 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>

The syntax

Elements, classes and ids

div            ->  <div></div>
p.lead         ->  <p class="lead"></p>
div#main       ->  <div id="main"></div>
div.card.wide  ->  <div class="card wide"></div>
.card          ->  <div class="card"></div>        (div is the default)
span.tag       ->  <span class="tag"></span>

Nesting and siblings

ul>li          child
h2+p           sibling
ul>li^p        climb up one level
(header>h1)+main   grouping
nav>ul>li>a
<nav>
    <ul>
        <li><a href=""></a></li>
    </ul>
</nav>

Repetition and numbering

ul>li*5              five list items
ul>li.item$*3        item1, item2, item3
ul>li.item$$*3       item01, item02, item03
ul>li.item$@3*3      start numbering at 3
ul>li.item$@-*3      count downwards

Text and attributes

p{Hello}                      ->  <p>Hello</p>
a[href=/about]{About}         ->  <a href="/about">About</a>
img[src=a.jpg alt=A map]      ->  <img src="a.jpg" alt="A map">
input[type=email required]    ->  <input type="email" required>

Placeholder text

lorem        a paragraph of filler
lorem10      ten words
p*3>lorem15  three paragraphs of fifteen words each

Worked examples

A navigation menu

nav[aria-label=Main]>ul>li*4>a[href=#]{Item $}
<nav aria-label="Main">
    <ul>
        <li><a href="#">Item 1</a></li>
        <li><a href="#">Item 2</a></li>
        <li><a href="#">Item 3</a></li>
        <li><a href="#">Item 4</a></li>
    </ul>
</nav>

A card grid

.grid>article.card*3>(h3>a[href=#]{Title $})+p{Summary}

A table

table>caption{Fees}+thead>tr>th[scope=col]*3^^tbody>tr*3>td*3

A labelled form field

p>label[for=email]{Email address}+input[type=email id=email name=email required]

A full page skeleton

!>header>nav>ul>li*3>a[href=#]^^^^main>h1{Title}+p>lorem20^^^footer>p>small{Copyright}

Wrapping existing content

Select some lines, open the command palette, and choose Emmet: Wrap with Abbreviation. Type an abbreviation and the selection is wrapped.

Selected:
  Design
  Data science
  Civil

Abbreviation:  ul>li*
<ul>
    <li>Design</li>
    <li>Data science</li>
    <li>Civil</li>
</ul>

The trailing * with no number means once per selected line. This is the single most useful Emmet feature after !, and the one most people never discover.

Other Emmet actions worth binding

ActionDoes
Balance (outward)Expands the selection to the enclosing tag
Go to Matching PairJumps between opening and closing tags
Remove TagDeletes a tag and keeps its contents
Split or Join TagConverts between self closing and paired
Toggle CommentComments the tag under the cursor

A caution

Emmet makes it easy to generate a great deal of markup quickly, and quantity is not the goal. div*10>div*3 produces thirty elements in one keystroke and none of them mean anything.

Use it to type the markup you were going to write anyway - which means writing article, nav, h2 and ul in the abbreviation, not div.

Important rules

  • Emmet expands on Tab in HTML files by default.
  • div is the implied element when only a class or id is given.
  • $ is the counter, @ sets its start and direction.
  • ^ climbs a level, + makes a sibling, > makes a child.
  • Text in braces, attributes in square brackets.
  • Wrap with Abbreviation works on a selection.

Common mistakes

  • Not knowing ! exists and typing the boilerplate by hand.
  • Forgetting ^ and nesting everything ever deeper.
  • Generating div soup because divs are the default.
  • Never using Wrap with Abbreviation, which is where most of the value is.
  • Expecting expansion in a file the editor does not treat as HTML.

Best practices

  • Learn !, >, +, *, ^, $, braces and brackets. That is the whole language.
  • Write semantic element names in the abbreviation.
  • Use Wrap with Abbreviation to convert pasted text into markup.
  • Build snippets for structures you write repeatedly.
  • Reformat after expanding so the indentation matches the project.

Practice

  1. Generate a full page skeleton with header, nav, main and footer from one abbreviation.
  2. Build a table with a caption, three header cells and three rows of three.
  3. Paste six lines of text and wrap them as a list with one command.
  4. Write an abbreviation for a labelled form field and reuse it five times.

Useful resources

Hand picked references for this topic
Written by Lorens Mishra

Default administrator account created by the installer.

Continue reading

All HTML notes →
HTML

Project Exams

Five larger assessments where the deliverable is a working site. Requirements, constraints and a rubric for each.

Read more

Discussion

0 comments
Sign in to join the discussion.

No comments yet. Be the first to say something.