クリーンなコードのための HTML フォーマットのベストプラクティス
ファイルを開いた瞬間、目に飛び込んでくるのは——インデントも何もない HTML の壁、タグがぎっしり詰め込まれ、div のスープが数百行にわたって続いている。閉じタグの漏れを見つけるのは至難の業です。誰もが一度は経験したことがあるでしょう。そして、適切な HTML フォーマットこそが、こうした苦痛を完全に解消してくれます。
整ったフォーマットの HTML は、見た目の美しさだけの問題ではありません。バグの発見速度、チームの協業効率、そしてコードベースの長期的な保守性に直接影響します。シンプルなランディングページでも複雑な Web アプリケーションでも、フォーマットの習慣がその後のすべてを左右するのです。
なぜ整った HTML フォーマットが重要なのか
可読性
コードは書かれる回数よりも読まれる回数のほうが圧倒的に多いものです。HTML が一貫したフォーマットルールに従っていれば、チームの誰でもひと目で構造を把握できます。ネストされた要素が明確になり、抜けているタグが際立ち、ドキュメント全体の流れが見通せるようになります。
保守性
半年後、あのコンポーネントを更新する必要が出てきます。きれいにフォーマットされていれば、すぐに修正に取りかかれます。フォーマットが乱れていると、構造を理解するだけで最初の20分を費やしてしまいます。
協業
チーム全員が同じフォーマット規約を守っていれば、コードレビューは空白の議論ではなく、ロジックやアーキテクチャについての有意義な会話になります。フォーマットが統一されていると、マージコンフリクトも減少します。
デバッグ
インデントが適切な HTML ドキュメントは、階層構造を即座に明らかにします。レンダリングに問題が生じたとき、ネスト構造を視覚的にたどって原因を特定できます。圧縮されたり、フォーマットが乱れたマークアップは、こうした構造的な関係を隠してしまいます。
インデントスタイルと慣例
HTML におけるインデントの議論は、プログラミングコミュニティ全体の議論をそのまま反映しています——スペースかタブか、そして1レベルあたり何スペースにするか。
2スペース
2スペースのインデントは HTML で最も一般的な選択です。Google のスタイルガイド、Prettier のデフォルト設定、そしてほとんどのモダンフロントエンドフレームワークで採用されています。
<main>
<section>
<h1>Welcome</h1>
<p>This is a paragraph.</p>
</section>
</main>
利点は、階層構造がはっきりと見えるコンパクトなコードです。HTML では深いネストが頻繁に起こりますが、2スペースなら行が右端に寄りすぎることを防げます。
4スペース
4スペースのインデントは、ネストレベル間により大きな視覚的間隔を提供し、階層構造をさらに際立たせます。
<main>
<section>
<h1>Welcome</h1>
<p>This is a paragraph.</p>
</section>
</main>
ネストが浅い HTML テンプレートでこの方式を好むチームもあります。ただし、多層にわたるネストを持つ複雑なレイアウトでは、コードが画面の端まで押し出されてしまう可能性があります。
タブ
タブを使えば、各開発者がエディタで好みの表示幅を設定できます。あるタブが一方の開発者には2スペースとして、別の開発者には4スペースとして表示されても、実際のファイル内容は変わりません。
ひとつ選んで一貫性を保つ
どれを選ぶかよりも、一貫性のほうがはるかに重要です。エディタを設定し、Prettier のようなフォーマッタをセットアップし、pre-commit フックで強制しましょう。インデントスタイルの議論は、ルールを設定するときに一度だけ行うべきものであり、プルリクエストのたびに繰り返すものではありません。
HTML5 セマンティック要素
セマンティック要素は、ブラウザと支援技術の両方に意味を伝えます。汎用的な div や span を、コンテンツの役割を説明する専用のタグに置き換えるものです。
ドキュメント構造要素
<body>
<header>
<nav>
<a href="/">Home</a>
<a href="https://example.com/about">About</a>
</nav>
</header>
<main>
<article>
<h1>Article Title</h1>
<p>Article content goes here.</p>
<section>
<h2>Subsection</h2>
<p>More detailed content.</p>
</section>
</article>
<aside>
<h2>Related Links</h2>
<ul>
<li><a href="https://example.com/related">Related Article</a></li>
</ul>
</aside>
</main>
<footer>
<p>© 2026 Example Inc.</p>
</footer>
</body>
各要素の使い分け
<header>— 導入的なコンテンツやナビゲーションリンク。ページレベルだけでなく、<article>や<section>の内部にも配置できます。<nav>— 主要なナビゲーションブロック。すべてのリンクグループに使うのではなく、メインナビゲーションにのみ使用します。<main>— ページの主要コンテンツ。1ページにつき1つだけで、<article>、<aside>、<header>、<footer>、<nav>の内部にネストしてはいけません。<article>— それ単体で意味をなす自己完結型のコンテンツ:ブログ記事、ニュース、フォーラムの投稿、商品カードなど。<section>— テーマごとにまとめられたコンテンツのグループで、通常は見出しを伴います。コンテンツが論理的なセクションを表す場合、divの代わりに使用します。<aside>— 周囲のコンテンツと間接的に関連する内容:サイドバー、引用、関連リンクなど。<footer>— 最も近いセクショニング祖先のフッター情報。<header>と同様に、記事やセクションの内部にも配置できます。
div とセマンティック要素の違い
div にはセマンティックな意味がありません。スタイリングとレイアウトのための汎用コンテナにすぎません。div を使おうとするとき、「このコンテンツをより適切に記述するセマンティック要素があるか?」と自問してください。答えがイエスなら、セマンティック要素を使いましょう。
<!-- Avoid this -->
<div class="navigation">
<div class="nav-links">
<a href="/">Home</a>
</div>
</div>
<!-- Prefer this -->
<nav>
<a href="/">Home</a>
</nav>
アクセシビリティパターン
アクセシブルな HTML は別個の関心事ではありません——それは上手に書かれた HTML そのものです。アクセシビリティの改善のほとんどは、マークアップをよりクリーンで意味のあるものにしてくれます。
見出しの階層構造
見出しは論理的な順序に従わなければなりません。スタイリングのためにレベルをスキップしてはいけません——見た目のサイズ調整には CSS を使いましょう。
<!-- Correct hierarchy -->
<h1>Page Title</h1>
<h2>Major Section</h2>
<h3>Subsection</h3>
<h3>Another Subsection</h3>
<h2>Another Major Section</h2>
<!-- Incorrect — skips h2 -->
<h1>Page Title</h1>
<h3>This skips a level</h3>
画像の代替テキスト
すべての <img> 要素には alt 属性が必要です。説明的な代替テキストは、スクリーンリーダーのユーザーがコンテンツを理解する助けになります。装飾的な画像には、画像が情報を伝えないことを示すために空の alt="" を使用します。
<!-- Informative image -->
<img src="chart.png" alt="Bar chart showing revenue growth from Q1 to Q4 2025">
<!-- Decorative image -->
<img src="decorative-border.png" alt="">
フォームラベル
すべてのフォーム入力にはラベルが関連付けられていなければなりません。ラベルの for 属性は、入力要素の id と一致させます。
<label for="email">Email Address</label>
<input type="email" id="email" name="email" required>
プレースホルダーテキストをラベルの代わりに使うのは避けましょう。プレースホルダーはユーザーが入力を始めると消えてしまい、そのフィールドに何を入力すべきかという文脈が失われます。
ARIA ラベル
ネイティブ HTML のセマンティクスだけでは不十分な場合に ARIA 属性を使用します。ただし、ARIA の第一原則は——必要なセマンティクスをすでに備えたネイティブ HTML 要素があるなら、そちらを使うことです。
<!-- ARIA for custom components -->
<button aria-label="Close dialog" aria-expanded="false">
<svg><!-- icon --></svg>
</button>
<!-- Better: use native semantics when possible -->
<button type="button">Close</button>
キーボードナビゲーション
インタラクティブな要素はキーボードでアクセスできなければなりません。<button>、<a>、<input> などのネイティブ HTML 要素は、デフォルトでキーボードアクセスが可能です。div や span をインタラクティブ要素として使う場合(一般的には避けるべきですが)、tabindex="0" とキーボードイベントハンドラを追加してください。
属性の並び順の慣例
一貫した属性の並び順により、HTML がスキャンしやすくなります。厳密な標準はありませんが、広く採用されている慣例では、重要度と機能に基づいて属性を並べます:
<input
type="email"
id="user-email"
name="email"
class="form-input"
placeholder="you@example.com"
required
aria-describedby="email-help"
data-validate="email"
>
推奨される順序:
type— 要素や入力の種類id— 一意の識別子name— フォーム送信名class— スタイリングのフックsrc、href、for— リソース参照value、placeholder— コンテンツ属性required、disabled、checked— ブーリアン状態aria-*— アクセシビリティ属性data-*— カスタムデータ属性
これは厳格なルールではありませんが、プロジェクト内での一貫性が重要です。選択した順序をリンターで強制するように設定しましょう。
自己閉じタグ、void 要素、ブーリアン属性
void 要素
一部の HTML 要素はコンテンツを持つことができず、閉じタグも不要です。これらは void 要素と呼ばれます:
<br>
<hr>
<img src="photo.jpg" alt="A sunset over the ocean">
<input type="text" name="search">
<meta charset="utf-8">
<link rel="stylesheet" href="styles.css">
HTML5 では、void 要素を末尾のスラッシュで自己閉じする必要はありません(<br />)。スラッシュは任意であり、純粋にスタイル上の好みです。ただし、プロジェクトが JSX や XHTML を使用している場合、自己閉じ構文は必須です。
ブーリアン属性
ブーリアン属性は存在するかしないかのどちらかであり、値を必要としません。属性の存在は true を意味し、不在は false を意味します。
<!-- These are equivalent -->
<input type="text" required>
<input type="text" required="required">
<input type="text" required="">
<!-- Preferred: just the attribute name -->
<input type="text" required>
<button disabled>Submit</button>
<video autoplay muted></video>
よくある HTML フォーマットの間違い
1. 一貫性のないインデント
タブとスペースを混在させたり、レベルごとにスペース数が異なったりすると、視覚的な混乱を招きます。フォーマッタを使ってこの問題を防ぎましょう。
2. div のスープ
セマンティック要素のほうが意味をより的確に伝えられるのに、すべてを div 要素で囲んでしまうこと。これはアクセシビリティ、SEO、コードの可読性すべてに悪影響を及ぼします。
<!-- Div soup -->
<div class="header">
<div class="nav">
<div class="nav-item"><a href="/">Home</a></div>
</div>
</div>
<!-- Clean semantic markup -->
<header>
<nav>
<a href="/">Home</a>
</nav>
</header>
3. alt 属性の欠落
画像の alt 属性を省略することはアクセシビリティ違反であり、すべての HTML バリデータで警告が出ます。
4. インラインスタイル
HTML の至るところに style 属性を散りばめると、関心の分離が崩れ、保守が困難になります。代わりに CSS クラスを使いましょう。
5. 深すぎるネスト構造
HTML が6層、7層にも深くネストされているなら、レイアウトを見直してください。深いネストは通常、より良いコンポーネントアーキテクチャで構造を簡素化できることを示しています。
6. ドキュメント言語の未指定
<html> 要素には必ず lang 属性を含めてください。スクリーンリーダーがこの属性を使用して、正しい発音ルールを選択します。
<html lang="en">
7. <!DOCTYPE html> 宣言の欠落
HTML ドキュメントは必ず doctype 宣言から始めてください。これがないと、ブラウザがクアークモードでページをレンダリングする可能性があり、一貫性のない動作を引き起こします。
自動整形とリンティングツール
手動のフォーマットはミスが起きやすく面倒です。自動化ツールを使えば、継続的な手間なしに一貫性を保てます。
Prettier
Prettier は Web 開発で最も人気のあるコードフォーマッタです。HTML、CSS、JavaScript、その他多くの言語に対応しています。一度設定すれば、インデント、属性の折り返し、行の長さを自動的に処理します。
{
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"htmlWhitespaceSensitivity": "css"
}
Prettier を pre-commit フックとして実行するか、エディタで保存時に実行するように設定すれば、フォーマットは完全に自動化されます。
HTMLHint
HTMLHint は HTML に特化した静的解析ツールです。フォーマッタでは検出できない問題——alt 属性の欠落、重複した ID、非推奨の要素などを検出します。
{
"tagname-lowercase": true,
"attr-lowercase": true,
"attr-value-double-quotes": true,
"tag-pair": true,
"id-unique": true,
"alt-require": true
}
エディタ統合
ほとんどのモダンエディタ——VS Code、WebStorm、Sublime Text——には、組み込みまたはプラグインベースの HTML フォーマット機能があります。保存時の自動フォーマットを有効にすれば、意識せずとも HTML をきれいに保てます。
本番環境向けの圧縮
開発時の HTML は美しくフォーマットされているべきですが、本番環境の HTML はファイルサイズを削減するために圧縮するのが効果的です。当サイトの Code Minifier を使えば、空白の除去、コメントの削除、デプロイ向けの HTML 圧縮が可能です。ポイントは、ソースコードはフォーマットされた状態を維持し、出力のみを圧縮することです。
ツールとリソース
適切なツールがあれば、良いフォーマット習慣を維持しやすくなります:
- Code Minifier — ソースコードをきれいに保ちながら、本番環境向けに HTML、CSS、JavaScript を圧縮
- Markdown Previewer — 多くの場合 HTML 出力を生成する Markdown コンテンツのプレビューとフォーマット
よくある質問
HTML のインデントには2スペースと4スペースのどちらを使うべきですか?
現代の Web 開発では2スペースが最も一般的な慣例で、Prettier のデフォルト値でもあります。4スペースはネストの浅いシンプルなドキュメントに適しています。最も重要なのは、ひとつを選んでフォーマッタで強制することです。
セマンティック HTML と通常の HTML の違いは何ですか?
セマンティック HTML は、汎用コンテナ(<div>、<span>)ではなく、コンテンツの意味を記述する要素(<article>、<nav>、<header>)を使用します。セマンティックマークアップはアクセシビリティ、SEO、コードの可読性を向上させます。
セマンティック HTML を使っていれば ARIA 属性は不要ですか?
ほとんどの場合、セマンティック HTML は十分なアクセシビリティ情報を提供します。ARIA は、ネイティブ HTML に相当するものがないカスタムインタラクティブコンポーネント(カスタムドロップダウンメニューやタブパネルなど)を構築する場合に必要です。
チーム全体で HTML のフォーマットを統一するにはどうすればよいですか?
共有設定ファイル付きの Prettier と、リンティング用の HTMLHint 設定を使用し、Husky と lint-staged などのツールを使って両方を pre-commit フックとして実行してください。
void 要素を <br /> のように自己閉じしても問題ないですか?
HTML5 では、void 要素の末尾スラッシュは任意です。<br> も <br /> もどちらも有効です。JSX(React)では自己閉じ構文が必須です。プロジェクトやフレームワークが期待する慣例に従ってください。
関連リソース
- Code Minification Guide — 本番環境向けに HTML、CSS、JavaScript を圧縮する方法を学ぶ
- Markdown Syntax Guide — ドキュメントやコンテンツのための Markdown フォーマットをマスターする
- HTML Entities Encoding Guide — HTML で特殊文字を正しく扱う方法
🛠️ 今すぐ試す: Code Minifier — フォーマット済みの HTML を本番環境向けに圧縮。100% 無料、すべての処理はブラウザ内で完結。データのアップロードは一切ありません。