OSSANS Project since 2020

「もし四十のおっさんがプログラミングを始めたらどう人生変わるのか」
このブログのメインテーマです
肩肘張らずにユルく、ときたま厳しくやっていきます
※プログラミング以外のことも書きます

CSS

2023.02.01(更新)

コード量激減!ブレイクポイントなしでレスポンシブ対応してみた【メリットしかない!】

アイキャッチ画像
CSS

レスポンシブ対応のブレイクポイントがややこしくて大変…。

今回はこんなお悩みに答えていきます。

本記事の内容

  • ブレイクポイントなしでレスポンシブデザインを実装する方法

本記事を対象とする方

  • フロントエンドエンジニアを目指す方
  • Webデザイナーを目指す方

この記事を書いている僕はプログラミング歴2年5ヶ月です。webエンジニアとして”社内転職”に成功しました。

レスポンシブデザインとは?

まずは簡単にレスポンシブデザインの説明をします。

Webページのレイアウトにおいて、「ビューポート」を意識したカラムレイアウトは非常に重要です。スマホの時の見え方、タブレットの時の見え方、PCの時の見え方。それぞれのスクリーン幅が異なる中で、メインコンテンツを極力見やすくしてUXを高めないと、ユーザーがWebページを離れる割合が高くなってしまいます。SEOを意識して優良なコンテンツを作り上げたとしても、意味がなく効果もありません。幸いなことに現在のCSS3にはメディアクエリという、言わば条件分岐が用意されていて、「ビューポート」の幅に応じて最適なカラムレイアウトデザインを設計することができます。これをレスポンシブデザインと言います。

サイドバー
※ユーザーの端末に応じてレイアウトを変えることができる

メディアクエリ(条件分岐)は、ブレイクポイントと呼ばれるレイアウトを変更する際の条件値を設定でき、例えば425px以下の時はAデザインを採用、426px以上の時はBデザインを採用という風に、柔軟にデザインを変更できる大変便利な仕様です。

一方で、CSS設計者においてはコンテンツありきの設計ではなく、「ビューポート」ありきの設計になります。ブレイクポイントが多くなればなるほど、コンテンツの内容を変更する必要があり、それはつまりコード量・工数が増えるという悩ましいものであることも事実です。メーカーによってサイズもマチマチだし、スマホやタブレットを横長で見る時はさらにややこしいです。少なくとも僕には「大変」というイメージがあり、そう感じる方も少なくないのではないでしょうか。

ビューポート幅
※端末によってビューポートの幅が様々なので悩ましいです

メディアクエリのブレイクポイントをいちいちCSSで設定しなくても、レスポンシブ対応できたらこれほど楽チンなことはありません。でもそんな方法あるのでしょうか…?

それがまたあるんです!しかもCSSのコード量はたったの28行です!次章でその実装方法を説明していきます。

実装方法

今回は2カラムレイアウトの場合で実装します。

結論から言うと次のコードを実行するだけで、ブレイクポイントなしにレスポンシブ対応が可能となります。

【HTML】

  1. <div class="parent">
  2.   <article class="main-child">
  3.     <p>
  4.       This is the main contents.
  5.     </p>
  6.   </article>
  7.   <aside class="sub-child">
  8.     <p>This is the sub contents.</p>
  9.   </aside>
  10. </div>

【CSS】

  1. .parent {
  2.   display: flex;
  3.   flex-wrap: wrap;
  4.   gap: 1rem;
  5. }
  6. .parent .main-child {
  7.   flex-basis: 0;
  8.   flex-grow: 999;
  9.   min-width: 50%;
  10. }
  11. .parent .sub-child {
  12.   flex-basis: 15rem;
  13.   flex-grow: 1;
  14. }
  15. @media not all and (-webkit-min-device-pixel-ratio: 0), not all and (min-resolution: 0.001dpcm) {
  16.   @supports (-webkit-appearance: none) and (not (translate: none)) {
  17.     .parent {
  18.       margin-top: 1rem;
  19.     }
  20.   }
  21. }
  22. @media not all and (-webkit-min-device-pixel-ratio: 0), not all and (min-resolution: 0.001dpcm) {
  23.   @supports (-webkit-appearance: none) and (not (translate: none)) {
  24.     .parent > * + * {
  25.       margin-left: 1rem;
  26.     }
  27.   }
  28. }

デモページは下記からご覧いただけます。

HTMLの説明は不要かと思いますが、メイン要素とサブ要素はarticle、asideでなくても構いません。ではCSSの解説をしていきます。ポイントは下記の通りです。

  1. main-childは親コンテナのスペースを占有させる
  2. main-childのmin-width: 50%;でしきい値をつける
  3. sub-childの幅をflex-basisで固定
  4. 親コンテナのgapにはSafari対策を施す

main-childは親コンテナのスペースを占有させる

  1. .main-child {
  2.   flex-basis: 0;
  3.   flex-grow: 999;
  4.   min-width: 50%;
  5. }

.main-child(メインコンテンツ)のflex-growの値は非常に大きい(999)ので、親コンテナ(.parent)の利用可能なスペースの全てを占有できるようになっています。

Check

