Hatena::Groupweb

vantguarde

 | 

4.16

でも、XHTMLじゃない件について

| 00:13

さて、さっき「別の方向でもやっとしたりするかも」と書きました。まあ分かると思うんですが、こうするためにはXHTMLではなく、HTML4を使うことになります。XHTMLはXMLなので、タグの省略ができないからです。

ただ、「なんだよー使えねー」と思う前にひとつ考えてみてください。ホントにXHTMLにする理由はありますか?

XHTMLにしたところで、広告スクリプトが吐くソースで整形式にならなかったり、自前のスクリプトがXMLを考慮してなかったりすることがほとんどだと思います。特に後者なんて、検証した事あるひと、ほとんどいないでしょう。

XMLとして扱えない文書なのに、XHTMLを利用する意義ってなんでしょう?それが「Web標準」とかいう、変な意識だからですか?

そんな「Web標準」なら、ほんとくたばってしまえばいいのに*1

というわけで、XMLとかを利用したり、rubyを使うならともかく、ただWebデザイン的なことをするときに、HTMLでよくないか考えてみてください。「XHTML!」っていきったところで、整形式にさえならないものはXHTMLではないです。

まあ、HTMLだからといって、アンパサンドをエスケープしないのが許されるわけではないんですが。ただ、こちらはまだHTML5とかブラウザーの実装っていう救いがあるので。

リストの横並びで不思議な空白ができるアレ、をスマートに解決する

| 00:01

まあ全然不思議でもなんでもないんですが。そうそう、これ、一言で説明するマジックワードがほしいですよね。

さてこれ、対処方法として紹介されてるのが、改行しないだとか、コメントを工夫するとか、開始タグや終了タグの書き方を工夫するとかです。「リストをinlineで並べた時の余白」がよくまとまってるかなと思います。

ただ、やっぱりもやもやする人は多いのではないかと。というわけで、ちょっと方法が違ったりしますが、スマートに書ける解決方法を。まあ、別の方向でもやっとしたりするかもしれませんが。

まず、display: inlineではなくてinline-blockを利用します。

li {
  display: inline-block;
 *display: inline;
 *zoom: 1;
}

下のふたつはIE7以下の対策ですね。こちらは「IE 6, IE 7 の inline-block 考察」あたりを読んでいただけるといいかなと。

「Firefox 2.0は?」と思った方。Fx2はいらないこです。目を覚ましてください。

さて、これだけではIE7以下を除いて、空白が(たぶん)できてしまいます。なぜならみなさん、「ふつう」はこう書いてるはずだからです。

<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>

liの終了タグを取ってみると。はい、これで空白が消えます。わーわー

理由を説明する前に、今のふたつのDOMツリーを見てみましょう。ついでに今書いたソースの確認も出来ます。

「ふつう」に書いたソースは、次のようなツリーを構成します。

UL
  #text:
  LI
    A href="foo"
      #text: foo
  #text:
  LI
    A href="bar"

</li>のあとにある改行と次の行のインデントからなるテキストノードが、liの兄弟として生成されます。

で、終了タグを取ったほうは、次のようになります。

UL
  #text:
  LI
    A href="foo"
      #text: foo
    #text:
  LI
    A href="bar"

よく見る必要がありますが、さっきの改行とインデントからなるテキストノードが、liの兄弟ではなく、liの子として存在しています。

どのようなことかてきとーに説明すると、終了タグは明示的に要素の終了を表す区切り子です。なので、ブラウザーは終了タグを見つけたら、DOMツリー上で生成された要素ノードを閉じます。次の開始タグ(要素ノードを生成する)までに現れる何かは、要素ノードの兄弟ノードになります。

「ふつう」の例では、終了タグが書かれていたので、終了タグのあとにあった改行と、インデントのスペース二つがテキストノードとして新たに生成され、liの兄弟として存在していました。

<ul>
  <li><a href="foo">foo</a></li>←ここで要素終了|→ここからテキストノード
  ここまで←|こっから要素開始→<li>

さて、終了タグを省略したらどうなるでしょう。ブラウザーは別の方法から、要素ノードの終了を表す区切り子を見つける必要があります。その区切り子とは、この場合liの開始タグになります。

では、aの終了タグの後ろにある、改行とスペース二つはどうなるのでしょうか。さっきと同じくテキストノードにはなりますが、li要素が終了しているとこの時点では見なされてないので、これはliの子として存在するのです。

<ul>
  <li><a href="foo">foo</a>|←ここからテキストノード
  ここまで←|こっから要素開始、なので前の要素終了→<li>

てきとーと書いたわりには思ったより長くなりましたが、そんな感じの理由です(細かいところがいろいろ怪しいですが)。これにinline-blockが加わる事でインラインボックスではなくなり、末尾の空白類が無くなります。それで、変な空白がなくなると。なお、省略の条件とか説明は「HTML や SGML における開始タグ・終了タグの省略」が詳しいです。

今回はliの終了タグが省略可能ということ、またブラウザーの実装がうまい具合になってるので、それを利用して実現したというはなしです。IE7以下だとhasLayoutマジックで良い具合になってくれますが。

*1:参考:「くたばれ!『Web標準』」 http://web.g.hatena.ne.jp/vantguarde/20090113/1231801020

securecatsecurecat2009/04/17 14:01かつてはHTML4→XHTMLという時代の趨勢が感じられた時期があって、その頃以降そのように啓蒙されているからではないですか。そんなに不思議がるのとか、くたばれとかって煽る意味がわからないですね。

 | 
Contact: @vant / lepetitcroissant@gmail.com.