krzm.jp
黒住浩司 Webサイト

フレキシブルボックスレイアウトの構成

内容

Firefoxの問題

これで、めでたしめでたしのフレキシブルボックス化のはずなのですが、しかし、ここで問題を起こすのは、IE10でも、IE9以下でもなく、Firefoxなのです。

先の記事で解説したとおり、フレキシブルボックスレイアウトの仕様は、二転三転というか、まさに三転しました。そして、現時点でのFirefoxには、一番古い仕様が実装されています。

その現代から二代前、近世のフレキシブルボックスは、コンテナやアイテムにoverflow:hiddenが指定してあると、アイテム下部が途切れるほか、今回の場合はmain_contents内のレイアウトそのものが崩壊しました

Firefoxの問題点1
Firefoxでの表示。main内の配置が崩れてしまう。このレイアウト例では、overflow:hiddenが適用されていると、flex-direction:row-reverse(Firefoxの場合は-moz-box-direction:reverse)による順序の反転が機能していない。

すなわち、近世フレキシブルボックスは、overflow:visibleでなければならないのです。一方、近代・現代のフレキシブルボックスは、overflow:hiddenでも全く問題ありません。

では、overflow:visible(ブロックレベル表示のデフォルト)にしておけばよいのかというと、それではfloatレイアウトに支障をきたします。

さらに、topnavのフレキシブルボックス化で判明したのですが、アイテム側のサイズ指定単位に%を使用していると、Firefoxだけがそれを再現できず、アイテムはインライン表示と同様に、幅が無くなってしまいます。

Firefoxの問題点2
topnavのボタン(li要素)では、幅の指定が効かなくなる

もう、どうしようもありませんね。

近・現代政治は、ブルジョア民主主義の多数決原理を金科玉条としていますから、それに従えば、overflow:hiddenや%指定で大丈夫な大多数のブラウザーを是とし、民主主義的にFirefoxは葬り去られるべきでしょう。

もちろん私は、ブルジョア民主主義に拝跪しているわけではないので、本来なら少数派に味方しそうなところですが、所詮はFirefox相手です。ほったらかしにしておいても、いずれは“高速バージョンアップ”とやらで、いつの間にか対応しているかもしれません。

当サイトでは、Firefoxに対し、基本的にはほったらかしのスタンスを取っています。ほかにも、当サイトのトップページでもわかるように、CSS AnimationやTransitionの実行速度や表示品質は、Firefoxが最低です。最近、背景画像にSVGファイルを多用してみると、アニメーションだけでなくスクロール速度までもたつくようになりました。実際のところ、IE10が最も高速で、表示品質も最高です。

まあ、そんなFirefoxでも、少しは救いの手を差しのべてあげましょう。やはり、Webクリエイター気取りの連中が、犬も杓子もChromeへなびいていく御時勢では、Firefoxにも少しは、判官贔屓をしたくもなります。ただし、IE9以下と違って、コメント分岐の手法はFirefoxには使えないので、ブラウザーの特定にはJavaScriptを使用します。そして、フレキシブルボックスレイアウトのアイテム部分に、スクリプトを使ってfloatを適用させます。

問題は、JavaScriptがオフになっていると、フレキシブルボックス指定がかかってしまい、アイテム下部が途切れてしまうことになりますが、それは仕方がないでしょう。noscript要素で、警告でも入れておくしかありません。

そして、Firefoxが現代フレキシブルボックスに対応した暁に、このスクリプトを削除すればよいわけです。

なお、以前の記事で非対応と紹介したOperaは、ver. 12.14ではフレキシブルボックスに対応しています。しかも、後出しジャンケンのように勧告候補以降での対応なので、ベンダー接頭辞ただしOperaは、独自レンダリングエンジンの開発を中止し、Chrome等と同じWebkitを採用することを表明しているので、場合によっては今後、接頭辞-webkit-が必要になるかもしれませんは必要ありません。

まとめ

以上のように、Firefox問題を除いては、フロートコンテナ/フロートアイテムのボックス構成をきちんと作っておくことで、フレックスコンテナ/フレックスアイテムへの移行は、容易いことなのです。また、その構成は、そのままIE9以下の互換性対策にもなるのです。

ただし、当サイトのようなボックス構成では、フレキシブルボックスよりもグリッドレイアウトの方が向いているかもしれません。グリットレイアウトは、IE10だけが現状では対応しています。問題は、他のブラウザーやIE9以下との互換性を、どう担保するかです。その点でも、フロート構成に流用できるフレキシブルボックスのほうが、当面は融通が利くといえるでしょう。

サンプル ソースコード

サンプルコード1

/* フレキシブルボックスのCSSコード */
div {
	overflow:hidden;
}
/* topnav */
#topnav ul {
	display:-ms-flexbox;
	display:-webkit-flex;
	display:flex;
	-ms-flex-pack:center;
	-webkit-justify-content:center;
	justify-content:center;
}
/* 主要記事 */
#contents {
	display:-ms-flexbox;
	display:-webkit-flex;
	display:flex;
}
#main {
	display:-ms-flexbox;
	display:-webkit-flex;
	display:flex;
	-ms-flex-direction:row-reverse;
	-webkit-flex-direction:row-reverse;
	flex-direction:row-reverse;
}
サンプルコード2

/* IE9以下用 */
/* topnav */
#topnav ul {
	display:block;
}
#topnav li {
	float:left;
}
/* 主要記事 */
#contents, #main {
	display:block;
}
#main_contents, #sidebar_frame {
	float:left;
}
#articles, #footnote {
	float:right;
}
サンプルコード3

//Firefox用JavaScriptコード
(function () {
	if (!(navigator.userAgent.indexOf("Firefox") != -1)) {
		return;
	} else {
		if (!document.addEventListener) {
			alert("ページを正しく表示できません。最新のFirefoxを使用してください。");
			return;
		} else {
			document.addEventListener("DOMContentLoaded", function () {
				var OBJs = document.querySelectorAll("#topnav li, #contents > div");
				for (var i=0; i<OBJs.length; i++) {
					OBJs.item(i).style.cssFloat = "left";
				}
				OBJs = document.querySelectorAll("#main > div");
				for (i=0; i<OBJs.length; i++) {
					OBJs.item(i).style.cssFloat = "right";
				}
			}, false);
		}
	}
}) ();
1 2 3