記事本文
ul 要素の直下は li 要素だけ
まず、
XHTMLのDTDだと ul 要素の直下は li 要素だけでPCDATAは存在できないんじゃありませんでしたっけ。
という点について。
そもそも vantguarde - web:g の kota さんは、当該記事のサンプル DOM ツリーでは <!DOCTYPE html> という DOCTYPE を用いており、かつ終了タグの省略といった話もしているので、 XHTML の DTD が云々と言ってもそれは関係ない話なのでは、というツッコミもできますが、そんないじわるよりも先に
「あれ、こんなコメントがあるってことは、 HTML 4.01 だったら ul 要素の直下に #PCDATA を置けるようなことになっていたっけ」
と思ったので調べてみました。
- HTML 4.01 Transitional DTD
-
<!ELEMENT UL - - (LI)+ -- unordered list -->
- HTML 4.01 Strict DTD
-
<!ELEMENT UL - - (LI)+ -- unordered list -->
- XHTML 1.0 Transitional DTD
-
<!ELEMENT ul (li)+>
- XHTML 1.0 Strict DTD
-
<!ELEMENT ul (li)+>
- XHTML 1.1 DTD ( xhtml-list-1.mod )
-
<!-- ul: Unordered List (bullet styles) ................ -->
<!ENTITY % ul.element "INCLUDE" >
<![%ul.element;[
<!ENTITY % ul.content "( %li.qname; )+" >
<!ELEMENT %ul.qname; %ul.content; >
<!-- end of ul.element -->]]>
もし HTML 4.01 Transitional DTD あたりで
<!ELEMENT UL - - (LI|#PCDATA)+ -- unordered list -->
なんて定義になっていたらどうしようかと思いましたが、 HTML 4.01 でも XHTML 1.0/1.1 でも、 Transitional でも Strict でも ul 要素の直下に配置できるのはやっぱり li 要素だけでした。
改行や空白もテキストノードになる
さて HTML でも XHTML でも ul 要素の直下には li 要素しか配置できないということを確認したうえで。
なんでそんなDOMツリーになってるんだろう?
という部分ですが。
これは「なんで」も何も、 ul 要素の直下には li 要素以外の要素は配置できませんが、 #text となるテキストはそこに記述できるから、としか言えないかなと思います。
<ul>
<li><a href="foo">foo</a></li>
<li><a href="bar">bar</a></li>
<li><a href="baz">baz</a></li>
</ul>
<ul>
<li><a href="foo">foo</a>
<li><a href="bar">bar</a>
<li><a href="baz">baz</a>
</ul>
先ほどのサンプルではこのようなソースが例示されていましたが、これを次のような形で考えてみましょう。
<ul>#xA
#x20#x20<li><a href="foo">foo</a></li>#xA
#x20#x20<li><a href="bar">bar</a></li>#xA
#x20#x20<li><a href="baz">baz</a></li>#xA
</ul>#xA
<ul>#xA
#x20#x20<li><a href="foo">foo</a>#xA
#x20#x20<li><a href="bar">bar</a>#xA
#x20#x20<li><a href="baz">baz</a>#xA
</ul>
#xA というのは制御文字の一種で改行を表し、 #x20 は空白を表します。
こう書くと、リストの横並びで不思議な空白ができるアレ、をスマートに解決する - vantguarde - web:g で
<ul>
<li><a href="foo">foo</a></li>←ここで要素終了|→ここからテキストノード
ここまで←|こっから要素開始→<li>
や
<ul>
<li><a href="foo">foo</a></li>|←ここからテキストノード
ここまで←|こっから要素開始、なので前の要素終了→<li>
と示されている部分が少し分かりやすくなるのではと思います。
(#xA も #20 もテキストであり、テキストノードにあたるので。 )
例えば、改行や空白を取り除いた <ul><li><a href="foo">foo</a></li><li><a href="bar">bar</a></li><li><a href="baz">baz</a></li></ul> という書き方をしたものの DOM ツリーを見てみると、
UL
LI
A href="foo"
#text: foo
LI
A href="bar"
#text: bar
LI
A href="baz"
#text: baz
のように、 li 要素と li 要素の間には #text は現れなくなります。
リストの横並びで不思議な空白ができるアレ、をスマートに解決する - vantguarde - web:g ではリストをinlineで並べた時の余白|CSS HappyLife という記事も紹介されているのですが、改行や空白を取り除いて一行で書く以外の方法でも同じような結果になります。
<ul>
<li><a href="foo">foo</a></li><!--
--><li><a href="bar">bar</a></li><!--
--><li><a href="baz">baz</a></li>
</ul>
のように、 li 要素の改行にコメントを挟む書き方をしたものの DOM ツリーを見てみると、
UL
#text:
LI
A href="foo"
#text: foo
#comment:
LI
A href="bar"
#text: bar
#comment:
LI
A href="baz"
#text: baz
#text:
という結果になりますし、
<ul>
<li><a href="foo">foo</a></li
><li><a href="bar">bar</a></li
><li><a href="baz">baz</a></li>
</ul>
のように、 li 要素の終了タグの > の前で改行する書き方をしたものの DOM ツリーを見てみると、
UL
#text:
LI
A href="foo"
#text: foo
LI
A href="bar"
#text: bar
LI
A href="baz"
#text: baz
#text:
という結果になります。
終了タグの > の前で改行する書き方ってオーケーなの ? と思われる方もいらっしゃるかもしれませんが、終了タグは
[42] ETag ::= '</' Name S? '>'
のように、 > の直前に
(#x20 | #x9 | #xD | #xA)
といった空白文字類を配置できるように定義されています。
( 今回の例では含めていませんが、 #x9 や #xD を記述してももちろん #text として DOM ツリー内に現れます。 )
リプライ
リプライはまだ送られていないか、管理者の承認待ち状態です。
この記事に対するご意見やご質問、ご感想などありましたら個別記事ページの送信フォームからお送り下さい。