【HTML/CSS】ウィンドウ(親)の余った領域の高さいっぱいに子要素を広げつつ、ウィンドウサイズが小さくなったら子要素がまずスクロール可能になるようにする【React】

【HTML/CSS】ウィンドウ(親)の余った領域の高さいっぱいに子要素を広げつつ、ウィンドウサイズが小さくなったら子要素がまずスクロール可能になるようにする【React】

親要素の高さはウィンドウいっぱいに、そして複数の子要素のうち1つだけをウィンドウの余った高さ領域いっぱいにします。
そしてその子要素は、孫要素に高さに関わらずウィンドウの高さが縮んだら縮んでスクロールバーが表示されるようにします。

説明が少し分かりづらいので画像を使って説明します。

以下のように各要素をレイアウトして、「data1~」がある領域はウィンドウ(ブラウザ)の高さに合わせて広がるようにしつつ、
2023-03-29_1.png

ウインドウを縦に縮めた場合に↓のようになるのではなく、
2023-03-29_3.png

↓の様になるようにします。
2023-03-29_2.png

ポイント

  • flexboxを使う
  • flex: 1を使う
  • overflow: autoを使う
  • うまくいかない場合はmin-height: 0を試してみる

実装例

以下は最初に添付した画像の内容を実装したReactのコードです。
Reactのコードといっても、「Root」や「FlexBox1」等はReactとemotionでstyleをあてているだけで、divにCSSを設定するのと同様です。

下部に記載されている「…= styled.div`…」あたりのコードと同等の記述をCSSで行えば、純粋なHTML+CSSで同じレイアウトを再現できるはずです。

import styled from "@emotion/styled";
import { FunctionComponent } from "react";

const LayoutWithFlexboxPage: FunctionComponent = () => {
  return (
    <Root>
      <FlexBox1>
        Top
      </FlexBox1>
      <FlexBox2>
        <ul>
          <li>data1</li>
          <li>data2</li>
          <li>data3</li>
          <li>data4</li>
          <li>data5</li>
          <li>data6</li>
          <li>data7</li>
          <li>data8</li>
          <li>data9</li>
          <li>data10</li>
        </ul>
      </FlexBox2>
      <FlexBox1>
        Bottom
      </FlexBox1>
    </Root>
  );
};

const Root = styled.div`
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  height: 100dvh;
  padding: 20px;
  background-color: lightblue;
`;

const FlexBox1 = styled.div`
  background-color: lightcoral;
  display: flex;
`;

const FlexBox2 = styled.div`
  background-color: lightgreen;
  display: flex;
  flex: 1;
  overflow: auto;
`;

export default LayoutWithFlexboxPage;

以上です。

補足

  • MUI等のBoxを使用する場合、うまくいかなければ上記の例でいうところの「FlexBox2」に「min-height: 0」を指定してみてください。
  • 親要素(Root)の高さは「100%」でもいいですが、さらに親の要素にも「height: 100%」が設定されていないと期待した振る舞いをしないことがあるため「height: 100dvh」を指定しています。

Share this post