【リキッド対応】CSSで要素を上下左右中央に配置する方法の実験
「ブラウザ(親要素)に合わせて子要素を上下左右中央配置にしたい」
というのは結構あったりすると思います。
今までは子要素(child)に
top、right、bottom、leftを0にして
marginをautoにすることで
上下左右中央に配置していました。
1 2 3 4 5 |
<div id="parent"> <div id="child"> <img src="/images/img.jpg" alt="" /> </div> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#parent { position: relative; min-height: 100vh; } #child { position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; width: 400px; height: 400px; } #child img { width: 100%; height: auto; } |
ですがwidthとheightの値を指定しなければ
中央に配置されないため
リキッド対応できません。。。
ブラウザが画像の幅より狭くなると当然はみ出ます。
子要素をリキッド対応にさせつつ
上下左右中央に配置することができないか実験してみました。
※今回はブラウザの横幅に対してのみの実験です。
①「top: 50%;left: 50%;」にしてみる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#parent { position: relative; min-height: 100vh; } #child { position: absolute; top: 50%; left: 50%; } #child img { width: 100%; height: auto; } |
%で指定してやればwidthとheightの指定は必要ありません。
これで万事解決!
と思ったのですが
全然なってない。。。(゚A゚;)
これは基準が「子要素の左上」に設定されているためです。
子要素の左上を高さ50%の位置にもってこようとするので、
少しずれた位置になってしまいます。
つまりは子要素の半分ずれているということになります。
②transformを一緒に使用する
子要素の中心を基準にするために
transformを使用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#parent { position: relative; min-height: 100vh; } #child { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } #child img { width: 100%; height: auto; } |
このプロパティは指定した子要素の大きさを基準にします。
真ん中にもってきたい子要素の高さが100pxで−50%を指定すれば
ちょうど子要素の半分(50%)、50px分位置を上にもっていきます。
中央になりました。
これで万事解決!!
と思ったのですが
ブラウザの横幅が子要素の画像の横幅の2倍以下になると
それに合わせて子要素の画像も縮小されていきます。。。(゚A゚;)
ブラウザの横幅が画像の横幅よりも短くなった時に画像を縮小させたいのです。
③画像をブラウザの横幅に合わせてリキッド対応させる
子要素に「width:100%;」、「max-width:800px;」、「text-align:center;」を追加、
imgの「width:100%;」を「max-width:100%;」に変更してみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#parent { position: relative; min-height: 100vh; } #child { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 100%; max-width: 800px; /* 画像横幅に合わせる */ text-align: center; /* これがないとブラウザの縦幅を縮めた時に画像が左上を基準に縮小される */ } #child img { max-width: 100%; /* maxにしないと画像の比率が変わる */ height: auto; } |
画像がブラウザの横幅に合わせてリキッド対応されるようになりました。
これで万事解決!!
と思ったのですが(またかよ)
EdgeとIE11でブラウザ幅を狭めていない状態でもスクロールバーが出てしまいます。。。
何でだよ。。。(゚A゚;)
よく分かりません(バグという話もありましたが)。。。(゚A゚;)
とりあえずIEは無視して
Edgeは何とか攻略したいと思います。
④right: 50%;bottom: 50%;transformは50%に変更でEdgeのバグ(?)を防止
調べてみたところ子要素のpositionをtopとleftではなく
bottomとrightに変更するのが良いそうなので試してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#parent { position: relative; min-height: 100vh; } #child { position: absolute; right: 50%; bottom: 50%; transform: translate(50%, 50%); width: 100%; max-width: 800px; /* 画像横幅に合わせる */ max-height: 400px; /* 画像縦幅に合わせる */ text-align: center; /* これがないとブラウザの縦幅を縮めた時に画像が左上を基準に縮小される */ } #child img { max-width: 100%; /* maxにしないと画像の比率が変わる */ height: auto; } |
Edgeで(IE11でも)スクロールバーが出なくなりました。
縦スクロールバーが出るとその分の横スクロールバーが出てきますが
Chormeでは出ないのでこれはブラウザのスクロールバーの解釈の違いとして仕方ないかと
(Edgeは画面の上にスクロールバーが乗っかる感じのようですね)。
⑤直接img要素にスタイルをあててみる
④まではimg要素の親要素(div)にスタイルをあてていましたが
直接img要素にスタイルをあててみました。
1 2 3 |
<div id="parent"> <img src="/images/gazou.jpg" alt="" id="child" /> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#parent { position: relative; min-height: 100vh; } img#child { max-width: 100%; height: auto; position: absolute; right: 50%; bottom: 50%; transform: translate(50%, 50%); } |
どのブラウザにも対応できてます。
スタイルの記述も少なく分かりやすいかも。
と思ったのですが(ラスト)
これだと「テキストを入れたい」とかになると対応できないですね。。。
う~む、なかなか簡単には理想の動きにはならないものですね。
とりあえず④を基本にして場合によって使い分けしていこうかと思います。
縦に関しては考えなくても良いかなぁ。。。
▼参考にさせていただきました。ありがとうございました。
この記事の投稿者
taka
Webサイト作ってます。
最近のモットー「決して無理をしないスタイル」
twitter: @taka_sbs