coding
コンテンツより大きい画像をキレイに中央配置するcssテクニック3選
コンテンツ幅よりも大きい画像を配置し、ウィンドウがコンテンツ幅より小さい時にだけ横スクロールバーを出す方法です。
今回は主な方法を3パターンご紹介します。配置したい画像や他の要素のスタイルによって使い分けてみてください。
よくある失敗例
まずはよくある失敗例をご紹介します。こんな風になってしまったことはありませんか?
- コンテンツ幅ではなく、画像の幅で横スクロールバーが出てしまう……。
- コンテンツ幅からはみ出す部分が表示されない……。
- ウィンドウを縮めると背景部分がずれてしまう……。
- そもそも横スクロールバーが表示されない……。
こんな大変な状態とは無縁の、キレイなコーディングの方法を見ていきましょう!
達成したい条件
- コンテンツ幅より大きい横幅の画像を配置
- 画像は左右中央に配置
- ウィンドウ幅を大きく(小さく)しても、画像の位置がずれない
- ウィンドウ幅がコンテンツ幅より小さい時にだけ横スクロールバーを表示
今回使用する画像はこちらです。
また、今回のサンプルでは分かりやすいように
- 画像の横幅は1200px
- コンテンツ幅は1000px
としています。
つまり、画像がコンテンツの左右から100pxずつはみ出し、ウィンドウ幅が1000px未満の時に横スクロールバーが表示されるということですね。
なお、見やすいようにmargin、padding、背景色を適宜つけています。
例では#wrapperが黄色、#mainimgがピンク色の背景です。
方法1: 背景画像と画像に分ける
配置したい画像を1200px幅の背景画像と中央1000px以内の画像に分けます。例えば今回は、背景画像と画像(透過png)に分けてみました。
コードは以下の通りです。
html
1 2 3 4 5 6 |
<div id="wrapper"> <div id="mainimg"> <p id="mainimgIn"><img src="img/pic02.png" width="1000" height="581" /></p> </div><!-- / #mainimg --> <!-- コンテンツ部分 --> </div><!-- / #wrapper --> |
css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
html { overflow: auto; } body { min-width: 1000px; } #mainimg { padding: 77px 0 42px; background: url(img/bg01.png) no-repeat center 0; } #mainimgIn { width: 1000px; margin: 0 auto; } |
#mainimgの中央に背景画像を表示させます。そして、子要素#mainimgInの左右のmarginをautoにすることで画像も中央に表示させています。
ここで特に重要なのはbodyのmin-widthです。
これを指定しないと、ウィンドウ幅が1000pxより小さいときにbodyの幅がウィンドウ幅と同じになってしまうので、背景画像がずれて表示されてしまいます。さらには、横スクロールすると背景が途切れてしまいます。
この方法は、コンテンツ幅の内側の画像と背景が自然に分けられる場合や、画像の上にテキストが乗っている場合などに適しています。
逆に、コンテンツ幅で切ると不自然になってしまう場合や、デザインファイル上で画像と背景になる部分がレイヤー分けされていない場合には適していません。
方法2: 親要素をコンテンツ幅にする
配置したい画像の要素(例では#mainimgIn)の親要素(#mainimg)の幅をコンテンツ幅と同じにします。
html
1 2 3 4 5 6 |
<div id="wrapper"> <div id="mainimg"> <p id="mainimgIn"><img src="img/pic01.png" width="1200" height="700" /></p> </div><!-- / #mainimg --> <!-- コンテンツ部分 --> </div><!-- / #wrapper --> |
css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
html { overflow: auto; } body { min-width: 1000px; overflow: hidden; } #mainimg { width: 1000px; margin: 0 auto; } #mainimgIn { margin: 0 -100px; } |
#mainimgをコンテンツと同じ1000px幅にし、左右marginをautoにしてセンタリングします。そして子要素#mainimgInの左右marginを-100pxにすることで、左右に100pxずつ飛び出させます。
ここで重要なのはもちろん#mainimgInのネガティブマージン(負の値のmargin)です。
#mainimgからはみ出した分だけ、横スクロールバーが出る状態でウィンドウからはみ出します。
また、bodyの overflow: hidden; も横スクロールバーを正しく表示するために指定しましょう。
方法3: 親要素を擬似的に100%幅にする
#mainimgより上位の要素の#wrapperで幅を指定し、#mainimgの幅を擬似的に100%にします。
html
1 2 3 4 5 6 |
<div id="wrapper"> <div id="mainimg"> <p id="mainimgIn"><img src="img/pic01.png" width="1200" height="700" /></p> </div><!-- / #mainimg --> <!-- コンテンツ部分 --> </div><!-- / #wrapper --> |
css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
html { overflow: auto; } body { min-width: 1000px; overflow: hidden; } #wrapper { width: 1000px; margin: 0 auto; } #mainimg { margin: 0 -100%; padding: 0 100%; } #mainimgIn { margin: 0 -100px; } |
html及び#mainimgInのスタイルは方法2と同じです。
#wrapperの幅を1000pxに指定してセンタリングし、中の#mainimg、#mainimgInをともにはみ出させています。
#mainimgに指定されているmarginとpaddingはどちらもパーセント指定されていますが、これは#mainimg自身の幅が基準になるので
1 2 3 4 |
#mainimg { margin: 0 -1000px; padding: 0 1000px; } |
と記述しているのと同じことになります。
marginとpaddingで符号が違うだけの同じ値を指定することが重要です。
この方法は、#mainimgの部分に別の横幅いっぱいの背景画像を入れたい場合にとても便利です。余分なブロック要素で囲む必要がなくなりますね。
ですが、今回の場合だと、#mainimgの幅はpaddingを合わせて 1000px + 100%(1000px) × 2 = 3000px しかないので、幅3000pxを超える解像度のディスプレイでは背景画像が切れてしまいます。
対応したい解像度に合わせて、margin・paddingの指定を-100%(100%)から-200%(200%)に変更するなどしましょう。
最後に
コンテンツより大きな画像というのはほとんどが、ページ内でまず最初に目に入るものかと思います。それだけに、しっかりキレイに表示したいですね。
今回は3パターンの方法をご紹介しましたが、それぞれに適した場面、適さない場面があります。その時々で一番使いやすそうな方法を試してみてください。
また、marginによるセンタリングやネガティブマージンが登場しましたが、marginの特徴についておさらいしたい方は、こちらの記事も読んでみてください。