JINMUSOFTWARE

CSSの無名ボックスについて

anonymouse-box

無名ボックスに気づく

例えばですが、div要素直下に、テキストとインライン要素を置くと、無名ボックスとインライン要素に分かれます。sample / div要素直下のテキストとspan要素の例

<div class="div1">
XXXXX<span>this is a span.</span>XXXXX
</div>

直下のテキストは生成された無名ボックスに包含されるようです。

また、無名ボックスはHTML要素が無いことを示します。

JavaScriptで無名ボックスのテキストを取得してみる

さて、無名ボックスはHTML要素でないようなので、それを確認してみます。

先ほどの例より、無名ボックスのテキストを取得する場合を考えます。

div.children ➡ HTMLCollection [span]は、span要素のみ抽出されます。

div.childNodes ➡ NodeList(3) [text, span, text]は、[text, span, text] と抽出されます。

この生っぽいテキストは、要素として認識されませんが、nodeの1つとして認識されるようですね。

無名ボックスにはCSSがあたらない

この無名ボックスにCSSスタイルを設定することは可能なのでしょうか?

全称セレクター(*)で確認してみます。

「div > *」を使用したとき、div配下にある無名ボックスのテキストを選択することはできませんでした。

テキストと同レベルにあるspan要素のみ選択されています。

以下のテストは、textノードの背景色は変わらず、span要素やem要素だけ背景色だけが変わっています。

<div class="div1">XXXX<span>span</span>XXXX</div>
<div class="div1">XXXX<em>em</em>XXXX</div>
.div1 > * {
    background-color: cornflowerblue;
}
XXXXXspanXXXXX
XXXXemXXXX

無名ボックスでも基本スタイルは親より継承されます。スタイルが無いわけではありません。

擬似要素before, after の領域が「div > *」の対象になるのか?

対象外でした。擬似要素も、HTML要素ではないようです。

XXXXXspanXXXXX

擬似要素はElement?Node?

擬似要素は、Nodeとしても抽出されないようです。

ブラウザのデベロッパーツールで対象要素を確認すると、親要素配下に「::before」「::after」と表示されていますが、ElementでもNodeでもないようです。

ブラウザのデベロッパーツールで確認すると、div要素の子要素に見えてしまうんですけどね。

擬似要素のツリー構造
擬似要素のツリー構造

JavaScriptで擬似要素の内容を取得する方法

では、JavaScriptから擬似要素の内容を取得するにはどのようにすれば良いでしょうか?

プロパティの「children」「childNodes 」では擬似要素を拾えません。

残念ながらJavaScriptから、擬似要素を取得する便利なメソッドは無いようです。

しかし、描画後のスタイルから取得する方法がありました。

getComputedStyle(document.getElementById("div3"), "::before").content;

JavaScriptから擬似要素を設定したり削除できるメソッドはないので、CSSクラスを付けたり外したりして制御します。

flexで表示すると

参考にflex-boxレイアウトでどのように表示されるか確認します。

以下は適当なsampleです。div直下に生テキストとspanがあります。親のdivとspan.3は擬似要素があります。

<div>
  XXX<span>span.1</span>XXX<span>span.2</span><span>span.3</span>XXX
</div>
XXXspan.1XXXspan.2span.3XXX

先ほどに全称セレクタが効いているのでdiv要素直下のspan要素の背景色がさわやかブルーに色づいています。

さて、この親div要素にdisplay: flex;flex-direction: column;を設定しています。

XXXspan.1XXXspan.2span.3XXX

上記のように縦に並びます。擬似要素、生テキスト、span要素は区別されるようですね。

参考文献・資料

視覚整形モデル / Visual formatting model

無名ボックスについて / Anonymous boxes

Element.children

Node: childNodes プロパティ

参考記事

CSSレイアウト float編

Box-Sizingを理解してボーダー幅のはみ出しを抑える方法

CSSのContainを利用して要素の封じ込めスタイルを理解する

擬似要素のbeforeとafterで画像を表示する方法【CSS】


個人の感想memo
  • テキストとhtml要素が同レベルで並ぶと生テキストは無名ボックスに包含されるようだ。
  • このページではテキストとspanを並べたが、テキストと同レベルにあるのはp要素でも良い。
  • 無名ボックスはCSSが適応されない。
  • 無名ボックスはHTML要素ではない。
  • 無名ボックスはスタイルがないわけではなく親からスタイルを継承している。
  • emタグなどで区切られると、インライン無名ボックスが生成されます。
  • 必要なときに無名ボックスが生成される感じかな。
  • 「.div1 > *」、が効かないのはびっくりした。
  • その親要素のcontentのような子要素のような感じがする。そもそも親要素のcontentですよね。
  • まぁでもそんなにトラブルになることはないかと思っている。