krzm.jp
黒住浩司 Webサイト

フレキシブルボックスのメロディ ― CSSの無知への傾向と対策

内容

第二幕
–CSS3–

とはいえ、あくまでもfloatの使用は、トリッキーな裏技です。宇宙大作戦のファンはトレッキー、ロシア革命の指導者はトロツキーで、似て非なるものです。そこで、こんなダジャレに惑わされず、ほんものの段組みを指定できるようにせねばとW3Cが決断したかどうかはわかりませんが、CSS3では、floatに代わるボックスの段組みレイアウト方法として、「フレキシブル ボックス レイアウト」という手法が導入される予定です。

予めお断りしておきますが、なるべく以降の解説は最後まで読んでください。なぜなら、いくつかのどんでん返しが含まれていますから。

フレキシブル ボックス レイアウトの指定

フレキシブル ボックス レイアウトの具体的な指定には、CSS2でも存在するdisplayプロパティに新たに追加された、boxという値を使います。このdisplay:boxを指定した要素の中に子要素として入れたブロックレベル要素が、横並びになります。

フレキシブルボックスレイアウトの図解1
親ボックスにdisplay:blockwを指定するだけで、子ボックスは横並びになる。ただし、親ボックスのoverflow値はvisibleでなければならない

先に、隔離ボックス構造が、後世に役立つと言ったのは、このためです。clearだけでfloatを制御していた場合、結局、display:boxためにdiv要素等を追加しなければなりません。それならば、初めから隔離ボックスがあったほうが、フレキシブル ボックスに流用できます。ただし、フレキシブル ボックスの場合、親ボックスのoverflowプロパティはvisibleでなければなりません。

また、フレキシブル ボックスには、入れ子ボックスの配置を制御するプロパティも用意されています。たとえば、box-directionプロパティでは、値をreverseにすると、横並びを逆順にできます。子ボックス側にbox-ordinal-groupプロパティを使って、数値で出現順を決めることも可能です。さらに、box-alignプロパティでは、子ボックスの垂直方向配置を指定できます。このプロパティの初期値はstretchになっているのですが、これは子ボックスの高さを一番大きいものに合わせて、引き伸ばしてくれます。ですから、フレキシブル ボックスの場合、何も指定しなければ子ボックスの高さは揃うことになります。フロート配置ではできなかったことが、事実上、親ボックスにdisplay:boxを指定するだけで実現されるわけです。

互換性対策

しかし、こんな便利なフレキシブル ボックスも、Internet Explorerでの対応は、10以降になります。IE 9以下では、フレキシブル ボックスは使えません。「だからIEは…」「IEは無視」なんて声もちらほらと耳にしますが、当krzm.jpは、そのような人として間違った方向には進みません。フレキシブル ボックスがダメならだめで、フロート配置との両立を図ります。そこでも、隔離ボックス構造が役立つのです。

例えば親ボックスA、子ボックスB、C、Dがある場合、次のように2つの指定を外部CSSファイルで用意します。

フレキシブル ボックス指定

#A {
 overflow:visible;
 display:-ms-box;
 display:-moz-box;
 display:-webkit-box;
 display:box;
 width:幅の値;
}
#B {
 width:幅の値;
}
#C {
 width:幅の値;
}
#D {
 width:幅の値;
}
フロート配置指定

#A {
 overflow:hidden !important;
 display:block !important;
}
#B, #C, #D {
 float:left;
}

そして、フレキシブル ボックス指定は、通常の方法(link要素)でHTMLファイルにリンクさせます。

なお、「!important」は、値の末尾に半角スペースを空けて付けることによって、そのスタイルの適用順位を最優先にします。overflow:hiddenとdisplay:blockは、フロート配置には欠かせないスタイルですから、IE 9以下では最優先で適用させるようにしています。もちろん、スタイルシートの構成を無視して、ただ!importantを乱用すると、すべてが最優先になり、結局、それは「どれも最優先ではない」ことになってしまうので、注意してください。!importantは、ここぞというところに、使わなければ意味がありません。まあ、Facebookで何にでも「いいね」をクリックしていると、それは「どうでもいいね」になってしまうのと同じです。

フロート配置指定のほうは、たとえば「iefix.css」というファイル名にした場合、以下のようにIEコメント分岐を使って、フレキシブル ボックス指定よりも後ろに記述します。

IEコメント分岐の記述

<!--[if lte IE 9]>
 <link rel="stylesheet" type="text/css" href="iefix.css" />
<![endif]—>

コメント分岐はIE専用の機能(最近はChromeもちゃっかり利用しているようですが…)で、コメント開始部分の条件指定により、IEのバージョンを判定します。「lte IE 9」の場合、IE 9以下となります。そして、対象となるIEはコメント内を有効なコードとして読み取ります。対象外のIEや他のブラウザは、すべてコメントとしてコード部分も無視します。この結果、IE 9以下のみ、フロート配置指定のスタイルが読み込まれることになります。

フレキシブルボックスレイアウトの図解2
IEコメント分岐によって、フレキシブル ボックスの配置と、フロート配置の指定を切り分ける

もちろん、IE9以下もフレキシブル ボックス指定を読み込みますが、後から読み込むiefix.cssによって、overflowとdisplayプロパティの指定が上書きされ、フロート指定に必要なスタイルが適用されます。また、floatプロパティは、フレキシブル ボックス指定には不要なので、フロート配置指定のほうにだけ記述し、やはりIE 9以下に適用させます。こうして、HTMLの構造はそのままで、IE 10はフレキシブルボックスで、IE 9以下はフロートで、ボックス配置のスタイルが適用されるようになるわけです。

Operaの問題

と、これで解決できればめでたし、めでたしなのですが、実はフレキシブル ボックスに対応していない他のブラウザがあります。そう、Operaです。もちろん、それ以外のブラウザも、古いバージョンでは非対応ですが、こうしたブラウザはIEとは違い、ユーザーが意図してインストールするので、随時新バージョンにアップデートしていると想定し、旧バージョンのことは考えなくても良い、と私は判断しています。ただ、その中のひとつであるOperaは、バージョン11.62でも、フレキシブル ボックスに対応していないのです。

そうなると、Opera対策も必要になってくるのですが、ちゃっかりもののChromeとは違い、Operaは毅然としてIE専用のコメント分岐には対応していません。他の方法で、フロート配置指定を適用するしかありません。すると、残っているのは、JavaScriptでOperaを判定し、スタイル適用を行う方法です。

ところが、頑固なOperaは、この方法すら拒絶します。IEなどでは、onload時にJavaScriptでoverflow:hidden、display:block、float:leftを対象の要素に適用すれば、フロート配置が適用されます。しかし、Operaは、これらをonloadで適用しても、反応しませんでした。

そこで、決断が必要になります。Operaを無視するか、それとも、フレキシブル ボックスは諦めるか。「Operaなんて、日本では誰も使っていないよ」などと、悪魔の囁きが耳を掠めるかもしれません。

それはそれとして、たとえば、ボックスの角を丸くするborder-radiusプロパティなどは、IE8以下が対応していませんが、このスタイルが適用されなかったとしても、レイアウトの大枠は維持されます。しかし、ボックスの横並びというレイアウトの根幹が崩れてしまうと、そうなってしまったブラウザでは、ページは非常に読みづらくなります。故に、krzm.jpでは、悪魔には耳を貸さず、フレキシブル ボックスの使用は当面、諦めることにしました。

1 2 3