HTML整形
HTMLフォーマッターは、マークアップをブラウザ内で再インデントし、最小化します。HTMLはXMLではありません。それだと思って整形すると、ドキュメントは4つの具体的なパターンで壊れます——void要素、rawテキスト要素、省略可能な閉じタグ、インライン要素間の意味のある空白——このツールはそのそれぞれに明示的に対応しています。
HTML整形はどう動きますか?
ほとんどのHTMLフォーマッターは、名前を変えただけのXMLフォーマッターです。そして両者の4つの違いは、いずれも実際のバグを生んできました。
void要素はスコープを開かない
<br>、<img>、<input>、<hr>とそのほか10個の要素には閉じタグがありません——省略できるのではなく、そもそも存在しません。開始タグごとにインデントを深めるフォーマッターは、最初の<img>以降をすべて1レベル右へ押しやり、二度と戻りません。画像が20個あるページは、画面の外までインデントされることになります。
scriptとstyleの中身はマークアップではなくテキスト
<script>の中に現れた<は、単なる「より小さい」記号です。タグとして解析しようとすれば、if (a < b)がドキュメントをめちゃくちゃにします。上のサンプルにまさにこの式が入っているのはそのためです。<script>、<style>、<textarea>、<title>の内容は、対応する閉じタグまでひとまとまりで取り込まれます。
インライン要素間の空白は表示に影響する
<b>a</b> <i>b</i>は「a b」と表示されます。間の空白がなければ「ab」です。すべての要素を独立した行に置くフォーマッターは、ドキュメント内のあらゆるテキストの流れに空白を1個ずつ挿入したのと同じことになります——典型的な症状は、句点の前やリンクの後にできる意図しない隙間です。そこでこのツールは、インライン要素をバッファされた連なりの中に保持し、行を始めるのはブロック要素だけにしています。同じ規則により、<pre>の内容は決して再インデントされません。ここでは空白こそがレイアウトだからです。
いくつかの要素では閉じタグを省略できる
</li>、</p>、</td>などは省略でき、手書きのHTMLでは実際に省略されていることもよくあります。厳格なタグスタックを持つフォーマッターは、ドキュメントを拒否するか、インデントを崩すかのどちらかになります。このツールでは、スタックの先頭と一致しない閉じタグに出会うと、閉じが省略可能な要素を巻き戻して通過します。
解析が報告する内容
alt属性のない<img>は警告の対象になります。スクリーンリーダーは代わりにファイル名を読み上げることになり、それは沈黙よりひどい結果です。装飾画像には属性を省くのではなくalt=""を付けるべきなのは、このためです。閉じられていない要素は名前を特定して報告します。ブラウザは後から復旧しますが、どこで閉じるかを決めるのはブラウザであってあなたではなく、両者はしばしば食い違います。
入力
<div><br><p>text</p></div>
整形結果
<div>
<br>
<p>
text
</p>
</div>HTML整形が対応するオプションとエッジケースは?
| パラメータ | 型 | デフォルト | 動作とエッジケース |
|---|---|---|---|
| インデント | スペース | 2 | ネストレベルごと。空要素はレベルを追加しません。 |
| 属性の折り返し | 個数 | 4 | 少なくともこれだけの属性を持つタブ、または100文字を超えるタブは、各属性を別の行に配置します。 |
| 生テキスト保持 | 真偽値 | on | preとtextareaのコンテンツはスペースがレンダリングされるため、決して変更されません。scriptとstyleの本体は再インデントされますが、これは安全です。 |
| void要素 | 14要素 | — | area base br col embed hr img input link meta param source track wbr。これらのいずれもスコープを開きません。 |
| 生テキスト要素 | script, style, textarea, title, pre | — | コンテンツはマークアップではなくテキストです。script内の<は小なり記号であり、それをタグとして解析すると文書が破損します。 |
| インライン要素 | フロー内に保持 | — | a, b, span, em, imgなどは、それらの間に改行があるとスペースとしてレンダリングされるため、元の行に留まります。 |
| 閉じタグ省略可 | 許容 | — | li, p, td, tr, optionなどは終了タブを省略できます。スタックは文書を拒否するのではなく、アンウインドされます。 |
| 属性の引用符 | 正規化 | 二重引用符 | 値に二重引用符が含まれる場合を除き、二重引用符が使用されます。ブール属性はそのままの形式を保持します。 |
| ミニファイ | 空白 | — | ホワイトスペースの連続を折りたたみますが、インライン要素が接続する箇所では単一のスペースを保持し、preコンテンツは保持します。条件付きコメントは古いIE向けのマークアップであるため、保持されます。 |
よくある質問
なぜインライン要素が独立した行に置かれないのですか?
そこに置くとページの表示が変わってしまうからです。<b>a</b> <i>b</i>は「a b」と表示されますが、タグ間に空白がなければ「ab」です。すべての要素を独立した行に分割するフォーマッターは、ドキュメント内のあらゆるテキストの流れに空白を挿入することになり、その症状が句点の前に現れる意図しない隙間です。インライン要素は、元の連なりのまま保持されます。
<pre>の中身がそのまま残されていたのはなぜですか?
<pre>では空白そのものが内容だからです。再インデントすれば読者が見るものが変わり、それは整形の真逆です。<textarea>も同じで、空白はフィールドの値そのものです。scriptとstyleの中身は、空白が表示に影響しないため再インデントされます。
HTMLに</li>という閉じタグがないのですが、壊れていますか?
いいえ。HTMLではli、p、td、tr、option、theadなどの閉じタグを省略でき、実際に省略している手書きのマークアップも多くあります。フォーマッターはスタックの先頭と一致しない閉じタグに出会うとスタックを巻き戻すため、ドキュメントは正しく整形されます。省略すべきかどうかはスタイルの問題です。パーサーが対処できるかどうかは、スタイルの問題ではありません。
alt属性の欠落について警告が出るのはなぜですか?
altのない<img>は、スクリーンリーダーにファイル名を読み上げさせるからです——「i-m-g underscore 4 0 2 1 dot p-n-g」——何も言わないよりひどい結果です。装飾画像への対処はalt=""です。支援技術に対して、この画像をスキップするよう明示的に伝えられます。属性がないことと空であることは意味が異なり、装飾として正しいのはそのうちの1つだけです。
HTMLを最小化すべきですか?
ビルドの一部としてだけです。しかもgzipやbrotliが絡むと、得られる縮小は想像より小さくなります。圧縮は反復する空白をすでに非常によく処理できるためです。最小化が本当に役立つのは、大きいメッセージを拒否するクライアントがあるメールテンプレートと、バイト数がクリティカルパスに乗るインラインのクリティカルCSSです。
マークアップはアップロードされますか?
いいえ。トークン化と整形はブラウザ内で実行されます。Networkパネルで確認できます。実際のアプリケーションのマークアップには、data属性や内部URL、実際の内容を含むインラインのJSONが含まれていることがよくあります。