【CSSテク】ブロック要素の比率を維持しながら可変させる方法
にリースはお応えします!
皆さんこんにちは、リースブログ編集部です。
本日は、レスポンシブ対応でかなり使えるCSSテクニックをご紹介します。
目 次
高さ不明のブロック要素の比率を維持させる方法
レスポンシブで組んでいると、どうしてもブロック要素をそのままの比率を維持しながら可変させたいという要望が生まれます。
画像の可変は、width=”100%”を指定すれば画像の比率を維持しながら勝手にウィンドウサイズに合わせてサイズが変更されるので楽ですが、ブロック要素では高さ方向でつまづきがちですね。
【NG例】通常のレスポンシブ対応方法例
通常であれば、heightを指定しない限り、親ブロック要素は子ブロック要素のコンテンツによって高さが依存します。
具体的な例がこちら。
ブラウザのウィンドウサイズをグイングイン動かしてみてください。
一応コードはこちらから確認頂けます。
<div class="adjust-box"> <p>ブロック要素の中身です。ブロック要素自体は可変でサイズ変更されますが、ブロック要素の高さは、文章に依存して比率を保持していません。</p> </div>
.adjust-box { width:100%; background:#EEE; padding:15px; -webkit- box-sizing:border-box; box-sizing:border-box; } .adjust-box p { font-size:24px; line-height:1.5em; }
【完璧例】比率を維持しながら文字サイズも可変する対応方法
こちらが完璧な可変対応方法です。
ひとつブロック要素を入れ子にする必要がありますが、ウィンドウサイズに合わせてブロック要素が可変することが確認頂けます。
サンプルはこちら
コードは下記のような感じです。
コピペで使ってもらえると思いますよ。
<div class="adjust-box box-1x1"></div> <div class="inner"> <p>ブロック要素の中身です。比率を維持して可変することができます。</p> </div> </div>
.adjust-box { position: relative; width: 50%; height: auto; background: #EEE; } .box-1x1:before { content: ""; display: block; padding-top: 100%; } .inner { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } .adjust-box p { line-height:1.5em; }
可変ブロックの簡単なCSS解説
何故高さ方向も比率が維持されるのか?
CSSは、高さ方向にpaddingを%で指定した場合、基準値をwidth(100%)から取得する性質があります。
要するに、widthの値が変化すると、paddingの値も同じ量だけ変化するということ。
それを利用することで、widthが可変した時に、高さ方法のpaddingも一緒に移動するというギミックですね。
CSSの「高さpadding」の性質を知っていれば案外簡単です。
ということは、今回正方形(1:1)の比率固定での可変でしたが、別の比率も簡単に作ることが出来るということです。
後でサンプルがあるので、そちらも参考にしてください。
1:1以外の比率固定でも可変させてみよう!
<!-- 2:1 --> <div class="adjust-box box-2x1"> <div class="inner"> <p>ブロック要素の中身です。比率を維持して可変することができます。</p> </div> </div> <!-- 1:2 --> <div class="adjust-box box-1x2"> <div class="inner"> <p>ブロック要素の中身です。比率を維持して可変することができます。</p> </div> </div> <!-- 4:3 --> <div class="adjust-box box-4x3"> <div class="inner"> <p>ブロック要素の中身です。比率を維持して可変することができます。</p> </div> </div>
.box-2x1:before { content: ""; display: block; padding-top: 50%; /* 2:1 */ } .box-1x2:before { content: ""; display: block; padding-top: 200%; /* 1:2 */ } .box-4x3:before { content: ""; display: block; padding-top: 75%; /* 4:3 */ }
もう賢い人は気づいたと思いますが、
16:9の場合は、
9÷16×100=56.25%という具合ですね。
応用編
それでは、このブロック要素の比率維持と一緒に、別の要素を合わせて使ってみましょう。
「iframe(Youtube)」
最も頻繁に使う機会のある事例は何か?
そう聞かれた際に真っ先に思いつくのは、iframe、特に「youtube」の動画埋込APIだと思います。
WEBページ内に動画を埋め込む際、どうしても動画のアスペクト比を維持したままレスポンシブ対応したい、そういった事例はとても多いです。
そんな時にもこの方法が活躍します。
書き方は先ほどと同じです。
サンプル内で動画を二つ読み込んでいます。上は比率を維持して可変。
下はメディアクエリーで何とか高さ指定を切り替えています。
PCの方は動画を再生しながら画面サイズをを色々動かしてみてください。
<!-- 比率維持 --> <div class="box-1"> <iframe src="https://www.youtube.com/embed/任意の動画" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe> </div> <!-- メディアクエリーで対応 --> <div class="box-2"> <iframe src="https://www.youtube.com/embed/任意の動画" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe> </div>
.box-1 { position: relative; } .box-1::before { content: ""; display: block; padding-top: 56.25%; } .box-1 iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
「min-height」と「max-height」
「横幅に対して50%の比率で高さを維持したい」
でも画面サイズがものすごく大きくなった際には大きすぎてしまったり、画面サイズが小さくなった際は小さすぎてしまうことがよくあります。
例えば横幅が1920pxなら縦幅は960pxになってしまいますし、横幅が320px(iPhone5など)の時は160pxになってしまいますね。
レスポンシブでサイトを作る際はこういった問題点をメディアクエリーを使って対応することが多いわけですが、これらも「min-height」「max-height」を使用すればメディアクエリー無しで実装することができます。
「flex-box」
ブロック要素に対しての指定でしたが、もちろん「flex-box」が指定された要素にも使用できます。
画面幅の5分の1のサイズの正方形を並べる10個並べると、ご覧いただいたようなレイアウトも簡単に実装できます。
<!-- max-height と min-height を使用した例 --> <div class="box-1"> <div class="inner"> <p class="text">ブロック要素の比率維持と一緒に、「min-height」や「max-height」も指定してあげると、メディアクエリーも画像も無しでこんなことができてしまいます。</p> </div> </div> <!-- flex-box を使用した例 --> <div class="box-2"> <div class="inner"> <div>こ</div> </div> <div class="inner"> <div>ん</div> </div> <div class="inner"> <div>な</div> </div> <div class="inner"> <div>事</div> </div> <div class="inner"> <div>も</div> </div> <div class="inner"> <div>可</div> </div> <div class="inner"> <div>能</div> </div> <div class="inner"> <div>で</div> </div> <div class="inner"> <div>す</div> </div> <div class="inner"> <div>。</div> </div> </div>
// max-height と min-height を使用した例 .box-1 { position: relative; min-height: 320px; max-height: 720px; } .box-1::before { content: ""; display: block; padding-top: 50%; } .box-1 .inner { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } // flex-box を使用した例 .box-2 { display: flex; flex-wrap: wrap; } .box-2 .inner { flex: 0 0 20%; position: relative; } .box-2 .inner::before { content: ''; display: block; padding-top: 100%; } .box-2 .inner div { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } .box-2 .inner:nth-child(even) div { background: #eee; }
サンプルの中で行っている高さ方向にセンタリング(中央配置)に関しては別記事で解説しているので、是非参考に。
IE と Firefox で効かないことがある?
Internet Explorer と Firefox では、この方法で比率維持ができないことがあるようです。
「padding-top」を指定している要素の親要素をチェック!
もしこの方法で不具合が出た際は、「padding-top」を指定している要素の親要素の横幅(width)が指定されているか確認してみてください。
<div class="box-1"> <div class="inner"></div> </div>
.box-1 { // この場合こちらが親要素になるので、横幅(width)を指定してあげる。 width: 100%; position: relative; } .box-1::before { content: ''; display: block; padding-top: 56.25%; } .box-1 .inner { position: absolute; width: 100%; height: 100%; top: 0; left: 0; }
まとめ
まだまだ使い方次第で色んなレイアウトに応用できる方法ですので、皆さんも色々試してみてください。
参考になった方は「フェイスブック」「ツイッター」「はてブ」や「シェア」も宜しくお願い申し上げます。
リースエンタープライズはお客様と寄り添い、
お客様と共に一つの問題解決に取り組みます。
あなたのやりたい、叶えたいを、なんでもお聞かせください。
- 著者.
- リースエンタープライズ レジェンズ
- 社名.
- 株式会社リースエンタープライズ
- Twitter.
- https://twitter.com/wreathofficial
- Instagram.
- https://www.instagram.com/wreath_enterprise/
リースエンタープライズを創業時期から現在まで中心となって支えてきた人たちが残したブログやクリエイティブ作品、そして日々学んだデザインやマーケティングなどに関する教養をまとめています。