May 06, 2007

first-letter 疑似要素と入れ子の要素

今日、CSS の表示をテストしていて気づいたのですが…。

次の CSS をご覧ください。

h2:first-letter { color: red }

そして、下の要素を見てください。

<h2><a id="intro">Introduction</a></h2>

h2 要素の中に a 要素が入れ子になった、この記述。これに上の CSS を適用すると、どうなるでしょうか? 答えは、IE および Opera では最初の "I" が赤くなり、Firefox では変わりません。

この挙動、いったいどちらが正しいのでしょうか。一見すると IE と Opera が正しいように思えますが、上の CSS は h2 要素の先頭 1 文字に対してスタイルを定義しているのですから、実際には a 要素の 1 文字目である "I" にはスタイルを適用しない Firefox の振る舞いも妥当であるように思います。けれども IE や Opera が間違っているかというと、この場合 "I" は a 要素の先頭 1 文字であると同時に、その外側の h2 要素の 1 文字目でもあるので、間違いとも言い難いような気がします。

単なる実装の違い、と片付ければ簡単ですが、この動作は知らないと意外に落とし穴のような気がします…というか、私ははまりました。上記のような a 要素の有無で、ページによって h2 要素の表示が変わってしまうのですから。皆さんは、どちらの挙動が妥当だと思いますか?

June 25, 2006

トラックワードと XHTML

先日設置したトラックワードが原因で、どうやらこのウェブログは IE でアクセス不可能になっていたみたいですね。

私は通常 Firefox で表示を確認しているので、知り合いから MSN メッセンジャーで言われるまで全く気づきませんでした。そして最初はその原因も、サイトのシステム変更に伴い導入した mod_rewrite によるアクセス制限などが原因かと思いました。しかしその割には、IE でアクセスした場合にも普通に読み込もうとするそぶりを見せる…というか、サーバー設定が原因なら IE のみアクセスできないなんて変です。

そこで最近 blog に加えた変更で思い当たったのが、トラックワードでした。試しにはずしてみると、案の定、正常にアクセス可能になりました。

しかし、これに使用している JavaScript は DOM 的にも正しくなるよう記述したのを自前で用意しており、プログラム的には問題ないはず…というわけで当初はアクセス不能になる理由がさっぱりわからなかったのですが、調べたところどうも自作したスクリプトが appendChildbody 要素の末尾に script を追加していたのが原因と発覚。そこで、これを body 要素の先頭に挿入するよう変更したところ、問題なくページを表示できるようになりました。

とはいえ、このような症状が出たのは IE だけなのですから、やはり IE の DOM 実装に何らかの問題点が存在するわけですかね…というか DOM の実装状況、ブラウザ間の差が大きすぎです。

でも、おかげで勉強になったのも事実。前回のトラックフィードの設置と今回のトラックワードの JavaScript で、DOM の作法というのが、少しは理解できたような気がします。とりあえず要素を追加する手順は記憶。ちぃ覚えた!

まあとにかく、これにてトラックワードはこのウェブログで正式に使用開始という方向で。明日から毎日楽しみです、訪問者がどんなキーワードで間違って私の blog に迷い込んでくるのかの情報がw

November 04, 2005

table 要素は難しい

1 つ前のエントリを書いていて、私が悩んだこと。それは、リスト項目のマークアップを dl 要素で行うか、table 要素で行うかということ。

前のエントリで私は、一対一で対応するデータを列挙しようと思ったのですが、これを表すのに理想的な要素がわからない。縦軸・横軸ともに見出しが必要な訳ではないので、table 要素を使うほどのことはない気がする。かといって dl 要素では対応関係がわかりにくく思える。

結局、悩んだ末に使ったのは table 要素。その理由は扱うデータが氏名で、対応するそれぞれに thead 要素と th 要素で見出しをつけたほうがわかりやすかったから。アクセシビリティの観点と、何よりマークアップの面倒くささからあまり table は使いたくないのですが、情報のわかりやすさを考えれば妥当な選択だったと思っています。

