IEの独自拡張を逆手に取って

CSS HappyLifeさんでまた気になる記事を見つけました。

IEの様々なバグの真相らしきもの

ソレはhasLayoutというIE独自拡張の一つ。

・・・中略・・・

その結果、hasLayoutがIEの様々なバグの元凶(大袈裟?)だったみたいです。

hasLayoutは、ソコにレイアウトが有るのか無いのかってのを判断しているようで、デフォルトの値がfalseでレイアウト無しになっているので「背景色が指定された要素内でfloatがある時、要素内の文字が消える」とかって現象が起こるっぽいです。

そして、heightやwidthを指定することでトリガーとなりhasLayoutの値がtrueになり、レイアウトが有るとみなされ表示されるようになると。

うへぇー、なるほど。記事内でのお言葉をそのまま使わせていただくと、超GJな記事ですよ。目からウロコ落ちまくり。こういったIEの独自拡張を逆手に取ったコーディングができるようになると、また一味も二味もコーディングの奥深さが違ってくるでしょうね。ただ、独自拡張を使っていくと、W3Cの仕様的にはValidではなくなってしまう点に注意です。

CSS HappyLife 管理人さんがおっしゃる通り、IEではこれが仕様だということでしょう。少なくとも、私はそう解釈することで少しでも納得するようにしています。「バグ」と言ってしまうと、プログラム開発者の想定の範囲外で発生する不具合のことであり、ユーザーとしてはそれに遭遇したが最後、どうしようもないわけですから。

Web標準化という大きな流れの中で、Microsoftの独自仕様が鼻に付くようになった、という解釈で良いのではないかと思います。(IE7のリリースによってMicrosoftもWeb標準に大きく歩み寄ったわけですが)

その記事からリンクのあったMSDN(英語)のリファレンス、ちょっと覗いて見ただけですが、かなりすごいです。天下のMicrosoftだけありますね。

MSDN CSS Reference

MSDNを本格的に見始めたりなんかしたら、さながらディベロッパーのようです。コーダーという職種は、デザイナーとディベロッパーの調度中間に位置しているような気がします。

Opera/Safariでレイアウトが崩れる現象

@import で呼び出すファイルのパスが間違っていると、詳細不明なレイアウト崩れが発生することがあります。HTML 4.01 Tranditional(システム識別子有り)のドキュメントで、Opera9、Safari2においてこの現象を確認しました。その他のブラウザでは、ファイルのパスが間違っていれば無視されるだけです。詳細不明な、と書くだけに理屈では説明できない、理解不能な崩れ方をします。

Like@Lunaticのテンプレートをベースにサンプルページを作ってみたのですが、自宅のOpera9(Win)ではこの現象を確認できませんでした。Like@Lunaticの文書型は XHTML1.0 Strict なので、文書型によって発生条件が変わるのかもしれません。

検証は不十分ですが、Opera/Safariでのみ理解不能な崩れ方をする場合は、この点を確認してみると良いかもしれません。

IE の Stand Alone版

ブラウジングに利用しているメインブラウザはFirefoxですが、InternetExplorerでのブラウザチェックを欠かすわけにはいきません。私のWindowsXP環境ではIE7をインストールしてしまっていますが、IE6とIE5.5のStand Alone版をインストールしています。

これらはevolt.orgというサイトにブラウザのアーカイブがどかーんとアップされているので、そこからダウンロードすることができます。IEのStand Alone版は InternetExplorer > 32bit > standalone の順にクリックしていけばあります。ただこのサイト、ところどころエラーが出たまま放置されているようですので、もう先は長くないのかもしれません。今のうちに必要なブラウザをダウンロードしておいた方がいいでしょう。

このStand Alone版、本当にサイトの表示チェックしかできません。お気に入りは使えない、Cookieも使えない、印刷もできない(印刷プレビューも表示されない)という・・・。公式なものではないだけに仕方ないところでしょうか。ただ、印刷プレビューができないのは痛いところです。「IE6で印刷するとレイアウトが崩れるんだけど・・・」などというクレームが来た日には、面倒なことになります・・・。

また、このStand Alone版の他に Install multiple versions of IE on your PC というものがあります。こちらはインターフェイスが全て英語になります。また環境によってはIE3、IE4はうまく動かないようです(私の環境もそうでした)。

恥ずかしながら、自宅にMac機がありません。そのうちIntelMacを買ってParallelsを入れてブラウザチェック環境は完璧だ、イヒヒ・・・などと妄想していたりするのですが・・・。

パンくずリストのマークアップ考察

とある案件でパンくずリストをどうやってマークアップするのが最適解なのか悩んでいました。例えば、以下のようなヴィジュアルデザインのパンくずリストをマークアップするとします。

とあるパンくずリストのヴィジュアルデザイン例

まずどんなブロック要素で囲むか?そして > 部分はどうするか?> というのが真っ先に思いつきますが、これはスマートとは言えないのでは・・・などなど。そこでGoogleで情報検索したところ、次の記事を見つけました。

