Emmet: Balance, Jump, and Select

In lessons 14–15 you learned Expand and Wrap — Emmet's two core "input" actions. But in real development, you still need to edit after expanding — changing the content of 5 <li> items, adding comments, removing outer tags. This lesson teaches Emmet's "editing trio": Balance / Next Edit Point / Select Item, plus Toggle Comment and Remove Tag. These 5 actions let you continue accelerating 3–5x after expansion.

1. What You'll Learn


2. A Frontend Developer's Real Story

(1) Pain Point: After Expanding 100 Lines of HTML, Finding the Place to Edit Takes 30 Seconds

Alice has written the HTML container for a blog post page:

HTML
<article>
  <header>
    <h1>Hello World</h1>
    <time>2026-07-31</time>
  </header>
  <section>
    <p>...</p>
    <p>...</p>
  </section>
  <footer>
    <address>...</address>
  </footer>
</article>

She now needs to make 3 bulk replacements:

  1. Change <h1>Hello World</h1> to <h1>Hello Emmet</h1>
  2. Add one line of lorem ipsum placeholder text to each of the 2 <p> tags
  3. Add a comment to <footer>

Her workflow:

  1. Find <h1>: Ctrl+F → type Hello World → replace with Hello Emmet (5 seconds)
  2. Find 1st <p>: Ctrl+F → replace (5 seconds); find 2nd <p>: Ctrl+F again (5 seconds)
  3. Find <footer>: Ctrl+F → add comment (5 seconds)

Total: 20 seconds, 9 Ctrl+F operations. Alice thinks: HTML is inherently a tree structure — there should be "structure-based navigation" shortcuts. Move the cursor to <h1>, press a single key to jump directly to </h1>, press a key to jump to the outer <header>... Emmet should have these "tree structure shortcuts".

(2) The Emmet Editing Trio Solution

Emmet's 5 editing actions are "tree structure shortcuts" — turning the HTML/CSS tree structure into your navigation tool.

Alice's solution:

  1. Balance: Cursor inside <h1>, press Ctrl+Alt+B to select up to </h1> closing tag → 2 seconds
  2. Next Edit Point: After expanding ul>li*3, press Ctrl+Alt+→ to jump to each <li>'s content position → 5 seconds
  3. Select Item: Cursor on <p>, press Shift+Ctrl+. to select the next <p> → 3 seconds
  4. Toggle Comment: Cursor on <footer>, press Ctrl+/ to add <!-- --> comment → 1 second
  5. Remove Tag: Cursor on <h1>, press Shift+Ctrl+; to delete <h1> but keep "Hello World" → 2 seconds

Total: 13 seconds, 5 shortcut operations. 35% faster than Ctrl+F replacement, with zero false replacements (Ctrl+F can easily match multiple locations).

(3) Benefits

The editing trio reduces "post-expansion editing" time from 20 seconds to 13 seconds, and more importantly reduces misoperations — Ctrl+F replacement can easily skip or over-replace; Emmet's structural navigation moves along the HTML tree, never misfiring. After mastering these 5 actions, Alice's total editing time for a 5-paragraph article page drops from 5 minutes to 2 minutes.


3. Core Definition of the 5 Editing Actions

Emmet provides 5 "editing acceleration" actions covering the 5 most common post-expansion operations: tag jumping, tabstop navigation, element selection, comment toggling, and outer tag removal.

Action Purpose Use Case
Balance Select content (inward/outward balance) Select current tag content / outer
Go to Matching Pair Jump to matching tag Move to </tag> or <tag>
Next/Previous Edit Point Jump to next/previous tabstop Navigate editable positions after expansion
Select Item Select next/previous element with same name Batch-select similar elements
Toggle Comment Toggle comments HTML/CSS smart commenting
Remove Tag Strip outer tag Remove shell, keep content
📌 Key Point: Balance and Go to Matching Pair are two different actions. Balance selects (content or tag name), while Go to Matching Pair jumps (moves the cursor to the match position). This is the most common confusion for beginners — the former "selects", the latter "jumps".


4. Trigger Key Comparison Across 4 Editors

The 5 actions have significantly different trigger keys across 4 major editors because these are relatively new actions and implementation progress varies by editor. Key fact: VSCode has only 1 default keybinding for Emmet's built-in actions — Tab triggers Expand Abbreviation (lesson 14). All other Emmet actions (Balance / Wrap / Select Item / Remove Tag, etc.) have no default shortcut in VSCode and must be triggered via the Command Palette or custom keybindings.json.

