個人備忘録です。「ポイント」→「改善前コード」→「改善コード(1,2)」の流れで解説。
実際の実装方法は、以下見出しから。
改善コード1[画像を等比率]
改善コード2[画像とitem自体を等比率]
画面幅を狭めたとき...
- 小要素はみ出ないがコンテンツが要素が縦長になり不恰好になるのを改善したい。
- 画像の見た目が正方形っぽくなり違和感がでるのを改善したい。
ゴールは画面幅を狭めたとき、ボックスデザインやカードデザインが縦長になるのを防ぎ等比率でサイズが変わるように組む。
全く謎な方はコードを見る前に
以下、ポイントと手順概要をある程度理解できるまで何度か読むことをお勧めします。
ここを理解すると80%理解したようなもので繰り返し読むことでなんとなくイメージを掴めるかと思います。
(ホントは図解したかったですが..わかりにくかったらすみません...🙏)
ポイント
- widthやheight含め
%
の値は親要素を基準に算出される - paddingを%で設定しても同じく親要素のwidthが基準に算出される
- (例: padding-top:100%は、親要素のwidthの値と同じ)
手順概要
- 親要素に基準のwidthを設定(33%や4remなど画面幅で可変ならなんでもOK)
- 比率を維持したい小要素に
width:100%
とpadding-top: xx%
を設定 - padding-topの%値は「1.」の親要素のwidthを基準に算出される
-
親要素のwidthに対する%の割合でpaddingの余白
が入り見た目上、小要素の高さの役割をする - 必然的に画面幅で変化する親要素のwidthの値応じたの割合(%)で小要素の高さ(padding-top)も一緒に変動する
改善前コード
画面幅を伸縮させてもwidthだけ変わり、hightはそのままのパターン。
※ このソースコードを元に改善してくのでなんとなく理解していて実装方法を先に見たい方は改善コード1[画像を等比率]から見てください。


<div class="container">
<!-- item部分 -->
<div class="itemA">
<div class="itemA__img"></div>
<div class="itemA__desc">
<h3 class="itemA__ttl">item見出し</h3>
<p class="itemA__text">サンプルテキストサンプルテキストサンプルテキスト</p>
</div>
</div>
</div>
.itemA{
width: 30%; /* 親要素に対する30%の幅 */
height: auto; /* 小要素のheightに自動的に可変される */
}
.itemA__img{
width: 100%;
height: 15rem; /* heightを設定してるたため画面伸縮で正方形っぽくなる原因 */
background-image: url(../img/photo--1.jpg);
background-size: cover;
background-position: center;
}
itemの高さは小要素の高さに依存しているため画面幅に応じて縦長になる。
widthと無関係に高さが変わってしまう状態。
また、背景画像を敷いているdivが正方形っぽくなるので画像縮尺が変わったかのように見えてしまう。
改善コード1[画像を等比率]
itemの基本階層早見表
item
(containerの小要素)
┗ item__img
(itemの小要素で画像の要素)
┗ item__desc
(itemの小要素でitemA__ttlとitemA__textを小要素にもつ要素)
<div class="container">
<!-- item部分 -->
<div class="itemB">
<div class="itemB__img"></div>
<div class="itemB__desc">
<h3 class="itemB__ttl">item見出し</h3>
<p class="itemB__text">サンプルテキストサンプルテキストサンプルテキスト</p>
</div>
</div>
.itemB{
width: 30%; /* 重要 */
height: auto;
}
.itemB__img{
width: 100%; /* 重要 */
height: auto;
padding-top: 40%; /* 重要,追加: item自体の高さをpaddingで形成している */
background-image: url(../img/photo--1.jpg);
background-size: cover;
background-position: center;
}
- (親)
item
にwidth:100%
を設定 - (子)
item__img
にwidth:100%
とpadding-top:xx%
を設定
だけでOK。
(親)と(子)のwidthは両方ぴったり同じ。
その状態で(子)のpadding-topで(親)widthの割合のpaddingで高さが生じて等比率になる。
次の見出しの改善コード2[画像とitem自体を等比率]は
・item要素自体を等比率にする
・比率維持した要素内に小要素がある
場合で追加処理が必要なためサンプルを分けて載せてます。
改善コード2[画像とitem自体を等比率]
画面幅を伸縮させると画像要素とitem自体も等比率で伸縮するパターン。


itemの基本階層早見表
item
(containerの小要素)
┗item__content
(追加)
┗ item__img
(itemの小要素で画像の要素)
┗ item__desc
(itemの小要素でitemA__ttlとitemA__textを小要素にもつ要素)
<div class="container">
<div class="itemC">
<div class="itemC__content"> <!-- 階層を増やす -->
<div class="itemC__img"></div>
<div class="itemC__desc">
<h3 class="itemC__ttl">item見出し</h3>
<p class="itemC__text">サンプルテキストサンプルテキストサンプルテキスト</p>
</div>
</div>
</div>
</div>
/* 親要素(黄色線)に対して、30%の幅で可変 */
.itemC{
width: 30%;
height: auto;
overflow: hidden;
}
.itemC__content{
width: 100%;
height: auto;
padding-top: 80%; /* itemCのwidth30%の値の80%のpadding(=高さ)が確保される */
position: relative; /* 追加 */
}
/* ↓ item__contentの小要素達 */
.itemC__img{
width: 100%;
height: auto;
padding-top: 40%;
/* 比率維持された中身はpaddingのため
itemC__contentの小要素は全てposition必須 */
position: absolute;
top: 0;
left: 0;
background-image: url(../img/photo--1.jpg);
background-size: cover;
background-position: center;
}
.itemC__desc{
/* 比率維持された中身はpaddingのため
itemC__contentの小要素は全てposition必須 */
top: 52%;
padding: 1rem;
background-color: #ffe4e1; /* テキスト部分はレイヤがわかりにくいので便宜上背景色付けました */
}
@media only screen and (max-width: 900px) {
.itemC__ttl{font-size: 1.2rem;}
.itemC__text{font-size: 1.1rem;}
}
- (親)
item
にwidth:100%
を設定 - (子)
item__img
とitem__text
を囲うitem__content
を新たに追加しwidth:100%
を設定 - (孫)
item__img
にもwidth:100%
とpadding-top:xx%
を設定
処理① 親子関係の追加
その下準備を前提にitem__content
とitem__img
の2つを等比率にする必要あり。
item
と親子関係の追加したitem__content
の仕組みは...↓
- itemレイアウト自体の等比率を制御するためのpadding-topを設定するため
- (親)と(子)と(孫)のwidthはどれもぴったり同じため
item__img
にpadding-topを設定することで実質、item
のwidthに合わせたwidthの割合のpaddingで高さが生じて等比率になる。
処理② positionで要素位置の調整
比率維持はクリアしたのですが、画像やテキストの要素を囲ったitem__content
もpadding-topでコンテンツ内をpaddingで埋めることで比率維してます。
なので崩さないようにするためitem__img
とitem__text
はposition
で位置設定が必須です。