折しも某方面で著名な言葉 言葉 言葉の闇黒日記で、ちょうど table について取り上げられている。そう、table を使うのは決して悪ではない。問題なのは、それをを表すためではなく、レイアウト目的に使用すること。逆に table を利用しなくても、CSS の見栄えのために何でもかんでも div 要素で囲むようなマークアップ (いわゆる div 厨) をしていれば、それは正しい HTML とは言えません。

けれども、アクセシビリティを考慮しつつ table 要素でマークアップするのは大変。

鳩丸ご意見番 - TABLE でレイアウトは

…音声ブラウザなどを想定すると、このような配慮が必要なのです。私も自分の PC の紹介過去に販売された PC のスペック一覧に table を使っていますが、これらがそういった要件を 100 パーセント満たしているという確信は持てません。さらに言うなら、どんなに配慮したところで、それを読み上げる UA が対応していなければ結局 table はユーザーのアクセシビリティを下げる原因となってしまいます。そしてこれは何も音声ブラウザに限ったことではありません。テキスト ブラウザにも table を表示できないものは多いですし、画面の狭い携帯電話では物理的に表示できないでしょう。

このように考えると、真のユニバーサルなサイトを実現するには、table 要素のマークアップがいかに難しく大変であるかがわかります。そしてこれを安易にレイアウト目的で使用することが、どれほどユーザーに不便を与えるか…私も以前そのようなテーブル レイアウトを行っていただけに、それがもたらす結果を今思うとぞっとします。

「あなたのそのサイト、あなた以外の人には見えていませんよ?」

…もっと世のほーむぺーじ おーなーの方々には、テーブル レイアウトのリスクと弊害を知ってほしいです。table 要素の使い方は、そんなに簡単ではないのです。

May 27, 2005

CSS と携帯電話

私の使っている京ぽんこと AH-K3001V もそうなのだけれど、最近の携帯電話に搭載されているブラウザは CSS にも対応しているらしい。

いったいそれがどの程度の実力なのか、試しに i-mode や EZweb の Openwave で自分のサイトにアクセスしてみた。私のサイトは AH-K3001V 用に handheld メディアのスタイルも定義してあるので、もしかすると最新の携帯電話なら PC と同様のデザインで閲覧できるだろうか…と期待した。

ところが、表示されたのは何も装飾の施されていない白黒のページ。えぇぇ? と思ったが、どうやらダメらしい。一般的な携帯電話の CSS 対応状況は、どうにも限りなくお寒いらしい。

…そう考えると、やはり京ぽんの Opera はすごい。それ用の CSS を用意すれば、ちゃんと HTML を装飾して表示してくれるのだから。もっとも京ぽんも、CSS の表示にはそれなりの癖があるので、対応した記述は必須なんですけれども。

携帯電話で見栄えのするページを作るには、結局 font やら blink だの marquee といった、W3C 的に使っちゃいけないものに頼るしかないのか…。

April 13, 2005

first-letter の悪夢

サイトの CSS 改良に伴い、first-letter 疑似要素を用いて見出しの先頭 1 文字の色を変えてみようと思った。

CSS を書き換え、Firefox で期待通りの表示となっているのを確認した後で IE の表示を確認すると…ぐあー、なんだこれ。first-letter を指定した要素に続くブロックが、ボーダーを突き破り左にはみ出している。

何が原因なんだ、もしかして IE のバグなのか…試しに first-letter に適用したプロパティを削除してみると…元の表示に戻った。

いったいどうなっているのかと苦労して情報を見つけると、どうやらこういうことらしい。

擬似要素を含む要素に後続する要素の内容物が左右にはみ出る

なんだか条件が複雑なのですが、検証してみると自分のサイトに見事にマッチしている。うわ、何このバグ。

対策として示されているwidth プロパティや height プロパティの値を明示してみると、はみ出す問題は直った…が、今度は肝心の first-letter 疑似要素を用いたブロックがガタガタになる。あげくの果てには標準準拠モードと後方互換モードで表示が全く異なってしまう始末。

結局、どうやっても IE でまともに表示できないので、今回は先頭 1 文字の色を変えるのはあきらめた。悔しい。やっぱり IE は窓から…(略)。

April 10, 2005

IE でもフロートにマージンを

以前のエントリで書いた、IE でフロートの左右マージンが大きくなるバグ。

