😵

`<p>` タグの中にブロック要素を入れてはいけない

2021/11/30に公開

結論

<p> タグの中にブロック要素を入れない方がいい

どういうこと?

MDN の <p> タグ要素のページには以下の説明があります。

段落はブロックレベル要素であり、特徴的なのは </p> で閉じる前に他のブロックレベル要素が見つかった場合は自動的に閉じることです。下記の「タグの省略」をご覧ください。

開始タグは必須。後続する要素が <address>, <article>, <aside>, <blockquote>, <div>, <dl>, <fieldset>, <footer>, <form>, <h1>, <h2>, <h3>, <h4>, <h5>, <h6>, <header>, <hr>, <menu>, <nav>, <ol>, <pre>, <section>, <table>, <ul> または別の <p> 要素のいずれかである、または親要素内で他のコンテンツがなく親要素が <a> 要素ではない場合は終了タグを省略することが可能。

つまり、 <p> タグの内部で <div> などを使うと、その時点で <p>タグは閉じられたことになる ということです。

実際に見てみる

以下のように HTML を書き、<p> タグの周りにボーダーを描画するスタイルを与えます。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
  </head>
  <body>
    <p>これは段落です!!</p>
    <p>
      pタグの中に
      <div>div</div>
      はだめ
    </p>
  </body>
  <style>
    p {
      margin: 10px 0;
      padding: 5px;
      border: 1px solid #999;
    }
  </style>
</html>

これのレンダリング結果はこんな感じになります。
スクリーンショット

ちなみにインスペクタで見ると <body> 以下の HTML 構造はこのようになっています。

<p>これは段落です!!</p>
<p>pタグの中に</p>
<div>div</div>
はだめ
<p></p>

MDN の記載通りに、 <div> 要素の前で <p> が閉じられていますね。

実際の動作はこちらで確認できます。

でも今まで特に問題起きたことなかった気がする...

今まで HTML 書いてきてその問題発生した事ない気がする、という方もいらっしゃると思います。どうやら Vue や React などのフレームワークだと <p> タグの中に何を入れようと問題は起きないようです。

仮想DOMの取り扱い周りでこの辺りをよしなにやってくれてたりするのでしょうか...?ご存知の方がいればコメントにお願いします🤲

ただ、 動作はしても Prettier 先生には怒られるようです。

とにかく

正しい HTML を書こう。

Discussion