如何解决min-height在flex布局中的失效问题

「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!

问题复现

首先来看一段简单的网页代码,使用min-height控制A区域的最小高度为父节点的50%。

1
2
3
4
5
6
7
8
9
10
11
12
...
<body class="body">
<div class="parent">
<div class="child-a">
A: min-Height: 50%;
</div>
<div class="child-b">
B: flex: 1
</div>
</div>
</body>
...

其相关样式表代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<style>
.body {
height: 300px; /*充满整个屏幕*/
width: 300px;
}

.parent {
min-height: 100%; /*parent充满整个body*/
display: flex;
flex-direction: column;
border: 1px solid black;
}

.child-a {
min-height: 50%; /*期待:A至少能充满半个区域*/
background-color: cornflowerblue;
}

.child-b {
flex: 1; /* 其他B填充除A外parent的剩余空间*/
background-color:bisque;
}

期待效果图如下图,希望通过min-height使得A至少占满50%的空间。

image.png

然而,实际效果图却是下图这样:

image.png

为什么A区域的min-height没有如我们所愿呢?

查找问题

我们试图通过查看min-height的定义来定位问题。

CSS官方文档中,我们查找到min-height定义与解释,其中提到,当其取值为百分比时,其高度是根据父节点(准确的说是包含块)的高度计算的,如果没有明确指定包含块的高度,并且该元素不是绝对定位的,其高度将取决于内容高度

原文如下:

<percentage>

Specifies a percentage for determining the used value. The percentage is calculated with respect to the height of the generated box’s containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the percentage value is treated as 0 (for min-height) or none (for max-height).

换句话说,当父节点的height未设置,而min-height为百分比取值时,其没有可依赖计算的基础值,因此无法计算其高度。此时按照CSS规范,元素的高度将由内部元素来决定。当 min-height 大于 max-heightheight时,元素的高度会设置为 min-height 的值。

解决问题

1. 给父节点设置height

我们给父节点parent设置height:1px即可。关于heightmin-heightmax-height的优先级,我们文章最后再说。

1
2
3
4
5
6
.parent {
/*新增一行,使得子节点的百分比值可以计算*/
height: 1px;

/*parent原css...*/
}

2. 给父节点外再加一层,并设置最外层display:flex

这一点我不知道原因,只是在查找过程中发现,这样也可以解决问题,所以列在此处,请读者指点

一个可参考的文章:Normalizing Cross-browser Flexbox Bugs

如果发现节点的宽度也受到影响,增加width相关设置调整即可。

1
2
3
4
5
6
.body {
/*新增一行*/
display: flex;

/*原css不变...*/
}

3. 设置为绝对布局:absolute

这一点是根据定义来的,当元素为绝对定位时,百分比的设置min-height也可以生效。(若影响了width,添加相关属性)

虽然这种方式可以解决min-height的问题,但是引入绝对布局,无疑会将页面变复杂。不可取!

1
2
3
4
5
6
7
8
.parent {
position: relative;
...
}

.child-a {
position: absolute;
}

优先级

heightmin-heightmax-height的优先级可以通过简单的代码来测试,结果表明:height<min-height或者 max-height< min-height时,其高度的实际取值为min-height

image.png