先日 blosxom の偉い人、Kyo さんのトコで対処法を見つけたので、試してみた。

結果…わ、左右マージンが正常に表示されてるよ。やった、これでダミーの padding ともお別れだ!

でも、フロートなのにインライン要素とかって超キモい…けど、まあ気にしたら負けなんだろう。

IE でまともに表示させようとすればするほど、CSS が汚くなっていくような気がする今日このごろ。

March 14, 2005

accesskey 属性に数字を

ふとした思いつきで、サイトの CSS を京ぽんこと AIR-EDGE PHONE AH-K3001V 対応にしてみようと思いました。

現状このサイトは京ぽんのスモール スクリーン モードでアクセスすると、CSS が適用されず、真っ白な画面に黒い文字が表示されます。これを少しでも PC での表示に近づけたい。そのために handheld メディア用のスタイルを定義することにしました。そうすれば、京ぽんはそれを読み込み、スモール スクリーン モードの表示に適用してくれます。

そうと決まれば、まず行わなければならないのはサイト HTML 論理構造の見直し。現在使用しているページ構成要素は Movable Type のテンプレートを一部参考にしているのですが、この構造は意味的に考えておかしな部分を抱えています。新しい CSS 適用にあたっては、それを補正しなければなりません。

さらにそれに加えて思いついたのが、ページ ナビゲーションや主要なリンクに、accesskey 属性による携帯電話用のアクセス キーを設定すること。入力デバイスの制限から PC に比べ操作性の劣る携帯電話のブラウザに対し、ダイヤル キーを用いたアクセス キーを設定することは、大幅なアクセス性の向上が期待できます。

というわけで、さっそくナビゲーションの「戻る」に数字の 0 キーを、そして「« 前へ」と「次へ »」の存在するページには、それぞれに *# を割り当てました。さらに章構成となっているページは各章のリンクに、目次ページは各コンテンツのリンクに、それぞれ 1 から 9 を割り当ててみました。

そして今日、もしかするとこのキー設定は非常に合理的なのではないかと、電車に乗りながら思いました。というのも、私が帰宅時の電車内で、手すりにもたれて立って、実際にノート PC で操作してみたからです。

ノート PC を立った状態で使う場合、基本的に片手で本体をホールドし、もう片方の手で入力を行うことになります。ところが乗り物の車内は揺れるために、モバイル機器のポインティング デバイスは意外と使いづらいものです。

通勤電車の乗客の大勢が、揺れる車内でも平気で携帯電話のメールを読み書きできるのはなぜでしょうか。それは、携帯電話が揺れの影響を受けにくい、ボタンという入力デバイスを採用しているからです。

ならば、それに近いキーボードというインターフェイスを使えるように、サイト側が用意すればどうでしょう。

今回私は、作りかけのサイトを車内で表示確認したのですが、アクセス キーを設定してあるとそれも簡単に行えました。Windows の IE の場合、アクセス キーを利用するには Alt キーを押しながら目的のキーを押さねばならないのですが、それでもマウス ポインタでいちいちリンクを選択してクリックするよりは楽に感じました。

さらに、これが今回の主題なのですが (前置き長すぎ…)、ここではアクセス キーに数字を設定したことに意義があります。

通常アクセス キーに数字を設定するのは携帯電話向けサイトが主ですが、私は PC サイトにおいても、数字のアクセス キーは有用だと思うのです。というのも、通常アクセス キーに使われるアルファベットは、常にブラウザのショートカットとバッティングする危険性を持っているからです。

具体例で言うと、たとえばサイトの解説ページ (ヘルプ) へのリンクとして、H キーを設定した場合。これは Windows の場合、ほとんどの環境においてメニューの「ヘルプ」とバッティングします。Firefox や IE だと、この場合は Alt キーを押しながら H キーを押すとアクセス キーが、Alt キーを押して (その後離して) から H キーを押すとメニューがアクティブになりますが、ユーザーの混乱を招くためこのような割り当ては避けたほうが無難でしょう。

これらアルファベットのうち、特に致命的なのが D キーです。前記 2 つのブラウザでは、Alt+D を押すことによりアドレス バーにフォーカスする (カーソルが表示され、入力状態になる) のですが、D キーにアクセス キーを割り当ててしまうと、既定のキーでアドレス バーにフォーカスできなくなってしまいます。

