92009


外側に大きさの決まってるブロック要素が合って  
その中に bootstrap の card を配置して  
中に大きなコンテンツがあっても card 内でスクロールしたいです

* * *

以下のように max-height 100% を内側に順に指定していったのですが  
card-body のところで max-height がきかずにはみ出してしまいます

container の max-height を height にかえれば収まるんですが  
内側の要素が小さい場合それにあわせて card も小さくしたいです

なぜ height だと内側に収まるのに max-height だときかないのでしょうか

[code]

    .container {
      max-height: 100%;
    }
    
    .card {
      max-height: 100%;
    }
    
    .card-body {
      overflow: auto;
      max-height: 100%;
    }
[/code]

[code]

    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"/>
    
    <div style="height: 100px; background-color: #eef; padding: 1ex;">
      <div class="container">
        <div class="card">
          <div class="card-body">
            <div style="height: 200px; background-color: #fee">
          </div>
        </div>
      </div>
    </div>
[/code]

height: 100% で収まる

[code]

    .container {
      height: 100%;
    }
    
    .card {
      max-height: 100%;
    }
    
    .card-body {
      overflow: auto;
      max-height: 100%;
    }
[/code]

[code]

    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"/>
    
    <div style="height: 100px; background-color: #eef; padding: 1ex;">
      <div class="container">
        <div class="card">
          <div class="card-body">
            <div style="height: 200px; background-color: #fee">
          </div>
        </div>
      </div>
    </div>
[/code]


CC BY-SA 4.0
2022-11-01T12:45:58.997
91934
2022-11-05T05:34:35.690
2022-11-02T09:58:51.247
question
css
max-height がきかない


`max-height`
プロパティによる高さの制約は子要素の内容によって仮の高さが決定された後に適用されます。さらにパーセンテージ値は包含ブロックの高さからの百分率となりますが、包含ブロックの高さが決定していない場合、パーセンテージ値は
`auto` として扱われます。これらの要因により `max-height` プロパティのみではカードからコンテンツがはみ出します。一方で
`.container` へ `height` プロパティを設定すると、包含ブロックの高さが決定する上に、 `flex-shrink`
プロパティが動作しフレックスアイテムが縮小されるため、スクロールコンテナが生成されます。

蛇足ですが、 `flex-direction` プロパティを `row` にすると `flex-shrink`
プロパティが適用されないため、一見するとコンテンツがはみ出してしまうように見えるかもしれません。しかしこの場合でも、 `align-items`
プロパティが `stretch` に設定されているため、はみ出すことはありません。

* * *

以下で 2 つのコードではどのような手順で高さが決定されているかを説明します。しかしこれは厳密ではないので、あくまでも参考として読み進めてください。

### `max-height` プロパティのみを使用した場合（1つ目のコード）

  1. 最上位の `div` 要素の高さは `100px` です。
  2. 次に `.container` の高さを決定します。 
    1. まず `max-height` を考慮せずに高さを決定します。`.container` の `height` は `auto` で、ブロックレベルの子要素 `.card` を持っています。このため `.container` の高さは、フロー内の最後の子要素までの高さとなります。つまり、要素の高さは再帰的に定義されるため、`.container` の高さを決定するには子要素 `.card` の高さを決定する必要があるということです。 
      1. `.card` の `height` は `auto` で、フレックスレベルの子要素 `.card-body` を持っています。このため、 `.card` の高さは子要素 `.card-body` のコンテンツサイズにより決まります。 
        1. `.card-body` の高さは子要素の高さが 200px で `padding` が 2rem のため、 `200px + 2rem` となります。ここで `.card-body` には `max-height` プロパティによる制約がありますが、この時点では包含ブロックの高さが決まっていないため、`max-height` プロパティの値は `auto` として扱われ高さが決定します。
      2. `.card` の高さは `.card-body` の高さの `200px + 2rem` となります。ここでも `max-height` は同様に `auto` として扱われます。
    2. `.container` の高さは `.card` の高さの `200px + 2rem` となります。ここで `.container` の高さは `max-height` プロパティにより 包含ブロックの親要素の高さ`100px - 2ex` に制約されます。`overflow` プロパティは `visible` なので、子要素は `.container` からはみ出します。

### `height` プロパティを使用した場合（2つ目のコード）

  1. 最上位の `div` 要素の高さは `100px` です。
  2. 次に `.container` の高さを決定します。`.container` の `height` プロパティの値は `100%` なので、`.container` の高さは `100px - 2ex` となります。
  3. 次に `.card` の高さを決定します。 
    1. `.card` の `height` プロパティの値は `auto` で、フレックスレベルの子要素 `.card-body` を持っています。このため、 `.card` の高さは子要素 `.card-body` のコンテンツサイズにより決まります。つまり `.card-body` の高さを決定する必要があります。 
      1. `.card-body` の高さは子要素の高さが 200px で `padding` が 2rem のため、 `200px + 2rem` となります。この時点では包含ブロックの高さが明らかではないため、`max-height` プロパティの値は `auto` として扱われます。
    2. `.card` の高さは `.card-body` の高さの `200px + 2rem` となります。ここで `max-height` プロパティの値は親要素 `.container` の高さとなり、この制約のもとで `.card` の高さは `100px - 2ex` となります。
  4. フレックスコンテナ `.card` の大きさが制約されたため、それに合わせてフレックスアイテム `.card-body` の高さは `100px - 2ex` に縮小されます。これは `.card-body` に設定されている `flex-shrink` プロパティの値が `1` となっているためです。
  5. 以上によりスクロールコンテナが生成され、カード内のコンテンツが収まるようになります。

* * *

参考：

  * [Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification](https://www.w3.org/TR/2011/REC-CSS2-20110607/)
  * [CSS Flexible Box Layout Module Level 1](https://www.w3.org/TR/css-flexbox-1/)


CC BY-SA 4.0
2022-11-05T05:27:15.640
92009
2022-11-05T05:34:35.690
2022-11-05T05:34:35.690
32986
32986
91934
answer