Emmet: ID and Class

レッスン03では、[YIJIAN 0 PH]と[YIJIAN 1 PH]を簡単に紹介しました。このレッスンでは、これら2つの「CSSセレクタースタイル」の速記演算子について体系的に説明します。Emmetの略語は、構造と属性の両方を一度に表現することができます。最も重要なルール: HTMLコンテキストでタグ名を省略するとデフォルトは[YIJIAN 2 PH]になり、Emmetはクラス名に基づいて別の要素を決して「推測」しません(クラスが[YIJIAN 3 PH]であっても、[YIJIAN 4 PH]にはなりません)。

1.学ぶこと


2.フロントエンド開発者の実話

###( 1)痛み:タグと属性は常に2つの別々のパスが必要でした

Alice was upgrading the styling of a login form. She needed to add class="btn btn-primary btn-lg" to every <button> and id="loginForm" with class="form-horizontal" to the form itself. Manually, every tag required writing the full structure:

HTML
<button class="btn btn-primary btn-lg">Login</button>
<input id="username" class="form-control" type="text" name="user">

Every tag repeated the tag name plus attributes, and the order of tags and attributes relied on memory. By her count: an 8-line login form required hand-writing 8 tags + 24 attribute names = 32 repeated text segments. Just typing the quotes and equals signs for attributes was making her fingers ache.

Even worse: she recalled a previous project where she mistakenly assumed .btn would automatically trigger a <button> tag—a misunderstanding that sent her down a troubleshooting rabbit hole. Emmet's implicit tag rule absolutely does not switch tag names based on class names.

(2) How .class and #id Shorthand Solves It

Emmet uses exactly the same syntax as CSS selectors to express attributes—.btn directly adds to the current tag's class attribute, and #loginForm adds to the id attribute. This syntax lets you write attributes at the same time you write the tag structure, without switching between "tag mode" and "attribute mode."

Alice rewrote the entire login form with a single line of Emmet:

TEXT 📖 参照専用
form#loginForm.form-horizontal>(input#username.form-control[type=text name=user])+(input#pwd.form-control[type=password name=pwd])+(button.btn.btn-primary.btn-lg{Login})

#loginForm.form-horizontal sets both id and class simultaneously. .btn.btn-primary.btn-lg chains three classes with . in one go. 8 tags + 24 attributes, handled in 1 line. From 32 repeated text segments to 1 line, from 5 minutes to 12 seconds.

(3) Benefits

.class and #id are the key operators that merge "structure" and "attributes" into one in Emmet. After this lesson, Alice can write attributes for 80% of her tags simultaneously; the multi-class syntax is identical to CSS, with nearly zero learning curve; and remembering the "omit tag name → div" implicit rule (even if the class is btn, it stays a div) prevents her abbreviations from being misled by class names.


3. .class: CSS Selector-style Class Attribute

.classname in Emmet is equivalent to adding class="classname" to the current tag. When no tag is specified (Lesson 03 implicit rule), it defaults to div.

Abbreviation Expansion Notes
.box <div class="box"></div> Implicit div
p.text <p class="text"></p> Explicit p
section.hero <section class="hero"></section> Explicit section
a.link <a href="" class="link"></a> Explicit a, a auto-adds href

Tip: Multiple classes are chained with . with no spaces between class names.btn.btn-primary means two classes: btn and btn-primary. Spaces in Emmet are stop characters; they are parsed as multiple independent abbreviations.


4. #id: CSS Selector-style id Attribute

#idname in Emmet is equivalent to adding id="idname" to the current tag. Usage is completely symmetric with .class and corresponds to the CSS ID selector (#id).

Abbreviation Expansion
#main <div id="main"></div>
header#top <header id="top"></header>
form#login <form id="login"></form>
div#app <div id="app"></div>

(1) id and class Can Be Mixed

#id and .class on the same tag have no ordering requirement and can be freely combined:

Abbreviation Expansion
#main.container <div id="main" class="container"></div>
.container#main <div class="container" id="main"></div>
header#top.nav <header id="top" class="nav"></header>
nav.main.dark <nav class="main dark"></nav>

Key Point: Emmet's #id and .class come from CSS selector syntax, but the semantics are reversed—CSS uses # and . to select existing elements, while Emmet uses # and . to generate elements with those attributes. Same syntax, opposite purpose.


5. Practical Examples

The following 5 examples cover all core scenarios for .class and #id—from basic single class, to multiple classes, to attribute chains in nested structures.

▶ Example: Single Class .container (Difficulty ⭐)

The most basic class shorthand: omit the tag name and it defaults to div.

Abbreviation:

HTML
.container

Expansion:

HTML
<div class="container"></div>

Output:

TEXT 📖 参照専用
Implicit div tag + single class. This shorthand is extremely common in utility-class frameworks like Bootstrap and Tailwind. .container in Bootstrap is a fixed-width container; in Tailwind it is a max-width utility. Note: when you write .container inside a ul parent, .container still implicitly becomes a div—unless your abbreviation position genuinely requires a li child of ul, .container will never auto-morph into a semantic element like li (Lesson 06 implicit rules).

▶ Example: Single ID #main (Difficulty ⭐)

The most basic id shorthand.

Abbreviation:

HTML
#main

Expansion:

HTML
<div id="main"></div>

Output:

TEXT 📖 参照専用
An empty div with id="main". In HTML, ids must be globally unique, so this shorthand is often used for "page main container" or "route mount point." Note: Emmet does not validate id uniqueness—multiple #main abbreviations all expand to id="main"; whether that causes a conflict is up to you to check manually.

▶ Example: Multi-Class Chain .btn.btn-primary.btn-lg (Difficulty ⭐⭐)

Chaining multiple classes with .—note: the default is still <div>; it will not become <button> just because a class name contains "btn."

Abbreviation:

HTML
.btn.btn-primary.btn-lg

Expansion:

HTML
<div class="btn btn-primary btn-lg"></div>

Output:

TEXT 📖 参照専用

QUERY LENGTH LIMIT EXCEEDED. MAX ALLOWED QUERY : 500 CHARS

▶ Example: id + class Combination #header.nav (Difficulty ⭐)

Mixing #id and .class—order does not affect the expansion result.

Abbreviation:

HTML
#header.nav

Expansion:

HTML
<div id="header" class="nav"></div>

Output:

TEXT 📖 参照専用
Sets both id="header" and class="nav" at once. This is the classic shorthand for a page header navigation. The order of id and class can be swapped (.nav#header produces the same result), but writing id first aligns with the semantic habit of "establish unique identity, then describe type." This shorthand is important in multi-page applications—the #header id remains the same across pages, so CSS can target it uniformly.

▶ Example: Nested Attribute Chain div#main.container>section.content>p.text (Difficulty ⭐⭐)

Distributing id and class across every level of nesting—3 levels of tags, each with its own attributes.

Abbreviation:

HTML
div#main.container>section.content>p.text

Expansion:

HTML
<div id="main" class="container">
  <section class="content">
    <p class="text"></p>
  </section>
</div>

Output:

TEXT 📖 参照専用

QUERY LENGTH LIMIT EXCEEDED. MAX ALLOWED QUERY : 500 CHARS


6. Complete Example: Login Form + Attribute Chain

Combine .class and #id with the > and + operators from earlier lessons to build a complete login form in one line.

▶ Example: Complete Login Form (Difficulty ⭐⭐)

Abbreviation:

HTML
form#loginForm.form-horizontal>(input#user.form-control[type=text name=user placeholder="Username"])+(input#pwd.form-control[type=password name=pwd placeholder="Password"])+(button.btn.btn-primary.btn-lg{Login})

Expansion:

HTML
<form id="loginForm" class="form-horizontal">
  <input id="user" class="form-control" type="text" name="user" placeholder="Username">
  <input id="pwd" class="form-control" type="password" name="pwd" placeholder="Password">
  <button class="btn btn-primary btn-lg">Login</button>
</form>

Output:

TEXT 📖 参照専用
Breakdown: form gets both id and class. Inside, + adds two input siblings, then + adds a button. Both inputs and buttons get styling classes via .class, and inputs additionally use #id (optional) and [type=name=placeholder=] (covered in the next lesson) for attributes. Note that the button level explicitly writes `<button>`, so .btn.btn-primary.btn-lg becomes a class on a button rather than an implicit div. This is the standard pattern of "using explicit tags to avoid misjudgment."

❓ よくある質問

Q Does .btn.btn-primary expand to <button> or <div>? Why?
A <div>. Emmet's implicit tag rules depend only on parent element context, not on the literal value of class/id names. Unless you explicitly write button.btn.btn-primary, the default when there is no explicit tag is always div. This is the most common pitfall for beginners—many assume .btn should map to button, and then think the div expansion is a bug.
Q Do hyphens in #my-id need to be escaped?
A No. Hyphens in #my-id and .my-class are valid CSS selector characters; Emmet treats them as part of the id/class name. However, an initial hyphen (e.g., #-main) is not valid CSS syntax and Emmet may throw an error or parse unexpectedly.
Q How many times can # and . be mixed on the same tag?
A Theoretically unlimited. #a.b.c.d.e.f.g is fully valid and expands to <div id="a" class="b c d e f g"></div>. In practice, ids should be unique and limited in number, and too many classes make style management harder. Recommendation: 1 id + 2–4 classes is a common "reasonable upper limit."
Q What is the difference between #header and .header after expansion?
A .header<div class="header"></div> (class is for reusable "type"); #header<div id="header"></div> (id is for "unique identity"). At the CSS selector level: .header can match multiple elements, #header can only match one. At the HTML semantic level: class is typically used for "component type" (button, card, form), while id is typically used for "page anchor or JS hook."

📖 まとめ


📝 練習問題

  1. Basic (Difficulty ⭐): Write 5 Emmet abbreviations that expand to: (a) .alert; (b) #app; (c) .btn.btn-danger; (d) #header.nav.dark; (e) a.btn.
  2. Intermediate (Difficulty ⭐⭐): Analyze the expansion structure of header#top.navbar>nav.main>ul.nav-list>li.nav-item*3>a.nav-link (name each tag and attribute at every level), and verify that Emmet's expansion matches your analysis.
  3. Challenge (Difficulty ⭐⭐⭐): Write a complete Bootstrap-style "card grid": outer div.container, containing div.row, which contains 3 .card elements. Each card includes img.card-img-top, div.card-body, h5.card-title, p.card-text, and a.btn.btn-primary. Write the entire structure in one line of Emmet, and explain why .btn.btn-primary here automatically becomes <a> instead of an implicit div (hint: is there an explicit tag in the abbreviation?).
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%