このように、アルファベットによるアクセス キーには、割り当てを誤ると逆にユーザーのアクセシビリティを低下させてしまう可能性があります。そしてブラウザが異なれば、これら危険なキーも異なってきます。その点、逆に数字はメニューに使用されることはほとんどないので、こういった問題も少ないと思われます。

HTML のアクセス キーには存在を疑問視する意見も多数ありますが、あって害になるのでなければ、つけてもいいのではないかと思います。特に操作性に難のある携帯電話向けのページには、絶対につけたほうがよいと思います。

携帯電話でもアクセスできて、PC でもアクセシビリティを損ねない。そんな「数字によるアクセス キー」の付加を、私はすべてのウェブサイト制作者に提案したいと思います。

March 05, 2005

mod_layout と mod_rewrite

昨日の XHTML の話の続きなんですけれども、XML 宣言の有無が問題なら、それをユーザーの環境に応じて動的に対処してやればいいじゃないかと思ったんですよ。

もっと具体的に言うと、私の考えた方法は次のようなもの。

まず、アクセスしてきた UAHTTP_ACCEPT を見るんですよ。そしてそこに application/xhtml+xml があれば、その UA には Content-Type: application/xhtml+xml; charset=Shift_JIS のヘッダと <?xml version="1.0" encoding="Shift_JIS"?> の XML 宣言を付加した文書を返してやる。これがない、つまり IE 6 を含む application/xhtml+xml を受け付けない UA に対しては、Content-Type: text/html; charset=Shift_JIS のヘッダと XML 宣言のない文書を返してやるんです。

では実際に、この処理を実現するにはどうすればいいか。ざっと調べたところ、Apache のモジュール mod_rewrite を利用して HTTP_ACCEPT の値に応じた Content-Type を出力する方法は見つかったのですが、文書側の加工なしで動的に XML 宣言の付加を制御する方法は見あたりませんでした。

SSIPHP を使えば簡単に文書内容を動的に変えられるのですが、そういった処理を通常の文書中に含めるのはできれば避けたい。

そこで思いついたのが、広告自動挿入に使われる Apache の mod_layout モジュールを利用して、サーバー レベルで UA に応じた XHTML を生成する方法。さっそく .htaccess ファイルにその処理を記述して試してみたのですが、残念ながらうまくいきませんでした。

ならばどうするかと考え思いついたのが、前出の mod_rewrite と CGI の併用です。かなり無茶な方法なのですが、概略を説明するとこんな感じ。

  1. まず、XHTML 文書を XML 宣言を記述せず作成する。
  2. HTTP_ACCEPT に application/xhtml+xml を含む UA の場合は、mod_rewrite を有効にする処理を .htaccess に追加。
  3. mod_rewrite は HTTP_REQUEST_FILENAME をパラメータとして CGI を呼び出す。
  4. 呼び出される CGI は Content-Type: application/xhtml+xml のヘッダと、パラメータに指定されたファイルに XML 宣言を付加した文書を出力。もちろん CGI は UA からは普通の文書に見えるよう Last-Modified を出力する。

なんだかこれだけだとわかりづらいですが、つまり IE などの application/xhtml+xml を受け付けないブラウザの場合は、あらかじめ作成した XML 宣言のない XHTML をそのまま出力するわけです。それ以外の場合に初めて CGI を通して出力を加工する…と。これを行えば、私のサイトにおける XHTML の互換性問題は一発解決ですよ。もうすばらしい。感激のあまり体中から何かが出そうですよ。で、自画自賛したらとりあえず口からあくびが出ました。寝不足なので。

さて、今後の方針が決まったので、これから XML 宣言のない XHTML をばりばり作ることにします。よーし、ガンガルぞ。

March 04, 2005

HTML か XHTML か、それが問題だ

サイト内の文書を HTML 4.01 Strict から XHTML 1.0 Strict に変更中。

今までこのサイトは UA の互換性などの配慮から、ウェブログも含めすべてを HTML で公開してきたのですが、最近 RDF などのセマンティック ウェブ関連の知識を得るにつれ、やはり XHTML に移行すべきと思うようになりました。