日々のネコゼログログ: アクセシブルな「パンくずリスト」

こちらの記事によると、インフォアクシアの植木さんのインタビューからの抜粋があります。そのインタビューの様子はこちら。アクセシビリティを言い出すと・・・結局はこの人にたどり着くようです。頭が下がります。

あとは、試しにやってみているのですが、パンくずリストの間に挟む矢印を画像にして、「の中の」という代替テキストを入れてあります。こうすると例えば「ホームの中のニュース」と読み上げられるので、ユーザーテストでもサイトの階層が分かりやすいとの声をいただいています。 ・・・中略・・・ いわゆるパンくずリストは、ユーザーテストをやっていると、画面を見ているユーザーにも意外とその意味が分からないという人が多いんです。確かに、ヘッダーにいきなり「ホーム>>ニュース>>過去記事」なんて書いてあっても初めて見た人はなんだろう?と思いますよね。 そこで、少しでも分かりやすくするために一番最初に「現在位置」と入れてみました。

なるほど確かに、インフォアクシアのソースは既にそうなっていました・・・ってそれは本人ですから当たり前ですよね。インフォアクシア式のやり方の他に、私は以下のマークアップを思いつきました。

<dl id="locus">
<dt>現在位置:</dt>
<dd>ホーム <img src="/common/img/icon_arrow.gif" alt="の中の" /></dd>
<dd>キャンペーン <img src="/common/img/icon_arrow.gif" alt="の中の" /></dd>
<dd>おにぎり100円セール</dd>
</dl>

dl要素を使用したやり方です。「現在位置」をdt要素に指定しています。ただ、ヴィジュアルデザインの都合上、「現在位置」表示を入れられない場合、どうするか。

(私の現在の仕事のように、既に決定されているヴィジュアルデザインをコーディングするという作業の場合、デザイナーと事前に打ち合わせておかない限り、ヴィジュアルデザインに「現在位置」表示が入っていることはまずないでしょう。)

こういった場合、dt要素に position:absolute を指定するなどして、画面外に飛ばしてしまいます。通常のブラウザでは見ることができなくとも、音声ブラウザでは読み上げられるはずです。

ただ、不覚にも私は音声ブラウザを利用したことがないので、dl要素を使用したマークアップと、インフォアクシ式のp要素を使用したマークアップが、それぞれどのように読み上げられるかがわかりません。

また、パンくずリストに付ける適切な id は何か、こちらもリサーチしてみました。インフォアクシアでは id="breadcrumbs" で「パンくず」をそのまま英語化したものです。また、CSS HappyLifeさんのこちらの記事(もう、class名やid名で悩まないんだからっ!!)では以下のようなご紹介があります。

パンくずっぽいの
topicpath
topic-path
topicPath
pan
pankuzu

・・・がどれもいまいちピンとこなかったので、その筋のサイトをいくつか続けて見て行ったところ、ありました。カッコイイのが。アックゼロヨンid="locus" です。

Infoseek マルチ辞書で「locus」をひいてみると 場所, 所在地; 【遺伝】遺伝子座; 【数】軌跡. とあります。これだ!と思いました。

パンくずリストは大概がサイトのメインコンテンツより上にあるものであるだけに、テキトーにマークアップしてしまうのはアクセシビリティの観点から避けたいところです。

エラスティックレイアウトを採用してみました

当サイトのレイアウトにはエラスティックレイアウトという手法を使いました。コンテナ要素の幅をem単位で指定しています。該当部分の記述は以下の通り。

div#container {
width: 90%;
max-width: 60em;
min-width: 46em;
margin: 0 auto;
}

コンテンツ全体を囲む div#container に対して max-width と min-width をem単位で指定しています。そうすることで、ブラウザで文字サイズを変更すると div#container の幅が変わるようになります。なお、 max-width/min-width プロパティに対応していないIE6以前などのブラウザでは単に width:90% になるだけです。

また、エラスティックレイアウトで2カラムを実現するためにネガティブマージンをレイアウトに使っています。ネガティブマージンというのは文字通り、マイナス値を指定した margin プロパティのこと。

div#main {
float: left;
width: 100%;
margin: 0 -16em 20px 0;
}
div#sidebar {
float: right;
width: 15em;
margin-bottom: 30px;
}

div#sidebar の幅が15emで、残りの領域は div#main という割り当てとなっています。div#sidebar の width:15em に対して div#main の右 margin:16em 。差分の1emは間のマージン。これだけだと、div#main の右端が div#sidebar に潜ってしまうため、div#main の中身のブロック要素に右 margin を設定します。

div.entry {
margin: 0 16em 30px 0;
}

これで完成。

なお、このレイアウトには以下のサイトを参考にさせていただきました。
2xup.org: 一行あたりの文字数を制限する elastic layout (エラステックレイアウト)
Alternative Design Project: デザインテンプレート1110とネガティブマージン