🐷

hr要素にbefore, after疑似要素を使ってはならないのか?

2021/02/24に公開

段落間を意味的に分割するための要素にhr要素がある。HTML文書で意外と使う機会の多い要素で、CSSにより装飾されたオシャレなhr要素が様々なサイトに使われている。その中にはhr要素に対する装飾を行う過程でbefore, after疑似要素を使っているものも少なくない。

しかし、こういった手法に対して「仕様上は無効な記述ではないか」というような批判も根強く存在する。そこで本記事では、hr要素においてbefore, after疑似要素を使用することの是非について、当該手法への批判的意見のうち、特によく見られる2つを示しながら検討していく。

hr要素はvoid elementだからbefore, after疑似要素を使ってはいけない」

Void elementは終了タグが存在せず、常に開始タグのみからなる要素を指す。Void elementでbefore, after疑似要素を使ってはならないといわれる根拠には、コンテンツモデルが関係している。Void elementはその性質から、ほとんど(すべて?)のコンテンツモデルがnothingとされている。そしてnothingコンテンツモデルは要素ノードおよびテキストノードをコンテンツとして含んではならない。つまり、事実上いかなるコンテンツも挿入することはできない。このため疑似要素も含んではならないという論理だ。

しかし私はこれを誤りだと考えている。なぜなら、コンテンツモデルはbefore, after疑似要素により生成されたコンテンツ(以下では生成されたコンテンツと呼ぶ)が考慮されていないからだ。そもそも、コンテンツモデルの指すコンテンツとは、とある要素におけるDOMでの子である。「生成されたコンテンツ」はDOM上の概念ではなく、DOMツリーに対して影響を与えない。よって、before, after疑似要素をvoid elementに許可するかどうかという議論のなかで、コンテンツモデルを根拠とするのは不適当といえる。

「同じくvoid elementのimg要素ではbefore,after疑似要素が動作しないから、hr要素でも使ってはいけない」

まず、before,after疑似要素の使用の可不可に、void elementかどうかは関係がないことは前述した通りだ。それでは次に、なぜ同じvoid elementであるimg要素ではbefore,after疑似要素が動作しないのかを考えていく。これはimg要素が置換要素であることが関係している。

置換要素とは、その要素のコンテンツがCSSフォーマットモデルの範囲外となる要素だ。わかりやすい例でいえば、画像や他のページなどのコンテンツが挙げられる。このことからわかるように、置換要素はコンテンツを外部のコンテンツによって置き換える要素といえる。さらに言い換えれば、もともとそこにあったコンテンツは、外部コンテンツに置き換えられる。

つまり、もともとは「生成されたコンテンツ」があったとしても、それが外部リソースにより置き換えられているということだ。これがimg要素ではbefore, after疑似要素が動作しない理由だ。

結論

ここまでで、hr要素にbefore, after疑似要素を使うことに対する主要な批判を2つ挙げ、それらに対する反論を試みた。この記事を通して私が主張したかったことは、HTMLにおけるコンテンツとCSSにおけるコンテンツは混同してはならない、という点だ。これは、レンダリングツリー上に存在するものすべてがDOMツリーのものではないということを表している。「生成されたコンテンツ」はレンダリングツリー上では見えているが、DOMツリー上には存在しないのだ。

最後に、hr要素にbefore, after疑似要素を使うことの是非に関して私見を述べておく。私はこの手法を利用することで得られる装飾上の利益から、(ブラウザでの動作確認が行えていれば)使っても問題はないと考えている。また、(私の知る限りでは)void elementでの「生成されたコンテンツ」の扱いに関して、いずれの仕様でも言及されていないため、基本的には他の要素と同様にbefore, after 要素を使っても問題は生じないだろう。ただし、今後どこかで明示され動作が変化する可能性もあるので、常に動向を探っておく必要があるだろう。

そんなわけで、hr要素を主題としたにもかかわらず明確な答えを提示できておらず、何とも線引きの出来ていない曖昧な結論となってしまったが、この記事がhr要素へbefore, after疑似要素を使おうとしている誰かの参考になればと思う。

参考

  1. HTML Standard
  2. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification
  3. CSS Display Module Level 3
  4. CSS Generated Content Module Level 3

Discussion