前回のエントリーで、CSSで画面全体に対して天地中央に配置するテクニック(1)として定番のテクニックをご紹介しました。今回は前回の手法の問題点を解決する別のテクニックをご紹介したいと思います。
定番テクニックの問題点のおさらい
定番のテクニックである「絶対配置+ネガティブマージン」にはコンテンツ表示上の大きな問題があります。それは、ブラウザの表示スペース(つまりbodyの大きさ)がコンテンツ表示領域(divなど)よりも狭い場合、コンテンツの全体が表示されないと いうことです。
これをわかりやすく説明するために、ブラウザで表示した例を見てみましょう。ソースは前回のエントリーでサンプルとして挙げたものを少し改変します。
HTMLは以下のようになります。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="stylesheet" href="base.css" type="text/css" media="all" />
<title>hoge</title>
</head>
<body>
<div id="content">
<p><img src="https://www.blades.co.jp/new/images/slideshow_blades_js.jpg" width="667" height="269" alt="" /></p>
</div>
</body>
</html>
CSSは以下のようになります。
html,body{
width: 100%; height: 100%;
margin: 0; padding: 0;
background-color: #ffffff;
}
div,p{
margin: 0; padding: 0;
}
#content{
position: absolute;
top: 50%; left: 50%;
width: 670px; height: 270px;
margin-top: -135px; margin-left: -335px;
border: 4px solid #000000;
}
これをFirefox3.6で見てみると以下のように表示されます。

表示スペースがコンテンツ領域よりも狭い場合にはスクロールバーが出ますが、左と上に切れている部分は見ることができなくなってしまいます。
解決方法 ダミー要素+ネガティブマージン+float
この問題を解決するためにまず原因を探ってみましょう。一番の問題は、#contentというコンテンツ表示領域に対して絶対配置を指定していることです。この指定のためにブラウザの表示スペースからはみ出した部分が表示されなくなってしまっています。
そこで絶対配置を使わない方法を考えます。#contentのスタイル指定から、絶対配置とネガティブマージンの部分を削除します。
base.cssのソースは以下のようになります。
html,body{
width: 100%; height: 100%;
margin: 0; padding: 0;
background-color: #ffffff;
}
div,p{
margin: 0; padding: 0;
}
#content{
width: 670px; height: 270px;
border: 4px solid #000000;
}
この段階では以下のように表示されます。

次に左右中央に表示されるようにbodyと#cotentにスタイル指定を追加します。
base.cssのソースは以下のようになります。
html,body{
width: 100%; height: 100%;
margin: 0; padding: 0;
background-color: #ffffff;
text-align: center;
}
div,p{
margin: 0; padding: 0;
}
#content{
width: 670px; height: 270px;
margin: 0 auto;
border: 4px solid #000000;
}
この段階では以下のように表示されます。

さて、このままでは天地に対して中央に表示させる術がありません。
そこで#content単独で天地中央に表示させることはあきらめます。代わりに#contentを外側から引き寄せるようなイメージのダミー要素をHTML上に新たに追加します。index.htmlに追記して以下のようにします。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Style-Type" content="text/css" /> <meta http-equiv="Content-Script-Type" content="text/javascript" /> <link rel="stylesheet" href="base.css" type="text/css" media="all" /> <title>hoge</title> </head> <body> <div id="dummy"></div> <div id="content"> <p><img src="https://www.blades.co.jp/new/images/slideshow_blades_js.jpg" width="667" height="269" alt="" /></p> </div> </body> </html>
続いて、新たに追加した#dummyというダミー要素に対してブラウザ表示スペースの50%の高さになるようにスタイル指定を追加します。また、ダミー要素がどのように表示されるのかを分かりやすくするために幅を5pxに、背景色を赤にします。
base.cssは以下のようになります。
html,body{
width: 100%; height: 100%;
margin: 0; padding: 0;
background-color: #ffffff;
text-align: center;
}
div,p{
margin: 0; padding: 0;
}
#dummy{
width: 5px; height: 50%;
background-color: #ff0000;
}
#content{
width: 670px; height: 270px;
margin: 0 auto;
border: 4px solid #000000;
}
この段階では以下のように表示されます。

この時、#contentの上辺はブラウザ表示領域の高さに対して50%の位置にあります。つまり上方向に#contentの高さの半分だけ移動すれば天地中央に表示されることになります。
#contentにスタイル指定してもいいのですが、ここでは#dummyに指定をまとめることにしましょう。
base.cssに追記して以下のようにします。
html,body{
width: 100%; height: 100%;
margin: 0; padding: 0;
background-color: #ffffff;
text-align: center;
}
div,p{
margin: 0; padding: 0;
}
#dummy{
width: 5px; height: 50%;
margin-bottom: -135px;
background-color: #ff0000;
}
#content{
width: 670px; height: 270px;
margin: 0 auto;
border: 4px solid #000000;
}
この段階では以下のように表示されます。

これで完成!?と思ってしまいそうですが、念のためブラウザ表示スペースを小さくしてみます。

#contentの左側が切れる現象は解消されていますが、上にはみ出た部分が以前と同じように表示されていません。
ブラウザの表示スペースに余裕がない場合には、ネガティブマージンが効かないようにできないでしょうか?
#dummyに対してfloat:leftを指定してみます。
html,body{
width: 100%; height: 100%;
margin: 0; padding: 0;
background-color: #ffffff;
text-align: center;
}
div,p{
margin: 0; padding: 0;
}
#dummy{
float: left;
width: 5px; height: 50%;
margin-bottom: -135px;
background-color: #ff0000;
}
#content{
width: 670px; height: 270px;
margin: 0 auto;
border: 4px solid #000000;
}
この段階では以下のように表示されます。

うまくいきました!上にはみ出ずにきちんと表示されています。
しかし実はこのままではIEで常に廻り込みがされた状態になってしまい、天地中央に表示されません。そこで#contentに対してclear:leftを指定し、廻り込みを解除するようにします。
base.cssは以下のようになります。
html,body{
width: 100%; height: 100%;
margin: 0; padding: 0;
background-color: #ffffff;
text-align: center;
}
div,p{
margin: 0; padding: 0;
}
#dummy{
float: left;
width: 5px; height: 50%;
margin-bottom: -135px;
background-color: #ff0000;
}
#content{
clear: left;
width: 670px; height: 270px;
margin: 0 auto;
border: 4px solid #000000;
}
これでbase.cssは完成です。
今回のCSSソースを実際に使用する場合には、#dummyの幅を1pxに、背景色をtransparentにするなどして見えないようにするといいと思います。
天地中央に関するトピックは随分前から語りつくされているので今さらな感じも否めませんが、今回ご紹介したテクニックは意外と知られていないのではないでしょうか?
定番テクニックの問題点を解決する方法としてなかなか使えると思いますので、機会があればぜひ使用してみたいですね。
追記@2010/09/15
今回ご紹介したテクニックの応用編を以下のアプリケーションで使用しています。
GeoLocator(ジオロケーター)製品紹介ページ
あわせてご覧ください。
