zz log

zaininnari Blog

floatによる固定幅+リキッドレイアウトで、HTMLと表示を逆にする。

検証ブラウザ

win:ie5.5〜8(IEtester3)、firefox3.5、opera9.6、safari3、chrome3

完成版

»floatによる固定幅+リキッドレイアウトで、HTMLと表示を逆にする

<div id="wrapper">
	<div id="header">
		<h1>ヘッダー</h1>
	</div>
	<div id="content">
		<div id="main">
			<div id="body">
				<h2>メイン</h2>
			</div>
		</div>
		<div id="sidebar">
			<p>サイドバー</p>
		</div>
		<div id="footer">
			<p>フッター</p>
		</div>
	</div>
</div>
#wrapper {
	width: 95%; /* センタリング用 */
	text-align: left;
	margin: 0 auto; /* センタリング用 */
	text-align: left;
}

#header {
	background-color: #FF9900;
}

#content {
	background-color: #666;
}

#main {
	float:right;
	width:100%;
	background-color: #00FF99;
}

#body {
	margin-left:190px;
	background-color: #CF0;
}

#sidebar {
	float:left;
	margin-left:0;
	margin-right:-166px;
	width:166px;
	background-color: #FFFF99;
}

#footer {
	background-color: #CC99FF;
	clear:both;
}

メインコンテンツの部分がサイドバーより先に記述している状態で、
左にサイドバー(固定幅)、右にメインコンテンツ(可変幅)を表現する(下記図)
はてなのCSSでこの方式が採られている。

○メリット

  • メインコンテンツの部分が先に記述することでSEO的に有利らしい。

×デメリット

  • 実装がちょっとめんどくさい
  • 余計なコードが入る(#body)
試行1(不完全)

深く考えずに実装しようとすると多分下記の様になる

<div id="wrapper">
	<div id="header">
		<h1>ヘッダー</h1>
	</div>
	<div id="content">
		<div id="main">
			<h2>メイン</h2>
		</div>
		<div id="sidebar">
			<p>サイドバー</p>
		</div>
		<div id="footer">
			<p>フッター</p>
		</div>
	</div>
</div>
#wrapper {
	width: 95%;
	text-align: left;
	margin: 0 auto;
	text-align: left;
}

#header {
	background-color: #FF9900;
}

#content {
	background-color: #666;
}

#main {
	float:right;
	background-color: #00FF99;
	margin-left: 190px;
}

#sidebar {
	float:left;
	margin-left:0;
	margin-right:-166px;
	width:166px;
	background-color: #FFFF99;
}

#footer {
	background-color: #CC99FF;
	clear:both;
}


メインコンテンツの部分が最低限の表示分だけ確保して左によってしまう。
(ちなみに、div,h2はdispaly:block)

試行2 試行1に#mainに「width:100%」を指定する(不完全)

うまくいかない。
ただし、メインコンテンツの部分が固定幅にする分には問題ない。

ie5.5 × センタリング無視
ie6 × センタリング無視、メインコンテンツの部分がmargin-left分だけはみ出る
ie7 × メインコンテンツの部分がmargin-left分だけはみ出る
ie8 × メインコンテンツの部分がサイドバーとかぶる(margin-leftを無視)
fx3 × メインコンテンツの部分がサイドバーとかぶる(margin-leftを無視)
opera9.6 × floatが無視される(カラム落ち?)
safari3
chrome3 × floatが無視される(カラム落ち?)
試行3 試行1においてメインコンテンツの部分のテキストをたくさんいれる(実用的ではない)


リキッドレイアウトなので、解像度が高いと、結局は試行1と同じ結果になる。

試行4 試行1において#sidebarのfloatをleftからrightにする(不完全)

試行2と同じ結果になる

ここまでのまとめ

残念ながら、
仕様からすると、当たり前な結果。

基礎編5 フロートの性質より引用:


フロートの前後のブロックボックスは、フロートが存在しないかのように流し込まれます。
  • ただし、フロートにつづく行ボックスはフロートの幅を確保するために幅が短縮されます。

対処法いろいろ

各種ブラウザに対応していたりして、これを思いついたのはすごい(要は、widthを200%にした後、50%で半分にして、marginを使って元の位置に配置している)。ただし、一見したところでは、なにをしているのか分かりづらい。

  • javascriptを使って、#mainに計算した固定幅を与える

javascriptが無効ならば効果がない

  • ブラウザの独自cssを仕様する

firefox3.5(?)以降ならば、試行1の#mainに「width:-moz-available;」を追加する。もちろん、firefox以外にはこの指定に類するものはない

  • css3の利用。ie6など古いブラウザが無くならない限り、利用は難しい。
  • #mainの子要素にmarign-left用のブロック要素を配置する。但し、余分な要素が入る

試行2がヒント

fx3 × メインコンテンツの部分がサイドバーとかぶる(margin-leftを無視)
試行5 #mainの子要素にmarign-left用のブロック要素を配置する

→完成版のソースコード

余分な要素(#body)が入るのがデメリット。一見したところ、意味の無いコードに見えるから余計困る。

ここまできて、今更なこと。

固定幅+リキッドレイアウト、かっこいい!と思って、始めたけど、
最近は、ネットブックの普及&大型解像度のディスプレイの出現を考えると、
固定幅+リキッドレイアウトは、どちらにとっても不幸になる。

ネットブック(低解像度) メインコンテンツの部分が狭くなる
高解像度 メインコンテンツの部分が間延びして、読みづらい。

1行で読みやすい文字量は、「句読点」が1個入る分量(26文字)が適当と、2段組で論文を書いた時、先生が言っていた。
ちなみに、googleはてなブックマークでは、固定幅+リキッドレイアウトだが、テキストには、「width:42em;」が指定されている。

固定幅が至上というわけではなく。要は「読み手が読みやすさ」が重要ってこと。
「min-width」&「max-width」、「width:●●em;」の利用も面白そう。