Emmet: Text Content `{text}` and Multi-`$` Zero-Padding
QUERY LENGTH LIMIT EXCEEDED. MAX ALLOWED QUERY : 500 CHARS
1. What You Will Learn
- Text content
{text}curly-brace syntax (including automatic special-character escaping) {text}adjacent to parent vs.>{text}nested: the difference between the two "position modes"- Combining numbering
$with{text}: each line of content gets a number (item 1, item 2, ...) - Multi-digit zero-padding
$$$$$$$$$: auto-generate 001, 002, 003 - Starting value
$@Nand reverse$@-: start numbering from a specified value, or count backwards
2. A Frontend Developer's Real Story
(1) The Pain: Tags Are Built, But Content Still Needs Typing Character by Character
Alice was building a "Features Showcase" section for a product landing page, requiring 6 cards, each containing an icon, title, description, and button. She first wrote the card structure using Lesson 06's () and implicit tags:
section.features>(.card*6>i.icon+h3+p+button.btn)
The structure was done in 1 line—Emmet expanded 6 cards, each with an icon, h3, p, and button. But then Alice had to write the content for each card: titles like "High Performance," "Ease of Use," "Scalable," "Secure," "Cross-Platform," "Open Source," a 30-character description for each, and the "Learn More" button text repeated 6 times.
Alice started by hand—expanded HTML with 30+ empty tags, filling in content one by one. Just the titles took 5 minutes, descriptions another 10, and finally she typed "Learn More" 6 times (or just copy-pasted it).
Even worse was the pagination: a 100-page product list with <li>Page 1</li> through <li>Page 100</li> at the bottom of each page. Alice gave up after 30 lines. She tried using $: (ul.pagination>li>a{Page $})*100—the expansion gave "Page 1" through "Page 100," but pages 1–9 came out as single-digit numbers, looking like a bug. She wanted "01," "02," ..., "99," "100"—the first 9 pages needed two-digit zero-padding, while the rest could display normally.
(2) How {text} and Multi-$ Zero-Padding Solve It
Emmet provides two complementary mechanisms:
Text content {text}: Content inside curly braces is inserted as a text node inside the tag. Alice's 6 cards could be written as:
section.features>(.card*6>(i.icon)+h3{High Performance}+p{This is the first description}+button.btn{Learn More})
But with 6 cards each needing different content, *6 can't simply repeat the same text—this is where looping templates with $ numbering come in.
Numbering $ and multi-digit zero-padding: $ is the current sequence number; $$ zero-pads to 2 digits; $$$ zero-pads to 3 digits. Alice's pagination can be written as:
(ul.pagination>li>a{Page $$})*100
Which expands to "Page 01," "Page 02," ..., "Page 99," "Page 100"—the first 9 are auto-zero-padded to 2 digits, and from page 10 onward they display normally.
Alice rewrote the entire Features section in one line:
section.features>(h2{Product Features})+((.card>(i.icon)+h3{Feature $}+p{This is feature $ of 6}+button.btn{Learn More})*6)
And the 100-line pagination:
(ul.pagination>li>a{Page $$})*100
Alice verified and exclaimed: "6 cards' content went from 30 hand-written lines to 1 line, and the 100-line pagination went from 200 lines to 1 line. Emmet's efficiency boost in batch content generation scenarios is 50x or more."
(3) Benefits
QUERY LENGTH LIMIT EXCEEDED. MAX ALLOWED QUERY : 500 CHARS
3. Text Content {text} Definition
{text} is Emmet's syntax for inserting a text node inside a tag. Content inside curly braces becomes the tag's inner text verbatim—it can include any characters (Chinese, spaces, punctuation, etc.).
(1) Shorthand Rules
| Abbreviation | Expansion | Notes |
|---|---|---|
a{Click me} |
<a href="">Click me</a> |
Single tag + single text block |
p{Hello world} |
<p>Hello world</p> |
p tag + text |
button{Submit} |
<button>Submit</button> |
Works in any language |
a{<strong>bold</strong>} |
<a href=""><strong>bold</strong></a> |
< and > auto-escaped to HTML entities |
Key Point: Special characters (
<>&) inside{text}are automatically escaped by Emmet to HTML entities (<>&). This is an HTML5 safety requirement—preventing user input with angle brackets from breaking document structure. If you want to insert real HTML tags (so<strong>is parsed as a tag rather than text), you'll need the "filters" covered in Lesson 13, or manually edit after expansion.
(2) Where {text} Can Be Placed Inside a Tag
| Position | Abbreviation | Expansion |
|---|---|---|
| Adjacent to tag name | a{Click me} |
<a href="">Click me</a> |
With > nesting |
p>{Click }+a{here} |
<p>Click <a href="">here</a></p> |
Bare {text} |
{ to continue} |
to continue (bare text, as an independent element) |
With $ numbering |
li{item $}*3 |
<li>item 1</li>, <li>item 2</li>, <li>item 3</li> |
4. Two Positions for {text}: Adjacent to Parent vs. Nested
This is the most refined design in Emmet's text content system. When {text} immediately follows a tag name, it does not change the parent context; but >{text} pushes the context one level deeper. The difference is the most common pitfall for beginners.
(1) Adjacent Mode: a{click}+b{here}
When {text} immediately follows a tag name (without a > prefix), the text is treated as a direct child of that tag, but it does not change the parent context—meaning subsequent + sibling elements remain at the same level as the current tag.
a{click}+b{here}
<a href="">click</a><b>here</b>
(2) Nested Mode: a>{click}+b{here}
When {text} is preceded by >, Emmet treats the >{text} as a child element and pushes the parent context inside a—subsequent + sibling elements are appended inside a.
a>{click}+b{here}
<a href="">click<b>here</b></a>
(3) Multi-Element Mixed Text: p{Click }+a{here}+{ to continue}
This classic example from the official documentation demonstrates the difference between the two modes:
p{Click }+a{here}+{ to continue}
<p>Click </p>
<a href="">here</a> to continue
p>{Click }+a{here}+{ to continue}
<p>Click <a href="">here</a> to continue</p>
Key Point: The first abbreviation (adjacent mode) produces 3 root-level elements (p, a, bare text), while the second (nested mode) puts the entire "Click here to continue" inside
<p>. The difference comes from>: in the first version,{Click }makes p into a "p with click text" (without drilling down), while the second version's>{Click }pushes the context from p into p's interior, so the subsequent+a{here}and+{ to continue}are both appended inside p.
▶ Example: Basic Text Content a{Click me} (Difficulty ⭐)
The first text content example from Emmet's official documentation—adding a block of text to an a tag.
Abbreviation:
a{Click me}
Expansion:
<a href="">Click me</a>
Output:
TEXT 📖 参照専用Breakdown: a is the tag name (which defaults to including href=""), and {Click me} is the text node. Emmet automatically adds the href="" attribute to a (HTML5 default behavior), and the text "Click me" becomes a's child node. Note: {text} after the a tag does not change the parent context—if followed by +b{some}, b will be a sibling of a, not a child of a.
▶ Example: Multi-Element Mixed Text p>{Click }+a{here}+{ to continue} (Difficulty ⭐⭐)
Use nested mode to put the entire "Click here to continue" inside <p>.
Abbreviation:
p>{Click }+a{here}+{ to continue}
Expansion:
<p>Click <a href="">here</a> to continue</p>
Output:
TEXT 📖 参照専用Breakdown: p>{Click } pushes the context inside p, and "Click " becomes p's first text child; +a{here} appends an a with "here" text inside p; +{ to continue} appends the bare text " to continue" inside p. The final p contains 3 children: text "Click ", an a tag, and text " to continue". Without > (i.e., p{Click }+a{here}+{ to continue}), p would only contain "Click ", and a and the bare text would become root-level siblings—resulting in <p>Click </p> followed by <a>here</a> and bare text.
5. Numbering $ and Multi-Digit Zero-Padding
$ is Emmet's numbering placeholder (introduced in Lesson 08). This lesson extends it with two advanced uses: multi-digit zero-padding and start/reverse control.
(1) Multi-Digit Zero-Padding $$ $$$ $$$$
Lesson 08 used a single $ to generate 1, 2, 3. When the number range exceeds 9 (e.g., 100 table row numbers), a single $ displays mixed digit widths: 1, 2, ..., 9, 10, 11. Multiple $ characters make numbering auto-zero-pad to a fixed minimum width:
$ Count |
Expanded Form (*5) |
Use Case |
|---|---|---|
$ |
1, 2, 3, 4, 5 | Simple lists |
$$ |
01, 02, 03, 04, 05 | Small lists, months |
$$$ |
001, 002, 003, 004, 005 | Order numbers, table row IDs |
$$$$ |
0001, 0002, ... | Thousand-row tables, chapter numbers |
Key Point: The number of
$characters determines the minimum padding width. If the actual number exceeds this width, Emmet does not truncate—*12with$$expands to01, 02, ..., 09, 10, 11, 12(the first 9 are zero-padded; the last 3 display normally). This semantic is "padding width = minimum width, not maximum."
(2) Starting Value $@N and Reverse $@-
By default, numbering starts from 1 ascending. Use @N to start from N, and @- for descending:
| Modifier | Meaning | Example (*5) |
|---|---|---|
$ (default) |
Ascending, from 1 | 1, 2, 3, 4, 5 |
$@3 |
Ascending, from 3 | 3, 4, 5, 6, 7 |
$@- |
Descending (iteration count → 1) | 5, 4, 3, 2, 1 |
$@-3 |
Descending, from 3 backward | *5 → 7, 6, 5, 4, 3 (based on @-3 start + iteration count overlay) |
Note:
$@-3is supported in Emmet 1.2+. Common combinations are$@N(starting value) and$@-(descending starting from the iteration count). In@N, N is the starting value, not the ending value.
▶ Example: Numbering + Text ul>li{item $}*3 (Difficulty ⭐)
Embed $ inside {text} so each li's content carries an auto-number.
Abbreviation:
ul>li{item $}*3
Expansion:
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
Output:
TEXT 📖 参照専用Breakdown: li{item $} is "an li tag + a block of text (item + current number)," and *3 repeats this template 3 times. Each repetition replaces $ with the current iteration number (1, 2, 3). The final 3 li elements each contain a block of "item N" text. This is Emmet's core pattern for scenarios like todo lists, feature lists, and FAQ numbering. Note: the space after "item" is part of the text (not an operator).
▶ Example: Zero-Padding ul>li{$$}*5 (Difficulty ⭐)
2-digit zero-padding—the first 9 elements auto-zero-pad; numbers beyond 9 display normally.
Abbreviation:
ul>li{$$}*5
Expansion:
<ul>
<li>01</li>
<li>02</li>
<li>03</li>
<li>04</li>
<li>05</li>
</ul>
Output:
TEXT 📖 参照専用Breakdown: $$ means "display the current number with 2 digits." *5 repeats li 5 times, with $ values of 1, 2, 3, 4, 5—after 2-digit zero-padding, they become 01, 02, 03, 04, 05. With *12, the expansion would be 01, 02, ..., 09, 10, 11, 12—the first 9 are zero-padded, while the last 3 exceed 2 digits and display normally (no truncation). Zero-padding scenarios: pagination page numbers, months, product SKU codes.
▶ Example: Starting Value + Reverse ol>li{Step $@3}*5 (Difficulty ⭐⭐)
A 5-step process starting from 3—use $@3 to control the starting value.
Abbreviation:
ol>li{Step $@3}*5
Expansion:
<ol>
<li>Step 3</li>
<li>Step 4</li>
<li>Step 5</li>
<li>Step 6</li>
<li>Step 7</li>
</ol>
Output:
TEXT 📖 参照専用
QUERY LENGTH LIMIT EXCEEDED. MAX ALLOWED QUERY : 500 CHARS
6. Complete Example: Paginator + Numbering + Text Content
Combine {text}, multi-$ zero-padding, and $@N starting value—a 100-page paginator with each page displayed in 2-digit zero-padded format.
▶ Example: 100-Page Paginator (Difficulty ⭐⭐)
Abbreviation:
(ul.pagination>li.page$$>a{Page $$})*100
Expansion (excerpt):
<ul class="pagination">
<li class="page01"><a href="">Page 01</a></li>
<li class="page02"><a href="">Page 02</a></li>
<li class="page03"><a href="">Page 03</a></li>
<!-- ... -->
<li class="page09"><a href="">Page 09</a></li>
<li class="page10"><a href="">Page 10</a></li>
<li class="page11"><a href="">Page 11</a></li>
<!-- ... -->
<li class="page99"><a href="">Page 99</a></li>
<li class="page100"><a href="">Page 100</a></li>
</ul>
Output:
TEXT 📖 参照専用
QUERY LENGTH LIMIT EXCEEDED. MAX ALLOWED QUERY : 500 CHARS
❓ よくある質問
QUERY LENGTH LIMIT EXCEEDED. MAX ALLOWED QUERY : 500 CHARS
QUERY LENGTH LIMIT EXCEEDED. MAX ALLOWED QUERY : 500 CHARS
QUERY LENGTH LIMIT EXCEEDED. MAX ALLOWED QUERY : 500 CHARS
QUERY LENGTH LIMIT EXCEEDED. MAX ALLOWED QUERY : 500 CHARS
📖 まとめ
{text}is the text content syntax; content inside curly braces becomes the tag's text node (e.g.,li{item $}*3→ "item 1," "item 2," "item 3")<>&inside{text}are auto-escaped to HTML entities (<>&)- Adjacent mode
a{text}does not change parent context; nested modea>{text}pushes context one level deeper $is the numbering placeholder; multiple$auto-zero-pad:$$= 2 digits,$$$= 3 digits,$$$$= 4 digits (padding width = minimum width; no truncation when exceeded)$@Nstarts numbering from N;$@-produces descending numbering (based on iteration count)
📝 練習問題
- Basic (Difficulty ⭐): Write one-line Emmet abbreviations that expand to: (a) a
button{Sign Up}tag; (b) a<strong>tag with text "Warning"; (c) ap>loremparagraph (i.e.,<p>Lorem ipsum...</p>, not covered in this lesson; Lorem is covered in the next lesson). - Intermediate (Difficulty ⭐⭐): Write a 12-item "Month List"
ol>li{Month $$}*12and verify the expansion (should be "Month 01" through "Month 12"). Then rewrite as a "Quarter List"ol>li{Quarter $}*4, verifying numbering from 1–4. Finally, write a "Product Features Section" with 5 cards, each containing<h3>Feature $</h3>and<p>Description for feature $</p>, all in one Emmet line. - Challenge (Difficulty ⭐⭐⭐): Write a 100-page paginator with 3-digit zero-padding (
Page 001throughPage 100). Requirements: (a) class usingpage$$$(3-digit zero-padding); (b) text usingPage $$$(3-digit zero-padding); (c) starting page using$@1(same as default behavior but explicitly declared). Verify the expansion in one Emmet line, and explain why$$$does not truncate numbers beyond 99 (hint: Emmet's zero-padding = minimum width, not maximum width).