首页 > 解决方案 > height/minHeight 和 display:flex 的行为

问题描述

我正在观察以下行为。

这段代码:

<div style={{ height: "100%", display: "flex", flexDirection: "column" }}>
      <div container style={{ flex: 1, border: "2px solid green" }} />
      <div style={{ minHeight: 300, border: "1px solid blue" }}>
        <div id="map" style={{ border: "3px solid red", height: "100%" }} />
      </div>
</div>

结果是:

在此处输入图像描述

看到红色边框,似乎带有 id map 的 div 花了一些高度。

现在,如果我对上面的代码进行一次更改,并将顶部 div的高度更改为 minHeight:

<div
      style={{ minHeight: "100%", display: "flex", flexDirection: "column" }}
    >
      <div container style={{ flex: 1, border: "2px solid green" }} />
      <div style={{ minHeight: 300, border: "1px solid blue" }}>
        <div id="map" style={{ border: "3px solid red", height: "100%" }} />
      </div>
</div>

你可以看到下面的屏幕截图,红色边框,地图没有高度了。

在此处输入图像描述

似乎很奇怪为什么玩顶级 div 会以这种方式影响带有 id 映射的 div ......不是吗?

演示

标签: htmlcssreactjsflexbox

解决方案


规范

有时,百分比大小的盒子的包含块的大小取决于盒子本身的内在大小贡献,从而产生循环依赖。在计算这种盒子的内在尺寸贡献时(包括基于内容的自动最小尺寸的任何计算),循环百分比......

然后是一整套复杂的规则和:

然后,除非另有说明,在计算包含块内容的使用大小和位置时:

  1. 如果由于包含块上的块大小或最大块大小而引入循环依赖,导致它依赖于其内容的大小,则框的百分比不会被解析,而是表现为自动。

  2. 否则,百分比将根据包含块的大小进行解析。(包含块的大小不会根据框的结果大小重新解析;因此内容可能会溢出或下溢包含块)。

基本上我们需要看看百分比是否可以在没有任何循环依赖的情况下解决。

在第二种情况下,您将容器定义为具有 a min-height,这意味着它的高度将由其内容定义,因此我们需要首先知道内容高度才能找到容器的高度,这将导致百分比高度无法自动,因为我们无法解决它,因为我们只有min-height:300px并且我们还需要根据内容找到高度。

在第一种情况下,您定义了容器,height:100%因此定义了高度,但我们仍然只有min-height子元素。这里有点复杂,因为可以使用 flex 属性找到该元素的高度。基本上,浏览器可以在不知道其内容的情况下解析该元素的高度,然后使用计算出的高度来解析百分比值。

这是一个基本示例,可以更好地说明:

.box {
  display: flex;
  flex-direction: column;
  border:1px solid red;
  margin:10px;
}

.box>div {
  border: 1px solid;
}

.height {
  height: 80%;
  background: red;
}
<div class="box" style="min-height:200px;">
  <div style="min-height:100px;">
    <div class="height">content here</div>
  </div>
</div>

<div class="box" style="height:200px;">
  <div style="min-height:100px;">
    <div class="height"> content here</div>
  </div>
</div>

<div class="box" style="height:200px;">
  <div style="flex-basis:50%;">
    <div class="height"> content here</div>
  </div>
</div>

<div class="box" style="height:200px;">
  <div style="flex-grow:1;">
    <div class="height"> content here</div>
  </div>
</div>

您可以看到,在定义了 flex 容器高度的所有情况下,我们都能够解析嵌套元素的百分比高度,因为浏览器能够在不需要内容的情况下计算高度。

实际上,内容还用于定义增加更多复杂性的高度。让我们考虑下面的例子:

.box {
  display: flex;
  flex-direction: column;
  border: 1px solid red;
  margin: 10px;
}

.box>div {
  border: 1px solid;
}

.height {
  height: 80%;
  background: red;
}
<div class="box" style="height:200px;">
  <div style="flex-basis:50%;">
    <div class="height">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse pulvinar nunc sit amet justo congue, et convallis diam porttitor. Curabitur semper tellus eget semper vehicula. In auctor ut nunc vitae faucibus. Integer molestie aliquam lacinia.
      Vestibulum blandit sem vitae tortor fermentum auctor. Morbi pharetra ante laoreet vestibulum laoreet. Nam id tempor eros, non ultrices leo. Quisque tincidunt hendrerit tortor ut malesuada.
       Vestibulum blandit sem vitae tortor fermentum auctor. Morbi pharetra ante laoreet vestibulum laoreet. Nam id tempor eros, non ultrices leo. Quisque tincidunt hendrerit tortor ut malesuada.</div>
  </div>
</div>

你可以看到文本溢出了红色的 div(它的容器)并且 flex 项的高度与文本的高度相匹配。在这种情况下,浏览器仍然能够根据 flex 属性识别 flex 项目的高度,并且这些属性还考虑了内容!

弹性项目不能缩小超过其内容大小,这就是为什么flex-basis:50%不给出50%父高度而是给出 50% 和内容高度之间的最小值的原因。

如果添加min-height:0,您将有不同的行为:

.box {
  display: flex;
  flex-direction: column;
  border: 1px solid red;
  margin: 10px;
}

.box>div {
  border: 1px solid;
}

.height {
  height: 80%;
  background: red;
}
<div class="box" style="height:200px;">
  <div style="flex-basis:50%;min-height:0">
    <div class="height">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse pulvinar nunc sit amet justo congue, et convallis diam porttitor. Curabitur semper tellus eget semper vehicula. In auctor ut nunc vitae faucibus. Integer molestie aliquam lacinia.
      Vestibulum blandit sem vitae tortor fermentum auctor. Morbi pharetra ante laoreet vestibulum laoreet. Nam id tempor eros, non ultrices leo. Quisque tincidunt hendrerit tortor ut malesuada.
       Vestibulum blandit sem vitae tortor fermentum auctor. Morbi pharetra ante laoreet vestibulum laoreet. Nam id tempor eros, non ultrices leo. Quisque tincidunt hendrerit tortor ut malesuada.</div>
  </div>
</div>

现在 flex 项目采用50%父高度(忽略其内容),然后其子元素采用80%该高度并且内容在逻辑上溢出。


TL;博士

弹性项目(当弹性方向是列并且弹性容器具有明确的高度时)将具有由弹性属性定义的高度并考虑内部内容(基本上内容只会设置min-height约束)然后在计算该高度之后浏览器可以为里面的项目解析任何高度的百分比值。


这是一个相关的问题,我们有类似的问题并且我们能够解决百分比值:为什么我的 Grid 元素的高度没有被正确计算?


推荐阅读