よくあるレイアウトほど、落とし穴が深い

定番レイアウトがもたらす安心感

Webサイト制作では、よく見かける定番のレイアウトがあります。
たとえば「左にテキスト、右に画像、テキストエリアの下部にボタンを配置する」という、いわゆる王道の構成です。
今回の要件は次のとおりです。

  • 左側:見出し・説明文・CTAボタン
  • 右側:画像(今回はスライダー)
  • 補足:テキスト量に関わらず、CTAボタンは常に下部に固定して表示する

flex を使った「下付きボタン」の定番テクニック

この要件を満たすため、よく使われるのが flex を使ったレイアウトです。

  • 親要素を display: flex にして左右を横並びにする→高さを揃える
  • 左カラム(テキスト側)を flex-direction: column にする→縦積みにする
  • ボタンに margin-top: auto を指定する

この構成にすると、
テキスト量が増減しても、ボタンは常にカラムの一番下に配置されます。
実際にダミーテキストの量を変えて検証してみると、添付画像のように、

  • テキストが長くても
  • 短くても

どのパターンでもボタンはきれいに下付きになります。


「やっぱり flex は便利だな」そう感じる、よくある成功体験です。
しかし、このセクションがスライダーだったためか、思わぬ問題が起きました。

なぜかスライダーが巨大化する

ところが、表示を確認すると違和感がありました。

  • スライダーが異常にデカい
  • 左のテキストがギュッと押しつぶされている
  • 画面幅は十分あるのに、レイアウトが崩れている

flex レイアウトでは、コンテンツサイズ・比率指定・画像の実寸が絡むと、意図しない伸び方をすることはよくあります。(実際の画像は画質重視で2300pxほどあります)
ただ、ぱっと見で原因が分からない。
CSSを見直しても、致命的におかしな指定はなさそうでした。

原因は flex の指定だった

flex: 0 1 60%;
スライダー側に「デザインを考慮して60%くらいね」という軽い気持ちで指定していました。
しかし、これを 固定値 にすると、問題なく表示される。
flex: 0 1 600px;
……表示は直る。でも、それは負けた気がする。
レスポンシブ前提のコーポレートサイトで、固定幅は避けたい。
そこで追加したのが、
width: 60%;
これで、

  • スライダーが必要以上に拡大しない
  • テキストエリアも正しい幅を保つ
  • レスポンシブも問題なし

という、意図したレイアウトに収まりました。

flex は「割合」だけでは信用しすぎない

今回の学びはシンプルです。

  • flex-basis だけにレイアウトを委ねるのは危険
  • 特に、スライダーや大きな画像を持つ要素は要注意
  • 画像サイズや内部コンテンツによって、flex が「親のサイズをうまく掴めない」ことがある

width を明示することで、ブラウザに「ここまでだよ」と境界を教えるそれだけで挙動が安定するケースがあります。
よくあるレイアウトほど、「いつもの実装」で流してしまいがちですが、flex と画像とスライダーが揃ったときは、一度立ち止まる。
そんな教訓を、またひとつ積み上げた案件でした。

html

<section>
  <div class="row">
    <div class="col-left">
      <div>
        <h2 class="h2">
          ダミータイトル<span class="subttl">ダミーサブタイトル</span>
        </h2>
        <p class="txt">
          テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト(80)
        </p>
      </div>
      <a href="/" class="btn">詳細はこちら</a>
    </div>
    <div class="col-right">
      <div class="slider">
        <figure class="slide-img">
          <img src="https://placehold.jp/1000x600.png" alt="" />
        </figure>
        <figure class="slide-img">
          <img src="https://placehold.jp/1000x600.png" alt="" />
        </figure>
        <figure class="slide-img">
          <img src="https://placehold.jp/1000x600.png" alt="" />
        </figure>
      </div>
    </div>
  </div>
</section>

css

.row {
  display: flex;
  gap: 32px;
}
.col-left {
  flex: 0 1 40%;
  display: flex;
  flex-direction: column;
}
.col-right {
  flex: 0 1 60%;
  width: 60%;
}
.btn {
  display: inline-block;
  background-color: #000;
  color: #fff;
  font-size: 14px;
  font-weight: 500;
  padding: 8px 24px;
  text-align: center;
  text-decoration: none;
  transition: opacity 0.3s ease;
  margin-top: auto;
  max-width: 290px;
  width: 100%;
}

関連記事