こういうレイアウトをHTML/CSSで実現する

こういうレイアウトをHTML/CSSで実現するための備忘録です。

![20241217.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821654/45caa9e5-e4ad-3e48-555e-d9a64e5c3cab.png)

作成中のツールで実現したかったけれど、だいぶ悩んだので書き留めておきます。

上にいくつかUI（ボタンや説明文）が存在し、その下に縦幅いっぱいのテキストエリアがあるというレイアウトです。

まずはベースです。

```html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            box-sizing: border-box
        }

        body {
            margin: 0;
        }

        p {
            margin-block-start: 0;
        }

        .yokonarabi-buttons {
            display: flex;
        }

        .green-box {
            background-color: green;
        }

        .input-area textarea {
            background-color: yellow;
        }
    </style>
</head>

<body>
    <div class="green-box">
        <div class="ui-area">
            <p>山路を登りながら、こう考えた。</p>
            <div class="yokonarabi-buttons">
                <button>ボタン1</button>
                <button>ボタン2</button>
                <button>ボタン3</button>
            </div>
            <div>
                <label>何かの設定値: <input type="text"></label>
            </div>
        </div>
        <div class="input-area">
            <textarea></textarea>
        </div>
    </div>
    </div>
</body>

</html>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821654/cce64d69-6d33-98b6-eec3-f927417f650d.png)



# 全体の縦幅を広げる

大本になる入れ物を広げます。

```css
body {
    margin: 0;
    height: 100vh;
}
.green-box {
    background-color: green;
    height: 100%;
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821654/56f75f85-ef26-711b-cd2a-34b15ca49f74.png)


# Flexboxを利用する1段階目

オブジェクトの伸張には、flexを使用し、以下のようにします。

```css
.green-box {
    background-color: green;
    height: 100vh;

    display: flex;
    flex-direction: column;
}

.input-area {
    flex-grow: 1;
    display: flex;
}

.input-area textarea {
    background-color: yellow;
}
```

`green-box`クラスのdivへ`display: flex;`と`flex-direction: column;`を指定し、フレックスコンテナ化します。

すると、その子要素のdiv（`ui-area`クラスと`input-area`クラス）が、縦に並べられたフレックスアイテム化します。

さらに`input-area`クラスのdivへは`flex-grow: 1;`を指定すると、フレックスコンテナ内の分配可能な余白いっぱいに`input-area`クラスのdivが伸びます。

# Flexboxを利用する2段階目

で、さらに、`input-area`クラスへ`display:flex;`を指定すると、自身もフレックスコンテナ化します。

:::note
ここからが、よく理解していないのだが
:::

フレックスアイテムとなった`textarea`は、親コンテナのデフォルト設定の`align-items: normal;`で、`align-items: stretch;`相当が影響し、交差軸方向で伸張します。

https://developer.mozilla.org/ja/docs/Web/CSS/align-items

`flex-direction`もまたデフォルト設定の`row`であることから、ここでいう『交差軸』は画面上から下方向です。（誤解の無い適切な表現がわからない）

したがって、textareaは伸張します。

# そして、こうなる

最後にちょっと見やすいように`padding`を付け足して、完成です。

```css
.green-box {
    padding: 10px;
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821654/91a2d3e9-767f-5811-1b39-4e95a534e3a2.png)

必要なら、横方向もFlexboxを使って、伸張します。

```css
.input-area textarea {
    background-color: yellow;
    flex-grow: 1;
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821654/ece300e8-bf74-d1ca-24b7-16d584acd65c.png)

# 最後に

こういうレイアウトを使ったツールを使いたかったけれど、なかなか実現できずにいました。

しかし、ようやく実現しました。

Flexboxについての理解も多少深まりましたし、さらに開発を進めたいと思います。

ここまで、読んでいただきありがとうございました。