104人がいいねしました
更新日
【一覧表あり】HTML5でのタグの入れ子のルールを徹底まとめ
html5のタグの入れ子のルールの保存版まとめです。「〇〇タグに〇〇タグって入れてもいいんだっけ?」という悩みを全部解決します!すべてw3cのコンテンツモデルの仕様に基づいた内容になっていますので安心して読んでくださいね。
入れ子のルールはコンテンツモデルで決まる
html5からはブロック要素とインライン要素という概念が廃止されました。そのため以前まではインライン要素の中にブロック要素を入れてはいけないというルールがあったと思いますがそれは完全に無視してください。
とはいえcssでレイアウトを行う上では従来と変わらず
- display : blockで親要素の幅に合わせる
- display : inlineでその要素自体が持つ幅
という指定の仕方はできます。
ただhtmlでタグの入れ子を考える上でブロック要素とインライン要素という概念がなくなっただけです。
じゃあなにが追加されたかというと、w3cは代わりにコンテンツモデルとカテゴリーという概念を新しく追加しました。
コンテンツモデル・カテゴリーと向き合おう
コンテンツモデルとカテゴリーは一見難しそうな印象だけど、この概念を理解することで「このタグ入れてもいいんだっけ?」となった時に自分で簡単に調べることができるようになるんだ。
最初は面倒に感じるかもしれないけど、まずはゆっくり以下の解説を見てみよう!
カテゴリーとは?
※よく使うタグだけを抜粋
html5ではすべてのタグが
- フローコンテンツ
- セクショニングコンテンツ
- ヘッディングコンテンツ
- フレージングコンテンツ
- エンベデッドコンテンツ
- インタラクティブコンテンツ
この6種のカテゴリーのいずれかに属しています。
それぞれのカテゴリーが重なっているのは複数のカテゴリーに所属している要素もあるからです。
例えば「h1はヘッディングコンテンツかつフローコンテンツである」といえます。
「aはフレージングコンテンツであり、インタラクティブコンテンツでもあり、フローコンテンツでもある」といえます。
コンテンツモデルとは?
コンテンツモデルとは「その要素にはどのカテゴリーのコンテンツを入れていいか」を決めているルールです。
タグの入れ子のルールはこのコンテンツモデルによって決まっています。
例をあげてみましょう。
コンテンツモデルに反している例
<p>
<h1>ヘッドライン</h1>
</p>
<p>
<div>pタグにdivは入れられない</div>
</p>
例えばp
が含んでいい要素はフレージングコンテンツのカテゴリーのみです。
h1
もdiv
もフレージングコンテンツのカテゴリーに属していませんよね。
コンテンツモデルに沿っている例
<p>
<img src="img.png">
</p>
<p>
<a>リンク</a>
</p>
a
とimg
は両方フレージングコンテンツのカテゴリーに属していますよね。なので問題ナシです。
カテゴリーとコンテンツモデルのまとめ
- html5の要素はすべて6種のカテゴリーのいずれかに属している
- 要素ごとにどのカテゴリーの要素を含んでいいか決まっている
- それらのルールをコンテンツモデルと呼ぶ
要素ごとのタグの入れ子ルールまとめ
ここまででコンテンツモデルとカテゴリーについてなんとなくでも理解していればOKです。
ここからはルールに基づいたタグの入れ子ルールをよく使うタグを厳選して一覧で紹介していきます!
divタグ:構造・レイアウト
divタグはフローコンテンツの要素を含むことができるのでほぼすべての要素を入れ子に含むことができます。
div
自身がフローコンテンツでもあるのでdivの中にdivももちろん問題ありません!
divに入れられるタグ
a / article / aside / audio / b / blockquote / br / button / canvas / cite / code / div / dl / em / figure / footer / form / h1 / h2 / h3 / h4 / h5 / h6 / header / hgroup / hr / i / iframe / img / input / label / main / nav / ol / p / picture / pre / script / section / select / small / span / strong / svg / table / template / textarea / time / ul / video…などなど
spanタグ:構造・レイアウト
spanタグはフレージングコンテンツを子要素として入れ子に含むことができます。
- spanの中にspan
- spanの中にbr
- spanの中にimg
- spanの中にa
全てOKです!
spanに入れられるタグ
a / audio / b / br / button / canvas / cite / code / data / em / i / iframe / img / input / label /picture / select / small / span / strong / svg / textarea / time / video /…などなど
h1〜h6タグ:見出し
h1〜h6タグはフレージングコンテンツを子要素として入れ子に含むことができます。
ただ、フレージングコンテンツを入れることができるといっても、hの中にimgやiframeとかは単純に論理構造上おかしいのであくまで論理的に正しい形で使用しましょう。
hタグに入れられるタグ
a / audio / b / br / button / canvas / cite / code / data / em / i / iframe / img / input / label /picture / select / small / span / strong / svg / textarea / time / video /…などなど
p / preタグ:段落
pタグもhタグ同様、フレージングコンテンツを子要素として入れ子に含むことができます。
pタグに入れられるタグ
a / audio / b / br / button / canvas / cite / code / data / em / i / iframe / img / input / label /picture / select / small / span / strong / svg / textarea / time / video /…などなど
strong / emタグ:強調
strognタグはpタグ同様、フレージングコンテンツを子要素として入れ子に含むことができます。
strong/emタグに入れられるタグ
a / audio / b / br / button / canvas / cite / code / data / em / i / iframe / img / input / label /picture / select / small / span / strong / svg / textarea / time / video /…などなど
ul / olタグ:リスト定義
ulもolも基本は直下の子要素にはliしか入れていけません。template、scriptといったタグは例外として入れることはできますが、よっぽどのことがないと使用する機会はないでしょう。
ul/olタグに入れられるタグ
li / template / script
liタグ:リスト定義(子要素)
liはdiv同様フローコンテンツを入れ子のタグとして含めることができる万能タグです。
liタグに入れられるタグ
a / article / aside / audio / b / blockquote / br / button / canvas / cite / code / div / dl / em / figure / footer / form / h1 / h2 / h3 / h4 / h5 / h6 / header / hgroup / hr / i / iframe / img / input / label / main / nav / ol / p / picture / pre / script / section / select / small / span / strong / svg / table / template / textarea / time / ul / video
ulの中にulを入れたい場合は?
<ul>
<li>親メニュー1</li>
<li>親メニュー2
<ul>
<li>子メニュー1</li>
<li>子メニュー2</li>
</ul> <!-- liで囲って中にul -->
</li>
<li>親メニュー3</li>
<ul>
ナビゲーションに階層つきメニューをつけたい場合があります。そんな時にulの直下にulを入れることはできないのでli
の中にul
を入れる必要があります。
ulの中にdivを入れたい場合は?
<ul>
<li>
<div>
<p>スライドタイトル01</p>
<img src="img.png">
</div>
</li>
<li>
<div>
<p>スライドタイトル02</p>
<img src="img.png">
</div>
</li>
</ul>
スライダーなどをつくるときに、ul
の中にdiv
を入れたいということがあります。
そのときはul
の中にul
を入れる時と同様でli
でdiv
を囲うことで入れ子のタグとして入れることができます。
tableタグ:表の定義
表を定義するtable
ですが、直下に置いてよいのは
tableタグに入れられるタグ
tbody / thead / tfoot /caption / colgroup
だけです。この中でもtbody / thead / tfoot に関しては省略可ですので、よく使うタグであればtr
のみがtable
の直下に置くことのできる要素となるでしょう。
th / tdタグ:見出しセル/データセル
th
とtd
はフローコンテンツを含めることができます。
trタグに入れられるタグ
a / article / aside / audio / b / blockquote / br / button / canvas / cite / code / div / dl / em / figure / footer / form / h1 / h2 / h3 / h4 / h5 / h6 / header / hgroup / hr / i / iframe / img / input / label / main / nav / ol / p / picture / pre / script / section / select / small / span / strong / svg / table / template / textarea / time / ul / video…などなど
tableの中にdivやtableの中にulを含みたい場合はthもしくはtd
の入れ子タグにしましょう。
dlタグ:定義リスト
dlはtableと似ていますね。データの枠組みであるdlの直下には
dlタグに入れられるタグ
dt / dd / div
を入れることができます。
dt / ddタグ:定義リスト(子要素)
こちらもtable
のth / td
と同様に、フローコンテンツを入れることができます。dlの中にdlを入れる時はdt
またはdd
の中に入れるようにしましょう。
dtタグに入れられるタグ
a / audio / b / blockquote / br / button / canvas / cite / code / div / dl / em / figure / form / hgroup / hr / i / iframe / img / input / label / ol / p / picture / pre / script / select / small / span / strong / svg / table / template / textarea / time / ul / video…などなど
dt
はフローコンテンツを入れることができますが、header
、footer
、セクショニング・コンテンツ、ヘッディング・コンテンツを入れることはできないので注意してください。
ddタグに入れられるタグ
a / article / aside / audio / b / blockquote / br / button / canvas / cite / code / div / dl / em / figure / footer / form / h1 / h2 / h3 / h4 / h5 / h6 / header / hgroup / hr / i / iframe / img / input / label / main / nav / ol / p / picture / pre / script / section / select / small / span / strong / svg / table / template / textarea / time / ul / video…などなど
aタグ:リンク
a
はちょっと特殊なコンテンツモデルを持っています。transparent(トランスペアレント)といって親要素のタグのコンテンツモデルを引き継ぎます(透過的と呼ぶ)
以前まではa
でdiv
やhx
といったタグを囲うことは禁止されていましたが、現在は親要素によってはaタグの中にdivやhタグを入れることが良しとされています。
実際にどういったケースがあるか見てみましょう。
aタグでhやdivを入れ子にできない場合
<!-- 親要素がpなのでフレージングコンテンツ -->
<p>
<a href="http://smpl.com">
<h3>記事タイトル</h2>
</a>
</p>
aの親要素に注目してください。
a
の親要素であるp
はフレージングコンテンツしか含むことができません。先ほど説明した通りa
は親要素のコンテンツモデルを引き継ぐので、この場合aもフレージングコンテンツしか入れ子に含むことができないということになります。
aタグでhやdivを入れ子にできる場合
<!-- 親要素がdivなのでフローコンテンツ -->
<div>
<a href="http://smpl.com">
<h3>記事タイトル</h2>
</a>
</div>
aの親要素はdivはですね。
この場合a
はdiv
のフローコンテンツを入れ子にできるというコンテンツモデルを引き継ぐので、ほとんどのタグを入れ子にすることができます。
このように親要素タグのコンテンツモデルがなにかによって、aタグの中にpタグ、aタグの中にaタグ、aタグの中にdivを入れることが可能になるわけです。
html5の入れ子タグ早見表
div | a | br | div | dl | h1〜h6 | img | ul | ol | p | span | table |
---|---|---|---|---|---|---|---|---|---|---|---|
span | a | br | em | img | input | label | span | strong | svg | ||
a | 親要素のコンテンツモデルを継承 | ||||||||||
h1〜h6 | a | br | em | img | input | label | span | strong | svg | ||
p | a | br | em | img | input | label | span | strong | svg | ||
ul/ol | liのみ(例外:template,script) | ||||||||||
li | a | br | div | dl | h1〜h6 | img | ul | ol | p | span | table |
table | tbody | thead | tfoot | caption | colgroup | ||||||
th/th | a | br | div | dl | h1〜h6 | img | ul | ol | p | span | table |
dl | dt | dd | div | ||||||||
dt/dd | a | br | div | dl | h1〜h6 | img | ul | ol | p | span | table |
w3cの仕様書でコンテンツモデルを確認する方法
HTMLにはバージョンがあり、バージョンごとに「仕様(htmlのルール)」がちょくちょく変更されていきます。
仕様書の見方を理解できれば解説された記事を見なくてもダイレクトに最新の情報を追うことができるようになります。ということで2019/02時点で最新のHTML5.2の仕様書の「コンテンツモデル」の確認方法を見ていきましょう。
ステップ2
タグをクリックし、確認する
タグの中から<span>
をクリックしてみると<span>
の細かな仕様が表示されます。
その中に
- Categories = spanのカテゴリー
- Content model = spanの中に入れられるタグのカテゴリー
が表示されています。
これでspanには「フレージングコンテンツ」を入れられることがわかりますよね。
ステップ3
タグのコンテンツを確認する
そこで先ほどのカテゴリー一覧に戻ると「フレージングコンテンツ」のタグ一覧があるので、そこに書かれている「aタグ」や「imgタグ」が入れることのできるタグだと判断することができます。
仕様書を読めるようになれば自信を持ってタグを書ける!
仕様書を読めるようになれば常に正しい情報を追えるようになるから自信を持ってタグを書くことができるようになるよね!どこを読めばいいのかを絞り込めれば英語が読めなくてもある程度理解することができるはずだからぜひチャレンジしてみてね!