Action VSCode WebStorm Sublime Atom
Expand Abbreviation Tab (default, lesson 14) Tab Ctrl+E Tab
Balance None (Command Palette / custom keybindings.json) Ctrl+] Ctrl+D Ctrl+Alt+B
Go to Matching Pair None (Command Palette / custom keybindings.json) Ctrl+M Ctrl+Alt+J Ctrl+Alt+J
Next Edit Point None (Command Palette / custom keybindings.json) Ctrl+Alt+→ Ctrl+Alt+→ Ctrl+Alt+→
Select Item None (Command Palette / custom keybindings.json) Shift+Alt+. Shift+Ctrl+. Shift+Ctrl+.
Toggle Comment No Emmet default (VSCode native Ctrl+/ comments current line) Ctrl+/ Ctrl+/ Ctrl+/
Remove Tag None (Command Palette / custom keybindings.json) Ctrl+Shift+Delete Ctrl+Shift+; Ctrl+Shift+;
💡 Tip: "None" in the table means VSCode does not ship the Emmet action bound to any key by default. Common community custom bindings (like Ctrl+Alt+B / Shift+Ctrl+. / Shift+Ctrl+;, etc.) must be explicitly declared in keybindings.json with commands like "command": "editor.emmet.action.balance" / "editor.emmet.action.selectItem" / "editor.emmet.action.removeTag". First-time use should start with the Command Palette (Ctrl+Shift+PEmmet: Balance, etc.) — this both verifies editor support for the action and reveals the exact command name (which you then write into keybindings.json).


5. Mermaid Diagram: Editor Cursor Movement Path

The diagram below shows the cursor navigation path between editable points (tabstops) after Emmet expands ul>li*3.

100%
graph TB
    Start([User types ul>li*3<br>Presses Tab to expand]) --> Expand[Emmet expands 4 lines of HTML]
    Expand --> S1[tabstop 1:<br>Content position of first li in ul]
    S1 -->|Press Ctrl+Alt+→| S2[tabstop 2:<br>Content position of second li in ul]
    S2 -->|Press Ctrl+Alt+→| S3[tabstop 3:<br>Content position of third li in ul]
    S3 -->|Press Ctrl+Alt+→| End([Expansion end point:<br>After ul closing tag])
    S1 -->|Press Ctrl+Alt+←| Start
    S2 -->|Press Ctrl+Alt+←| S1
    S3 -->|Press Ctrl+Alt+←| S2
    End -->|Press Ctrl+Alt+←| S3

    style Start fill:#3b82f6,color:#fff
    style Expand fill:#8b5cf6,color:#fff
    style S1 fill:#10b981,color:#fff
    style S2 fill:#10b981,color:#fff
    style S3 fill:#10b981,color:#fff
    style End fill:#ef4444,color:#fff
📌 Key Point: After expanding ul>li*3, there are 3 tabstops (each li's content position) + 1 end point (after </ul>). Next Edit Point jumps between these one by one. Backward jumps to the previous point, Forward jumps to the next. Notably: this is NOT "pressing Tab" — pressing Tab in VSCode after expansion is "indentation" or "accept Emmet expansion" (if still at the original shorthand), but to continue navigating tabstops after expansion, use Ctrl+Alt+→ instead of Tab.


6. Hands-On Examples

The following 5 examples cover the core scenarios of the editing trio + Toggle Comment + Remove Tag.

▶ Example: Balance — Jump to Matching <div> Tag (Difficulty ⭐)

The most common "tag navigation" — cursor inside <div>, press Balance to select content, press again to select the entire tag.

Original code:

HTML
<div class="container">
  <p>Hello World</p>
</div>

Steps:

  1. Place cursor anywhere inside the content area of <p>Hello World</p>
  2. Press Ctrl+Alt+B once → selects Hello World (content)
  3. Press Ctrl+Alt+B again → selects <p>Hello World</p> (entire p tag)
  4. Press Ctrl+Alt+B again → selects the entire <div> and all its content
  5. Continue pressing Ctrl+Alt+B → selection expands outward level by level (outward balance)

Press again (Shift+Ctrl+Alt+B) → selection contracts inward (inward balance)

Output:

TEXT 📖 Display only
Explanation: Balance's "bidirectional balancing" is a unique Emmet feature — most editors only support "outward expansion", but Emmet also supports inward contraction. This "adjustable selection size" design makes Balance a versatile tool for HTML editing: select 1 word, select 1 tag, select 1 container, select 1 section — adjust level by level with each Balance press. **Important detail**: Emmet's Balance is not "cursor movement" — it's "selection change". The cursor stays in place, but the selected range expands or shrinks. If you only want to "jump" without "selecting", use Go to Matching Pair.

▶ Example: Next Edit Point — Jumping Tabstops After Expansion (Difficulty ⭐⭐)

After expanding ul>li*3, press Ctrl+Alt+→ to jump to each li's content position.

Original code:

HTML
ul>li*3

Steps:

  1. Press Tab to trigger Expand → 4 lines of HTML appear
  2. Cursor is at tabstop 1 (inside the first li)
  3. Press Ctrl+Alt+→ → jump to tabstop 2 (inside the second li)
  4. Press Ctrl+Alt+→ → jump to tabstop 3 (inside the third li)
  5. Press Ctrl+Alt+→ → jump to the end point (after </ul>)

Expanded HTML:

HTML
<ul>
  <li>|</li>
  <li>|</li>
  <li>|</li>
</ul>

Output:

TEXT 📖 Display only
Explanation: Lesson 14 on Expand Abbreviation mentioned that "expansion includes tabstops" — but didn't explain how to navigate them. Next Edit Point is the dedicated action for "jumping to the next tabstop". `Ctrl+Alt+→` is forward, `Ctrl+Alt+←` is backward. **Why not use the Tab key?** Because after expansion completes, VSCode treats Tab as "indentation" (the cursor is already at an "editable position" inside the li's content), so it won't trigger Emmet navigation again. To "jump between tabstops", use `Ctrl+Alt+→`. This is Emmet's key design decision separating "input triggering" (Tab) from "editing navigation" (Ctrl+Alt+→).