flex-growとは?

親要素の空きスペースを子要素にどう割り振るかを設定するプロパティ

flex-grow – CSS: カスケーディングスタイルシート | MDN

flex-grow
※親要素に空きスペースがない場合は適用されません

main-childのmin-width: 50%;でしきい値をつける

ここが今回のテクニックの肝なんですが、min-width: 50%;で、main-childの幅が親コンテナの50%未満にならないようにしています。50%未満になってしまうくらい親コンテナの幅が小さくなった時は、強制的にメインコンテンツとサイドバーが縦並びになります。これが折り返しのしきい値となり、ブレイクポイントとなります。

  1. main-child {
  2.   flex-basis: 0;
  3.   flex-grow: 999;
  4.   min-width: 50%; /* 折り返しのしきい値 */
  5. }
折り返し
※min-widthを設定することでブレイクポイントが作れます
Check

min-widthとは?

要素の最小幅を指定します

min-widthで120pxを指定した場合、その要素の幅は120px未満にはならず120px以上になり、120pxを下回ることはなくなります

min-width – CSS: カスケーディングスタイルシート | MDN

sub-childの幅をflex-basisで固定

  1. .sub-child {
  2.   flex-basis: 15rem;
  3.   flex-grow: 1;
  4. }

.sub-childの幅の設定にはflex-basisを使い、flex-growで幅を伸張できるようにします。これは基本的にはflex-basisの幅を採用するけど、必要に応じて幅を伸ばすことができる、という意味になります。必要に応じて幅が伸びる時ってどんな時?それはmain-childとsub-childが縦並びになった時です。

Check

flex-basisとは?

対象となる子要素の初期の幅を指定します

子要素の伸張(flex-grow)、収縮(flex-shrink)、折り返しを有効にすることにより、利用可能なスペースの中で各子要素の幅ができるだけ初期値になるように調整されます

flex-basis – CSS: カスケーディングスタイルシート

親コンテナのgapにはSafari対策を施す

通常、サイドバーとメインコンテンツとの間には明確な隙間を入れることが多いです。それには親コンテナにgapを指定します。

  1. .parent {
  2.   display: flex;
  3.   flex-wrap: wrap;
  4.   gap: 1rem; /* 隙間を作る */
  5. }

このgapは垂直方向に並んだ時でも有効になります。

gapの設定
※gapで隙間を作る

ただし、このgapは古いSafariには効かないので、以下のような設定をしてあげます。

  1. @media not all and (-webkit-min-device-pixel-ratio: 0), not all and (min-resolution: 0.001dpcm) {
  2.   @supports (-webkit-appearance: none) and (not (translate: none)) {
  3.     .parent {
  4.       margin-top: 1rem;
  5.     }
  6.   }
  7. }
  8. @media not all and (-webkit-min-device-pixel-ratio: 0), not all and (min-resolution: 0.001dpcm) {
  9.   @supports (-webkit-appearance: none) and (not (translate: none)) {
  10.     .parent > * + * {
  11.       margin-left: 1rem;
  12.     }
  13.   }
  14. }

今回のまとめ

今回はブレイクポイントなしでサイドバーのレスポンシブ対応を実装する方法について紹介しました。最後まで読んで頂きありがとうございました。

main-childは親コンテナのスペースを占有させる

main-childにmin-width: 50%;を設定することで、レスポンシブ対応のブレイクポイントを作る

sub-childの幅をflex-basisで固定

親コンテナのgapにはSafari対策を施す

関連記事

  • CSS
    ブログアイキャッチ画像
    CSS

    【CSS】margin?position?要素の中央寄せで使うプロパティとは?

  • CSS
    ブログアイキャッチ画像
    CSS

    【備忘録】CSSセレクター、結合関連の書き方をまとめてみた。

CATEGORY カテゴリー別最新記事

  • CSS
    アイキャッチ画像
    CSS

    【CSS】margin?position?要素の中央寄せで使うプロパティとは?

  • Docker
    アイキャッチ画像
    Docker
    2022.10.03(更新)

    【簡単設定!】DockerでWordPressをローカル開発する方法

  • HTML
    アイキャッチ画像
    HTML
    2023.02.18(更新)

    【図解あり】aタグの入れ子ルールとHTMLの入れ子ルールを覚える方法

  • JavaScript
    アイキャッチ画像
    JavaScript
    2023.03.04(更新)

    【実例コードあり】覚えておきたいパララックスデザインの3つの基本

  • Python
    アイキャッチ画像
    Python
    2023.02.09(更新)

    【やらなきゃ損!】2日でできるPythonのExcelコピペ自動化!

  • Study
    アイキャッチ画像
    Study
    2023.02.16(更新)

    稼ぐために始めたプログラミングのこれまでの振り返り。勉強方法や役立った本も紹介。

  • web site
    アイキャッチ画像
    web site
    2022.11.26(更新)

    ページ表示速度アップ!npmでソースファイルを軽量化する方法【サクッと簡単!】

  • WordPress
    アイキャッチ画像
    WordPress
    2022.10.26(更新)

    【コピペ可】WordPressサイトをPWA化するためにService Workerを実装してみた。