HTML-lintで100点なら良いのか
HTML-lintとわ
HTML-lintというと、まあ一般的にはAnother HTML-lintを指すだろう。って何処の一般なのかは知らんが。Another HTML-lintは非常に良いサービスで、単なる文法チェックにとどまらず、いわゆる宗教的と呼ばれるたぐいの文法であるとか、WCAGに基づくアクセシビリティのチェックまでも出来たりする。
あー便利だ、便利。マジ便利。
このチェックは採点方式で行われるのだが、DTD的にはあくまでValidな文書であっても、実際には減点されたりもする。たとえば、span要素が空だったり、p要素の中がbr要素だけだったりとか、こういうのは減点される。Authorは減点されるのを防ぐがためだけに、見栄え的に影響をあまり及ぼさない範囲、つまりたとえば空白を入れてみたりする。今のAnother HTML-lintではそれでも警告を発する。いやー素晴らしい。単にDTD的にValidかInvalidかを判定するだけだったらこうはいかない。こうまで警告されれば適切な文書構造とかいうのを学ぶキッカケにもなるというものだ。
しかし、実際には文書の内容まで読んで判定してくれるわけではないから、おかしなものでもAnother HTML-lint的には100点満点になったりもするわけだ。それだと、適切な文書構造とかいうのを学ぶキッカケにはならないし、むしろ適切でない文書構造を正しいものだと誤解して覚えていってしまう可能性すらある。まあ、こだわりませんがというか、もっともこのページなんぞ、まず前提としての(?)100点満点ではなかったりするわけで、他人のことなぞ言ってられないとかいう。
論理構造と外観が一緒くたになっている状況
「正しいhtmlとcssで作るstrict page」というサイトがある。とりあえずAnother HTML-lintでトップページを採点してみると、当然ながらというか100点満点だ。しかしちょっと待って欲しいというか、このページにはおかしい点があると思うのだ。これが100点満点なのは、その点というのがAnother HTML-lintの仕組みでは対応できないようなものだから。
とりあえず、レンダリング前の状態(つまりソース)を引用してみよう。
<div class="linkbar">/ <a href="./cssguide.html" charset="shift_jis" title="htmlの利点"><span
class="linkbar">cssguide</span></a> / <a href="cgi-bin/bbs.cgi" charset="shift_jis" title="総合掲示板" ><span
class="linkbar">bbs</span></a> / <a href="index.html" charset="shift_jis" title="index"><span
class="linkbar">index</span></a> / <a href="contets.html" charset="shift_jis" title="目次"><span class="linkbar">contents</span></a>
/ <a href="link.html" charset="shift_jis" title="link"><span class="linkbar">link</span></a> /
これがWin IE5.5によってレンダリングされると
らしい。
まず、細かい話なのだが、「linkbar」というクラス名はどうだろう。この場合、「link」と「bar」というふたつの単語を繋いだ状態だと思うのだが、「bar」は「横棒」という意味だと思う。しかしこれが横棒に見えるのは、まさしくスタイルシート次第ではないのだろうか。あと、「linkbar」って単語は無いだろうから、せめて「linkBar」とか「link-bar」とかのほうが、この命名の是非はさておいても良さげ。謎の単語を作り出すくらいならローマ字で「Rinkuba」とかどうか…って「リンク場」っぽいなコレだと。つーか何なら日本語でも良いし。
ついでになんか気になったので、適用されているスタイルシートであるstart.cssも見てみたり。background-colorプロパティの初期値はtransparentなのだから、transparentだったら別にあえて書かなくても良いはず。background-colorプロパティは継承だってしないんだから。各スタイル定義中、colorプロパティが有るところにはほぼ全てbackground-color:transparent;となっている。なんかこれって、CSS Validatorが出す警告防止のためだけのように思えてしまう(偏見)。transparentじゃなくても、なんか色の指定値がどうかと思うところとか。あと、なぜか宜しくない個所に全角空白があったりする。これだと、レンダリングエラー以前にパースエラーになる可能性があるような、ないような(どっち)。
ていうか、別に此処は野嵜氏の斬るコーナーを目指しているわけでもないので(しかも斬るコーナーの主旨とも違うし)、この辺にしといて、んで、ソースを引用して、このソースがレンダリングされるとこうなる、ってとこまで話を戻す。
さてこのlinkbarクラスのdiv要素であるが、この要素はコンテンツとして存在しうるアイテムを格納(羅列)したブロック要素と解釈すれば良いだろうか。それらのアイテムを「/」で区切って羅列しているという。
さて、ではリンク文字列となっている各アイテムとの区切り子になっている「/」、更にそれらの間に見られる全角空白、こいつらは一体何なのか?
この要素においては、リンク文字列たちもまた要素であるのだが、「/」と全角空白は外観(見栄え)を制御しているのではないだろうか。「/」については賛否両論あるやもしれないが、少なくとも全角空白は間違いなく外観だし、僕は「/」もそうではないかと思うのだ。根拠は次で述べるので読み進めて欲しい。
論理構造と外観の境界線
HTML 4.01文書である「正しいhtmlとcssで作るstrict page」の、このlinkbarクラスのdiv要素の部分だけを抽出して、しかもXHTML 1.0で書かれていることにして、その情報ソースとなっているXMLを想像してみる。それはたぶんきっと、こんな感じだ(適当)。
<?xml version="1.0" ?>
<?xml-stylesheet href="index.xsl" type="text/xsl" ?>
<contents>
<item>
<url>
<![CDATA[./cssguide.html]]>
</url>
<charset>
<![CDATA[shift_jis]]>
</charset>
<title>
<![CDATA[cssguide]]>
</title>
<description>
<![CDATA[htmlの利点]]>
</description>
</item>
<item>
<url>
<![CDATA[cgi-bin/bbs.cgi]]>
</url>
<charset>
<![CDATA[shift_jis]]>
</charset>
<title>
<![CDATA[bbs]]>
</title>
<description>
<![CDATA[総合掲示板]]>
</description>
</item>
<item>
<url>
<![CDATA[index.html]]>
</url>
<charset>
<![CDATA[shift_jis]]>
</charset>
<title>
<![CDATA[index]]>
</title>
<description>
<![CDATA[index]]>
</description>
</item>
<item>
<url>
<![CDATA[contents.html]]>
</url>
<charset>
<![CDATA[shift_jis]]>
</charset>
<title>
<![CDATA[contents]]>
</title>
<description>
<![CDATA[目次]]>
</description>
</item>
<item>
<url>
<![CDATA[link.html]]>
</url>
<charset>
<![CDATA[shift_jis]]>
</charset>
<title>
<![CDATA[link]]>
</title>
<description>
<![CDATA[link]]>
</description>
</item>
</contents>
しかし、こうして見ると、この時点で何か違うような。このXMLでいうところのtitle要素とdescription要素の違いというか、ふたつある意図がわからないというか。実際のHTMLソースでa要素title属性として扱われているからには補足説明なのだろうということでのdescription要素なのだが、title要素もdescription要素もどっちも「index」というのがある。「cssguide」なんかも「contents」に含まれそうな気もするというか。そもそもリンク文字列が英語でその説明として日本語(というか和訳)、みたいなのは、あまり好きじゃないというか。意味が無いと思うのだが。いや無いことは無いか。…まあいいや、っていうか、まあいいか(謎)。
んで、まあアレだ。HTML文書なのだからXML文書として考えなくて良いともいえるけど、そもそも情報を整理する際は論理構造と外観とを切り分けて考えていくのが近道というかで、考え方としてはXML文書を作る勢いのほうが結果として、真の意味でValidかつStrictな文書になるんじゃないかっつーわけで、上記の仮想XML文書(謎)のような状態になってしまうのは、僕のXMLも悪いとは思うが、そもそもうまいこと論理構造が確立されてないんじゃないか、とも思ったりするわけで、まあとにかく先に進むとしよう。
XMLは文書の論理構造(データ)でしかないから、このままじゃ多くのブラウザでは面白くない。というわけでXSLとCSSを使って、ブラウザで面白くするように仕向けるわけだ。XSLはたぶんきっと、こんな感じ(更に適当)。
<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<xsl:template match="/">
<xsl:doctype>
<![CDATA[html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"]]>
</xsl:doctype>
<xsl:element name="html">
<xsl:attribute name="xmlns">
<![CDATA[http://www.w3.org/1999/xhtml]]>
</xsl:attribute>
<xsl:attribute name="xml:lang">
<![CDATA[ja]]>
</xsl:attribute>
<xsl:apply-templates select="contents" />
</xsl:element>
</xsl:template>
<xsl:template match="contents">
<xsl:element name="head">
<xsl:element name="link">
<xsl:attribute name="rel">
<![CDATA[stylesheet]]>
</xsl:attribute>
<xsl:attribute name="href">
<![CDATA[index.css]]>
</xsl:attribute>
<xsl:attribute name="type">
<![CDATA[text/css]]>
</xsl:attribute>
</xsl:element>
<xsl:element name="title">
<![CDATA[linkbar]]>
</xsl:element>
</xsl:element>
<xsl:element name="body">
<xsl:element name="div">
<xsl:attribute name="class">
<![CDATA[linkbar]]>
</xsl:attribute>
<xsl:apply-templates select="item" />
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="item">
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:value-of select="url" />
</xsl:attribute>
<xsl:attribute name="charset">
<xsl:value-of select="charset" />
</xsl:attribute>
<xsl:attribute name="title">
<xsl:value-of select="description" />
</xsl:attribute>
<xsl:value-of select="title" />
<![CDATA[ / ]]>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
で、さきほど、全角空白だけではなくて区切り子になってる「/」も外観だと書いたが、その根拠。この場合「/」は、羅列の区切りなのだから、別に「,」でも、あとたとえば「|」とか、そういうんでも問題ないはずだし、逆にいえば、たとえば「/」じゃなくて「,」にしたくなった時、この区切り子をあくまで外観として定義してあったらどんなに変更が容易なことかは想像に難くないはずだ。要するに外観を構成する部品だということだ(XMLに含まれていないという時点で自明というか)。
上記のXSLの時点でも、最後のほう、赤い字かブラウザによっては太字だとか他の行とはちょっち違う感じで表示されているであろう「<![CDATA[ / ]]>」という行のところをいじるだけという簡単さではある。具体的には、区切りを「,」にしたくなったら、この行を「<![CDATA[ , ]]>」とするだけだ。
しかしだ。これはまだ甘いというか、全角空白の扱いだ。この全角空白は、リンク文字列と「/」とがくっつきすぎるのでAuthor的には見づらくなると予測して、それを防ぎたいがために入れてある、ようはCSS的にはpaddingプロパティみたいなもんだと思われる。となると、だったらまさしくCSSでやったらどうよ? と思うわけだ。
CSSでこの外観の部分を書くとすれば、たとえばこうなる(またもや適当)。
div.linkbar a {
text-decoration:none;
}
div.linkbar a:before {
contents:"\3000";
}
div.linkbar a:after {
contents:"\3000";
}
「/」も入れてしまいたいなら、a:afterの時のcontentsプロパティの値を「"\3000/";」にすれば良いだけ。そんで最初のアイテムの前にも「/」が欲しいという、いわゆる例外処理みたいな感じだったら、更に:first-child擬似クラスと混ぜたりすれば良さげ(XSLならもっと簡単そうだが)。
ちなみに、XSLで出来るんだからCSSじゃなくてもいいじゃん、というわけにはいかない。XSLはXML文書からHTML文書やらXHTML文書やらを生成したりするためのスタイルシートであるが、その生成された文書の外観は、たとえばCSSというスタイルシートによるなどして制御されるわけだから。
とはいっても、たとえばNetscape6にこれをレンダリングさせると思惑通りになるものの、:beforeコンテンツと:afterコンテンツも、当たり前といや当たり前なんだがリンク文字列の一部と見なされてしまう。まあ、それはそれでいいのか、とも思うけど、そうしたくないという場合はじゃあどうすれば良いのか。区切りの「/」のほうをspan要素で括るか?
div.linkbar span:before {
contents:"\3000";
}
div.linkbar span:after {
contents:"\3000";
}
こうか。確かにこれなら:beforeコンテンツと:afterコンテンツはリンク文字列の一部と見なされないよな。そーかそーか。こう書けば良かったんだ。だとするとつまり前述のXSLの赤だか太字だかいう個所の「<![CDATA[ / ]]>」は、
<xsl:element name="span">
<![CDATA[/]]>
</xsl:element>
こうなるわけか。うーむ、なるほど。
ていうかそもそも違うんじゃ?
しかしだ。このlinkbarクラスのdiv要素であるが、そもそもこれはdiv要素であるべきなのだろうか。strongクラスのspan要素であるとかを作るのが非常に望ましくないとされているのと同様に、既に存在する要素があればそれを使ったほうが意味づけの意図がより明確になるはずである。
というわけで、この場合、これはサイトのインデックスとなるリンク文字列を列挙しているわけなのだから、リストなのではないか、ということだ。
そうであれば、間の空白と「/」は一体何だとかいう疑問がそもそも出ずに、実にすんなり解決する。HTMLのマークアップ的にはこうすれば良い。
<ul>
<li><a href="./cssguide.html" charset="shift_jis" title="htmlの利点">cssguide</a></li>
<li><a href="cgi-bin/bbs.cgi" charset="shift_jis" title="総合掲示板" >bbs</a></li>
<li><a href="index.html" charset="shift_jis" title="index">index</a></li>
<li><a href="contets.html" charset="shift_jis" title="目次">contents</a></li>
<li><a href="link.html" charset="shift_jis" title="link">link</a></li>
</ul>
実に素直な、まさにそのまんまというやつだ。んで、このリストに対するCSSは、こんな感じに定義するわけだ。
ul {
color:white;
background-color:red;
margin:1em 2em;
padding:2px 1em;
}
ul li {
display:inline;
}
ul li a {
color:white;
background-color:transparent;
text-decoration:none;
}
ul li:after {
content:"\3000/\3000";
}
ではこれを実際にやってみよう。これにて一件落着というか、つまりリストであるべきだというか、そのほうが構造上スジが通っているんじゃないかってことだ。いずれにしても全角空白とか「/」とかは見栄えに含まれるということにもなる。
Another HTML-lintの一歩先へ
まあその例示としてはイマイチな題材だったかもしれないが、いずれにしても妥当な文書だと名乗るからには、やっぱり単純にDTD的にValidだというだけじゃつまらない。構造的にというか、文書として真に妥当たりえているかって辺りまで、とりあえず意識だけでも常々したいところだ。
ところで「Another HTML-lintの一歩先へ」ってフレーズ、今考えたわりにはなかなか秀逸だとかいう気分。
免責(謎)
ちなみに、haza氏の名誉のためにも(というと多少語弊があるが)フォローしておけば(というと更に語弊があるが)、別にhaza氏のページそのものがどうのというわけでもないし、ましてや当然ながらhaza氏自身がどうのというわけでもないので、その辺はひとつよろしくというか。
kotobaseekのCSSとかからリンクされてる様々なサイト、およびkotobaseekそのものでさえ、今回例として扱っているlinkbarクラスのdiv要素のような時には、やはり多くのサイトが、半角空白や全角空白や「/」や「|」なんかを使っている。だいたい僕のこの「suneo | Pointless In A Sence」だってMSのメニューみたいなのはdiv要素で表現されちゃっていたりするという勢い。ブラウザのCSS対応状況の関係でといいつつ、Authorの自己満足の便宜をはかるためには「バグのあるブラウザは無視しちゃう」とか豪語しつつも、:hover以外の擬似クラスは多くのブラウザが対応していないとかの都合上、Authorの自己満足の便宜があまりはかれない辺りだったりすると、「後方互換を意識しちゃう」などと言ったりして、結果的には自分に都合の良いマークアップをしてしまったりするものなのだ。と思う。
まあ、だからつまりは意識だけでもって話。
(2001.3.7)