Emmet: 省略記法でラップ — コードを選択して1キーストロークでラップ
第14回では1行の省略記法を完全なHTMLに展開する方法を学びました。しかし実際の開発では、既にコードが書かれているシナリオの方がはるかに一般的です — 例えば、既にたくさんの
<li>項目を書いた後で、外側の<ul>ラッパーが欠けていることに突然気づく場合です。手動でラッパーを追加するには1箇所あたり4〜5行の繰り返し操作が必要です。このレッスンではEmmetの省略記法でラップアクションを教えます — コードを選択 + 省略記法を入力 = ワンクリックラッピング。これはEmmetのエディタ操作における2番目のコアアクションです。
1. 学習内容
- 省略記法でラップのコアメカニズム:コード選択 + 省略記法 = ラッピング
- トリガー方法:VSCode コマンドパレット(
Ctrl+Shift+P→Emmet: 省略記法でラップ)。WebStormCtrl+Alt+J、SublimeCtrl+Shift+Gなど - 単一要素ラッピング:
<p>text</p>→ ワンクリックでdiv.wrapper外側ラッパー - 複数行バッチラッピング:3行選択 →
ul>li*3一括再構成 - ネストラッピング:テキスト選択 →
a[href="..."]ワンクリックリンク挿入
2. あるフロントエンド開発者の実話
(1) 課題:HTMLを書き終えた後、外側ラッパーを忘れていたことに気づく
アリスは同僚のボブからコードを引き継ぎました。ボブはブログの「関連記事」モジュールを書きましたが、<ul>でラップするのを忘れていました:
<li><a href="/post-1">Vue 3 入門</a></li>
<li><a href="/post-2">React Hooks 実践</a></li>
<li><a href="/post-3">TypeScript 上級</a></li>
アリスは3つの<li>項目をラップする<ul class="related-posts">を追加したいと考えました。彼女は手動で試みます:最初の<li>の前に<ul>開始タグをコピーし、3番目の<li>の後に</ul>をコピー — 2回のコピペ操作。コードベースにこのようなギャップが5箇所ある場合(ブログ記事ページ、リストページ、詳細ページ、アーカイブページ、検索ページ)、10回のコピペ操作 + 5回のクラス名スペルチェックになります。
さらに悪いことに、彼女はよくミスをします:<li>の後に</ul>を貼り付けると誤って途中に配置され(<li><a>...</a></li></ul>)、DOM構造が壊れます。アリスは考えました:文字通り「外側ラッパーを追加する」だけなのに、なぜこんなに面倒なのか?「選択 + 省略記法入力 = 1ステップラッピング」の方法はないのか?
(2) 省略記法でラップによる解決策
省略記法でラップはEmmetの「逆 省略記法の展開」です — 空白から展開するのではなく、既存コードの周りにラッパーを追加するのです。
アリスの解決策:
- 3つの
<li>要素すべてを選択(Alt+マウスドラッグで列選択、またはCtrl+Lで行選択) Shift+Alt+,を押してラップをトリガー- 省略記法
ul.related-posts>を入力 - 外側の
<ul>付きで完全な構造に自動展開
この1つのテクニックで、アリスは5つの欠落ラッパーの修正を10回のコピペ操作 + 5チェックから5回の「選択 + ラップ」操作に削減しました。速度向上3〜5倍、タイプミスゼロ(Emmetがクラス名を自動生成)。
(3) メリット
省略記法でラップはEmmetのエディタ操作における「ブリッジ」です — 「最初に書いて、後で最適化」のワークフローを3〜5倍加速します。第14回の省略記法の展開(ゼロから展開)と第16回のBalance/次の編集ポイント(編集加速)と組み合わせることで、Emmetの完全な「入力 → 展開 → 編集 → ラップ」ワークフローが整います。このレッスンの後、アリスのラッパー追加、コンテナ挿入、一括再構成の時間が5分から1分に短縮されます。
3. 省略記法でラップのコア定義
省略記法でラップはEmmetの既存コードを書き換えるアクションです — 選択されたコード断片を新しい省略記法でラップします。
| 次元 | 詳細 |
|---|---|
| 目的 | 選択されたコードの周りにラッパーを追加し、新しい省略記法に従って再構成する |
| トリガーキー | VSCode Shift+Alt+,(カンマ)。他のエディタ Ctrl+Shift+A |
| 前提条件 | コードを選択��ている必要がある(選択なしの場合、Match Tag Pairを呼び出してコンテキストをラップ) |
| ラップ位置 | デフォルトで選択さ��たコンテンツを最後の要素の内部に配置($#プレースホルダーで上書き可能) |
| 複数行サポート | *は繰り返し要素をマーク。数字なしの*は「選択行数に応じて繰り返し」を意味 |
$#プレースホルダーを使用します — これがラップと展開を区別する重要な拡張です。
4. トリガー方法:エディタ比較
省略記法でラップのトリガーキーはエディタによって大きく異なります。このアクションは比較的新しく(2013年以降に追加)、実装の進捗がエディタによって異なるためです。
| エディタ | デフォルトトリガーキー | コマンドパレット | 備考 |
|---|---|---|---|
| VSCode | デフォルトなし(コマンドパレットを使用) | Emmet: 省略記法でラップ |
直接入力ボックスを開く |
| WebStorm / IntelliJ | Ctrl+Alt+J |
Emmet: 省略記法でラップ |
省略記法入力用ポップアップ |
| Sublime Text | Ctrl+Shift+G(Emmetプラグイン必要) |
emmet: wrap |
省略記法入力用ポップアップ |
| Atom | Ctrl+Shift+A |
Emmet: 省略記法でラップ |
コード選択を自動プロンプ�� |
Shift+Alt+,は編集 > ドキュメントのフォーマットであり、ラップではありません。コミュニティではよくShift+Alt+,をラップにカスタムバインドしますが、keybindings.jsonでの明示的なバインドが必要です。��マンドパレット(Ctrl+Shift+P → Emmet: 省略記法でラップ)が最も信頼性の高いエントリポイントです — すべてのエディタでサポートされています。他のエディタでは、ショートカットを押す前にコードを選択する必要がある場合があります。初回使用はコマンドパレットから始めてください:トリガー + 入力ボックス + Enter — 3ステップです。
5. 4つのラッピングモード
省略記法でラップは4つのラッピングモードをサポートし、4つの一般的なニーズをカバーします:外側ラッパーの追加、兄弟の追加、一括再構成、ネストラッピング。
(1) 単一要素ラッピング:外側レイヤーを追加
1要素を選択し、1省略記法でラップ。一般的なシナリオ:元は<p>text</p>、今は<div class="wrapper">の内部にラップする必要がある。
(2) 複数行バッチラッピング:N行選択 → 一括再構成
連続する複数行を選択し、*を使用して繰り返し要素をマーク。主な違いは数字なしの* — 「選択行数に応じて自動繰り返し」を意味します。
(3) ネストラッピング:テキスト選択 → 内部タグを追加
テキストまたはタグの一部を選択し、省略記法を使用して新しい要素の内部に埋め込みます。これは「リンク追加、スタイル追加、意味付け追加」の一般的なパターンです。
(4) 組み合わせラッピング:選択 + ネスト + 複数属性
選択 + ネスト + カスタム属性 + 複数クラスを同時に使用します。これはラップの「究極の形」です。
6. ハンズオン例
以下の4つの例で省略記法でラップの4つのラッピングモードをカバーします。
▶ サンプル: 単一要素ラッピング <p>text</p> → div.wrapper(難易度:★)
最も一般的なラップシナリオ — 単一要素に外側コンテナを追加します。
元のコード(HTMLファイル内):
<p>Hello World</p>
手順:
<p>Hello World</p>を選択(マウスドラッグまたはCtrl+L)Shift+Alt+,を押してラップをトリガー- 省略記法
div.wrapperを入力 - Enterを押して確認
展開結果:
<div class="wrapper">
<p>Hello World</p>
</div>
出力:
TEXT 📖 参照専用分解:`<p>Hello World</p>`を選択してラップを呼び出すと、Emmetは`<p>`全体を「ラップされるコンテンツ」として扱い、`div.wrapper`省略記法から外側構造を生成します。デフォルトでは、ラップは選択されたコンテンツを**最後の要素**の内部に配置します — ここでは`<p>`が`<div>`の子になります。これは最も直接的な単一要素ラッピングシナリオです:以前は孤立していた`<p>`が今は`<div class="wrapper">`でラップされています。Emmetは自動インデントします — `<p>`は2スペースインデントされ、第6回の暗黙的タグルールと一致します。この1ステップで5回の手動操作(開始タグコピー、貼り付け、インデント調整、終了タグコピー、貼り付け)を置き換えます。
▶ サンプル: リストラッピング — 3つの<li>を選択 → ul.nav(難易度:★★)
複数行バッチラッピング — 3つの<li>項目を選択し、ナビゲーションコンテナでワンクリックラップします。
元のコード:
<li><a href="/home">ホーム</a></li>
<li><a href="/about">概要</a></li>
<li><a href="/contact">お問い合わせ</a></li>
手順:
- 3行すべてを選択(マウスで3行ドラッグ、または
Ctrl+Lで1行 +Ctrl+Shift+Lで複数行) Shift+Alt+,を押してラップをトリガー- 省略記法
ul.nav>を入力 - Enterを押して確認
展開結果:
<ul class="nav">
<li><a href="/home">ホーム</a></li>
<li><a href="/about">概要</a></li>
<li><a href="/contact">お問い合わせ</a></li>
</ul>
出力:
TEXT 📖 参照専用分解:3行選択、ラップ呼び出し、`ul.nav>`を入力。Emmetは`ul.nav>`を「選択された3行がulの子になる」として扱います。注意:ここでは**`>`がキー**です — これは「選択されたコンテンツを子として」を示します。省略記法が`ul.nav`(`>`なし)と書かれていた場合、Emmetは3つの`<li>`要素を`<ul>`の兄弟として配置します(不正な構造)。`>`は「ラップ位置」を決定します — 子ノードラッピングか兄弟ラッピングか。一般的なルール:デフォルトでは`>`を使用して「子ノードラッピング」を明示的にマークします。`+`は「兄弟追加」に使用します。
▶ サンプル: リンクラッピング — textを選択 → a[href="..."](難易度:★)
ネストラッピング — テキストの一部を選択し、リンクタグでラップします。
元のコード:
<p>詳しくは弊社ウェブサイトをご覧ください。</p>
手順:
弊社ウェブサイトを選択(ダブルクリックまたはドラッグ)Shift+Alt+,を押してラップをトリガー- 省略記法
a[href="https://example.com"]を入力 - Enterを押して確認
展開結果:
<p>詳しくは<a href="https://example.com">弊社ウェブサイト</a>をご覧ください。</p>
出力:
TEXT 📖 参照専用分解:`弊社ウェブサイト`の文字列を選択し(周囲のスペースを除く)、ラップを呼び出し、`a[href="https://example.com"]`を入力。Emmetは`<a>`タグ全体を「ラップテンプレート」として扱い、選択されたコンテンツが`<a>`の内部テキストになります。注意:このシナリオでは`>`は不要です — `<a>`はリーフノード(子を配置する場所がない)だからです。**重要な詳細**:`a[href="..."]`では、`href`は属性であり、ラップされるコンテンツはテキストです — `>`は不要です。この「プレーンテキスト → タグ内テキスト」変換はEmmetで非常によく使われます。
▶ サンプル: 組み合わせラッピング — Welcomeを選択 → header.container>h1.title(難易度:★★)
組み合わせラッピング — 選択 + ネスト + カスタムクラス + 多層構造。
元のコード:
<h1>Welcome</h1>
手順:
- テキスト
Welcomeをダブルクリックで選択(<h1>タグ全体ではなくテキストのみ) Shift+Alt+,を押してラップをトリガー(VSCodeユーザー:コマンドパレットCtrl+Shift+P→Emmet: 省略記法でラップ)- 省略記法
header.container>h1.titleを入力 - Enterを押して確認
展開結果:
<header class="container">
<h1 class="title">Welcome</h1>
</header>
出力:
TEXT 📖 参照専用分解:この例はラップ + 展開を組み合わせています。`header.container>h1.title`には3つのEmmetメカニズムが同時に含まれています:① `header.container` — タグ + クラス、② `>` — 子ネスト、③ 選択されたコンテンツが最後の要素(h1)の内部に配置されます。Emmetは「header > h1」の2階層構造に従って展開し、選択されたテキスト`Welcome`を最後の要素(h1)のテキストコンテンツとして配置します。この1ステップで5回の手動操作を置き換えます:`<header class="container">`を書く、改行、`<h1 class="title">`を書く、Welcomeを書く、`</h1></header>`を書く。**重要な詳細**:**テキストのみ**を選択し、`<h1>...</h1>`タグ全体ではない — ラップのデフォルトは「選択されたコンテンツを生成されたスニペットの最後の要素の内部にそのまま配置する」だからです(公式ドキュメント)。`<h1>Welcome</h1>`全体を選択した場合、結果は`<h1 class="title"><h1>Welcome</h1></h1>`(ネストされたh1、不正なHTML)になります。**インデントに注意**:Emmetはh1を2スペース自動インデントします(headerがコンテナ)。第4回のネストルールと一致します。
7. 一般的な省略記法早見表
省略記法でラップは省略記法の展開と同じ省略記法を使用します — 任意のEmmet省略記法をラップパラメータとして使用できます。以下は4つのよく使われる省略記法タイプです:
| シナリオ | 省略記法 | 効果 |
|---|---|---|
| 外側ラッパー追加 | div.wrapper |
選択 + div外側 |
| 意味付け追加 | section.hero |
選択 + sectionセマンティックタグ |
| ナビゲーション追加 | ul.nav>li* |
選択N行 + ul/li構造 |
| リンク追加 | a[href="..."] |
選択テキスト + aタグ |
| ヘッダー追加 | header.container>h1.title |
選択 + 多層ネスト |
*>3と*3は異なります — ラップでの*>3は「選択行を×3回繰り返し」を意味しま��(例:ul>li*5で2行選択 → 10行出力)。*3は常に3回繰り返します。ラップでは*(数字なし)= 選択行数に基づく自動繰り返しが最も一般的です。
❓ よくある質問
Shift+Alt+,を押しても何も起きません — VSCodeのデフォルト「フォーマット」ショートカットが表示されます?Shift+Alt+Fは「ドキュメントのフォーマット」です。思い違いをしている可能性があります — ラップの実際のショートカットはShift+Alt+,(カンマキー、Mキーの右隣)です。それでも動作しない場合は、コマンドパレットフォールバックを使用してください:Ctrl+Shift+P → Emmet: 省略記法でラップ。<p>を選択したのに、ラップ後に外側の<div>だけが残ります?>が欠けているために発生します。��えば、div.wrapper(>なし)ではネスト構造が生成されず、Emmetは<div>を「選択コンテンツの隣の兄弟ノード」として追加するだけです。ラップのコアルールは「選択コンテンツ = 最後の要素の子」です — >を使用して「ラップ位置」を明示的に表現する必要があります。修正:省略記法をdiv.wrapper>に書き直してください。*Nを明示的に使用する必要があります。ul>li*5で3行選択 → 5行出力(選択行数を無視)。しかしより一般的なパターンは*(数字なし)= 選択行数に基づく自動繰り返しです。この「行数による自動」はラップのコア機能で、何行選択したかを数える手間を省きます。$#プレースホルダーは何に使いますか?いつ使用すべきですか?$#はラップ固有の「出力位置」プレースホルダーです — ラップ結果のどこに選択コンテンツを配置するかを制御します。構文:ul>li[title=$#]*>{$#}+img[alt=$#]。この省略記法の意味:選択コンテンツが3箇所に同時に表示されます(liのtitle属性、liのテキスト、imgのalt属性)。一般的なシナリオ:CSSコメントを属性、テキスト、altに同時にコピーする。通常の省略記法では*は不要です。通常のラップではコンテンツを最後の要素に配置するだけで済みます。📖 まとめ
- 省略記法でラップはEmmetの「逆展開」 — 既存コードにラッピングを追加
- トリガーキー:VSCode
Shift+Alt+,(カンマ)。他の��ディタCtrl+Shift+AまたはCtrl+Alt+J - 4つのラッピングモード:単一要素ラッピング、複数行バッチラッピング、ネストラッピング、組み合わせラッピング
- 省略記法のコア:
>は「ラップ位置」(子 vs 兄弟)を決定。*は「選択行数による繰り返し」を決定 - 数字なしの
*= 選択行数に基づく自動繰り返し。*Nは回数を明示的に指定 $#プレースホルダー:ラップ結果の複数位置(属性、テキスト、altなど)に選択コンテンツを表示
📝 練習問題
-
基本(難易度:★):HTMLファイルで、独立した
<p>Hello World</p>を書き、選択し、Shift+Alt+,を押してラップをトリガーし、div.wrapperと入力し、Enterを押してください。展開結果が<div class="wrapper"><p>Hello World</p></div>であることを確認してください。正しくない場合は、>を忘れていないかチェックしてください。 -
中級(難易度:★★):HTMLファイルで、3つの独立した
<li>要素を(ulなしで)書いてください。ラップを使用してバッチラッピングしてください:(a) 3行すべてを選択、(b)ul.nav>と入力して出力を確認、(c) 次にsection.hero>を使用して複数行ラッピングを確認(*は不要 — 選択自体が「ulの子として」を意味します)。3回のラップ操作の展開結果を記録してください。 -
応用(難易度:★★★):HTMLファイルで、ブログ記事の断片(
<h1>...</h1>+<p>...</p>+<p>...</p>)を書いてください。3回のラップ操作で完全なブログカード構造に変換してください:1回目のラップheader>h1+ 2回目のラップarticle.content>(p)*+ 3回目のラップsection.blog-post>。3回のラップ操作の最終結果を記録し(3階層ネスト構造になるはず)、「ラップ vs. 手動ラッピング」速度比較レポートを書いてください。