▶ Example: Select Item — Progressive Granularity Selection (Difficulty ⭐⭐)

HTML contains a <p> with a class; the cursor is on the text. Press Select Item to progressively expand the selection — only within the current element, never jumping to adjacent elements.

Original code:

HTML
<p class="fruit">Apple</p>

Steps:

  1. Place cursor on the Apple text inside <p class="fruit">Apple</p>
  2. Press Shift+Ctrl+. once → selects Apple (text node)
  3. Press again → selects fruit (distinct class name)
  4. Press again → selects class="fruit" (attribute value)
  5. Press again → selects class="fruit" (full attribute)
  6. Press again → selects the entire <p class="fruit">Apple</p> (entire element)

Output:

TEXT 📖 Display only
Explanation: Select Item's "expanding selection" works progressively deeper **only within the current element** — from text → distinct class → attribute value → full attribute → entire element (official docs: "expands current selection to its parent item"). It does **not cross elements** — to jump from `<p>Apple</p>` to the next `<p>Banana</p>` for batch selection, use VSCode's `Ctrl+F2` (Change All Occurrences) or multi-cursor (`Ctrl+D` for next, `Ctrl+Shift+L` for all with same name) — those are native IDE features, not Emmet. **`Shift+Ctrl+.` is forward (outward expansion)**, `Shift+Ctrl+,` is backward (inward contraction). Similar behavior in CSS: selector → property → value; useful for "quickly selecting a single CSS property line" scenarios. This "progressive granularity expansion" mimics JetBrains IDE's Extend Selection (W/A style).

▶ Example: Toggle Comment — Switch Comments On/Off (Difficulty ⭐)

Cursor on the <footer> tag in HTML, press Ctrl+/ to add <!-- --> comment.

Original code (no comment):

HTML
<footer>
  <address>contact@example.com</address>
</footer>

Steps:

  1. Place cursor anywhere on the <footer> tag
  2. Press Ctrl+/ → the entire <footer> tag is wrapped with <!-- -->

Expanded:

HTML
<!-- <footer>
  <address>contact@example.com</address>
</footer> -->

Press Ctrl+/ again → comment removed (restores original HTML)

Output:

TEXT 📖 Display only
Explanation: Toggle Comment's "context awareness" is what distinguishes Emmet from regular editor commenting. Ordinary `Ctrl+/` only comments the current line; Emmet's Toggle Comment **recognizes the current context** — in HTML it comments the entire tag (since HTML comments can span lines), in CSS it comments the current rule or property. This "context awareness" makes Toggle Comment more useful than the IDE's built-in commenting — fewer keystrokes. **Note**: Toggle Comment is similarly context-aware in CSS — when the cursor is on the full `padding: 10px;` line, `Ctrl+/` comments the entire `padding: 10px;`; when the cursor is on the word `padding`, `Ctrl+/` still comments `padding: 10px;` (the entire property). Similarly in HTML — cursor anywhere in `<p>` comments the entire `<p>...</p>`.

▶ Example: Remove Tag — Strip Outer Tag, Keep Content (Difficulty ⭐⭐)

Cursor on <h1>, press Shift+Ctrl+; to delete <h1></h1> but keep the text content.

Original code:

HTML
<h1>Hello World</h1>

Steps:

  1. Place cursor on the <h1> tag
  2. Press Shift+Ctrl+; → deletes <h1> and </h1>, keeps "Hello World"

Expanded:

HTML
Hello World

Compound scenario: stripping nested outer tags

Original code:

HTML
<section class="hero">
  <h1>Welcome</h1>
</section>

