EVERY LAYOUTという書籍にMedia Queryを使わなくてもレスポンシブな2カラムレイアウトを実現する方法が紹介されてたので忘れないようにメモ。
Media Queryを使ってレスポンシブな2カラムレイアウトを作った場合
モバイルかデスクトップのどちらかをベースにレイアウトを作って、その後にMedia Queryを使ってどちらかのデバイスの値を上書くみたいな作りが一般的。
この方法だと端末ごとに上書きが発生してコードの可読性も悪くなる。
@custom-media --mq-desktop (min-width: 1024px);
.main {
width: 100%;
}
.aside {
width: 100%;
}
@media (--mq-desktop) {
.main {
width: calc(100% - 300px);
}
.aside {
width: 300px;
}
}
Media Queryを使わずに2カラムレイアウトを作る
flex-basis、flex-grow、flex-shrinkを組み合わせることでビューポート幅ではなくてコンテンツの利用可能なスペースに応じた折り返しを作れる。
flex-basis
width: 20rem
この宣言の場合はどんな状況でも幅は常に20remとなる。
flex-basis: 20rem
この場合、20remが 目標の幅
としてブラウザに提示することになる。20remにどれだけ近づけるかはコンテンツの内容によってブラウザが自由に計算してくれる。
flex-grow
flexアイテムの伸長率を整数で指定できる。
flexコンテナの幅からflexアイテムの幅を引いたスペースに対して割り当てられる。
flex-shrink
flexアイテムの縮小率を整数で指定できる。
flexアイテムの幅がflexコンテナの幅よりも大きくなってはみ出した場合のスペースに割り当てられる。
.container {
display: flex;
flex-wrap: wrap;
/* 左右同一の高さにする */
align-items: flex-start;
gap: 24px;
}
.main {
flex-basis: 0;
flex-grow: 999;
/* .asideと同じ幅になったら折り返す */
min-width: 50%;
}
.aside {
/* 広告が入るサイズで指定してみる */
flex-basis: 300px;
flex-grow: 1;
}
- .mainのflex-growの値を非常に大きく設定して利用可能なスペースを全て占領させる
- .asideのflex-basisの値は↑のスペースには含まれず、合計から差し引かれるので水平にレイアウトされる
- 閾値としてmin-widthを使用する。例の場合.mainが50%未満になると強制的に伸長して折り返す
- .asideにもflex-growが指定してあるので下に折り返した時に伸長する