しかし XHTML に移行すると、どうしても避けられないのが UA の互換性問題です。XHTML 1.0 は従来の HTML との互換性も最大限に配慮された規格ですが、それでも細かい部分の相違点は少なくありません。

XHTML 化にあたって、私が感じた問題は下記の点です。

  1. XHTML は属性の最小化ができない。つまり HTML の <input type="checkbox" checked> などは <input type="checkbox" checked="checked" /> のように書かねばならない。ところが古い UA はこれを解釈できない。
  2. IE の新しいバージョンは DOCTYPE 宣言により標準準拠モード後方互換モードの切り替えを行うようになったが、XML 宣言を記述した XHTML 文書は DOCTYPE 宣言に関わらず後方互換モードでレンダリングされてしまう。
  3. Mac 版 IE 4.5 は XHTML で XML 宣言が行われていると、そのファイルをソース表示してしまう。
  4. XHTML では XML 宣言を行うことが強く推奨されており、また文書の文字コードが UTF-8 または UTF-16 以外で、なおかつサーバーのヘッダ情報で文字コードを指定できない場合は encoding="Shift_JIS" のように encoding 宣言が必須。しかし文書中で文字コードを指定した場合、一部の文字コードを強制的に変換してキャッシュするプロクシ サーバを利用している環境では、変換された文書と encoding 宣言の文字コードが矛盾していると文字化けする。

属性値の最小化以外は XHTML に全く非はないのですが (XHTML 文書の解釈を間違う IE や、勝手に文字コードを変換するプロクシの責任)、どれも頭の痛い問題ばかりです。特に DOCTYPE 宣言の問題は多くの CSS 派の人々を悩ませていますし、Mac 版 IE 4.5 に至っては表示すらできないことになります。

文字コードについてはサーバー側で HTTP ヘッダに指定できれば問題ないのですが、それでも文書をローカルに保存した場合を考えると、文字コードは文書側にも指定するのが無難です。ところがそうすると、前述のプロクシ問題が発生する…と。

実は以前にも私はサイト内文書の XHTML 化を行ったことがあるのですが、上記のようなデメリットばかりが目立ったので、結局は HTML に戻してしまったのです。しかし今後を考えると、やはりサイトの XHTML 化は必須に思えます。

ならばどうするか。手っ取り早い解決方法としては、文書の XHTML 化はするけれども XML 宣言は行わない方法があります。こうすれば、上記のうち XML 宣言が原因の不都合はすべて解決することになります。また、Netscape Navigator 3.0x や携帯電話のブラウザなど XHTML に対応しない UA の中には、DOCTYPE 宣言より前に出現する XML 宣言を文字列としてレンダリングしてしまうものが存在しますが、これも XML 宣言を除去することにより解消します。

ただしこの方法を行った場合、完成した文書を Another HTML-lint でチェックすると XHTML 文書は XML 宣言をすることが強く求められています。と怒られ激しく減点されます。まあ私は Another HTML-lint で 100 点を取るためにサイトを作っているのではないのでそれ自体は別にかまわないのですが、でも XHTML 文書として不正であるのならそれは直すべきです。ところがそうすると上記の問題が浮上するわけですね。なんかもう振り出しに戻るみたいな感じ。

そんなわけでベストな解決方法は見つからないままに、今日は悶々としながら HTML ファイルを書き換えています。今の私の心理状況は、次のようなせりふで表されます。

「千歌音ちゃん…私、どうしたらいいのかな」

また、次のような一言で簡潔に表すことができます。

「どうすればいいんだ!」

千歌音ちゃん…私、どうすればいいんだ!

March 03, 2005

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML...

久しぶりに XHTML 1.0 Strict で文書を作成しようとしたら、システム識別子をど忘れ。

確か、こんなんだったはず…と思って書いたら、ばっちり間違えてましたよ。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml10/DTD/xhtml10-strict.dtd">

…何を勘違いしたのか、xhtml1 と書くべき部分によけいな 0 をつけている。Another HTML-lint でチェックすると当然エラー。

やっぱりしばらく使わないと忘れるものですね。あはは。