Steps:

  1. Place cursor on the <section> tag
  2. Press Shift+Ctrl+; → deletes <section> and </section>, keeps <h1>Welcome</h1>

Expanded:

HTML
<h1>Welcome</h1>

Output:

TEXT 📖 Display only
Explanation: Remove Tag's "shell removal, keep content" is the most concise of Emmet's editing actions — one keypress strips the outer tag. Common scenarios: ① design revision — the original `<header>` container is no longer wanted, but the `<h1>` text inside needs to be preserved; ② temporary debugging — strip the outer layer to inspect styles; ③ refactoring — reduce DOM nesting depth. Note: Remove Tag doesn't strip multiple layers at once — to strip 3 layers of nesting (div > section > h1), press `Shift+Ctrl+;` 3 times consecutively. The semicolon key (`;`) in `Shift+Ctrl+;` is a "macro command" key in many editors — corresponding to Emmet's internal `removeTag` command.

7. Decision Tree for Choosing Among the 5 Actions

In real development, the 5 actions often need to be combined. Here's a decision tree:

Scenario Recommended Action Reason
Want to jump to </tag> to see the closing tag Go to Matching Pair Jump only, no selection
Want to select the entire <tag> to copy it Balance Selection expands 1 level
Want to bulk-replace 5 <p> elements Select Item Select elements with same name one by one
Want to comment out a <div> Toggle Comment Context-aware smart commenting
Want to temporarily strip outer <div> for debugging Remove Tag Shell removal, keep content
Want to locate editable positions after expansion Next Edit Point Jump to tabstops

❓ FAQ

Q What's the difference between Balance and Go to Matching Pair?
A Balance selects (selection changes), Go to Matching Pair jumps (cursor moves). The former is good for "copying an entire tag", the latter for "locating the closing tag to inspect it". Real scenario: when editing nested HTML, you want to see where <section> ends — use Go to Matching Pair to jump there; you want to copy the entire <section>...</section> block — use Balance to select it. Both are common; learn both.
Q Pressing Ctrl+Alt+→ jumps to the next tabstop, but wouldn't pressing Tab after expansion be simpler?
A After VSCode expansion, the Tab key is the regular indentation key when the cursor is at an li's content position — it won't trigger Next Edit Point. Tab and Next Edit Point are two different mechanisms: use Tab to accept completion or indent, use Ctrl+Alt+→ to jump to the next editable point. If you want to use Tab to jump tabstops, you need emmet.triggerExpansionOnTab set to true in settings.json (on by default), but this only applies "before expansion" — after expansion, Tab no longer carries "jump tabstop" semantics.
Q When Select Item selects HTML elements, do class and id count as "same name"?
A No. Select Item's "same name" matching is by tag name (<p> vs <p>), not by class or id. So <p class="a"> and <p class="b"> are both treated as "same-name elements" by Select Item. To select by class, use VSCode's "Change All Occurrences" (Ctrl+F2) — that's a native IDE feature, not something Emmet provides.
Q After Remove Tag, how do I restore the outer tag?
A Remove Tag has no "undo" semantics — 1 press strips 1 layer. But VSCode's Ctrl+Z undo will restore it. So the "regret" operation after Remove Tag is Ctrl+Z. If you frequently need "strip + restore" operations, consider using the reverse of Wrap (Remove Tag then Wrap) — but this is rarely needed in practice, so Remove Tag is usually paired with the undo key.

📖 Summary


📝 Exercises

  1. Basic (Difficulty ⭐): In your HTML file, write a nested structure (<div><section><p>...</p></section></div>), place the cursor on <p>, and press Balance 5 times. Record each selection range ("content" → "p tag" → "section content" → "section tag" → "div tag"). Screenshot the selection changes.

  2. Intermediate (Difficulty ⭐⭐): In your HTML file, write 3 <p> elements (<p>One</p>, <p>Two</p>, <p>Three</p>). Place the cursor on the tag name of the first <p> and press Select Item 6 times (Shift+Ctrl+.). Record the specific content selected each time (tag name / full content / next tag name / next full content). Finally, use Toggle Comment to comment out all 3 <p> elements as a group.

  3. Challenge (Difficulty ⭐⭐⭐): Write a complete HTML landing page container (article > header + section + footer with 3-level nesting). Optimize it using 5 actions in combination: (a) Expand article>header>h1+section.content>p*3+footer.address; (b) Next Edit Point to jump to each <p> and fill in content; (c) Balance to select the entire article tag and copy it; (d) Toggle Comment to comment out the footer; (e) Remove Tag to temporarily strip the article and inspect styles (use Ctrl+Z to undo). Record the trigger sequence and final state for all 5 actions, and write an "Editing Trio Workflow" vs. "Ctrl+F Replacement" efficiency comparison report.

Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