flex布局 占满_Chrome72 嵌套 flex 布局修改,你的网站可能会发生布局错乱

  • Post author:
  • Post category:其他



起源

2019 年 1 月 29 日,Chrome72 正式版(72.0.3626.81)发布,本次发布带来了一个改变,且没有在更新日志中提及,该改变导致某些网站发生了布局错乱。该改变主要针对的是嵌套的flex布局,下面我们一起看下是怎么回事。


问题

首先,我们有一个嵌套的 flex 布局,代码如下:




div {





box-sizing: border-box;




}




.flex {





display: flex;




flex-direction: column;




}




.area {





padding: 10px;




height: 300px;




width: 300px;




background-color: #3fb9ab;




color: #fff;




}




.item {





padding: 10px;




flex: 1;




background-color: #158c7e;




}




.nest-item {





flex: 1;




overflow: auto;




background-color: #046b5f;




}




.content {





padding: 10px;




height: 600px;




}







class="area flex">




area













class="item flex">






item



















class="nest-item">

















class="content">content




























希望实现这样的效果:父容器 area 有一个指定的高度,且它是一个 flex 弹性盒子,它内部有一个子元素 item,使用

flex:1

指定了占满剩余空间,且 item 也是一个 flex 弹性盒子,它内部还有一个同样占满剩余空间的嵌套子元素 nest-item,通过设置

overflow:auto

让它的内容超出后显示滚动条。效果如下:

8b80db6354feb21fb2ef6f2398410aab.png

这样布局的想法很简单,即通过设置弹性盒子子元素的扩展比率,能得到一个自动占满剩余空间高度的容器,再在这个容器中放需要显示的内容,在某些情况下,这确实是一个比较不错的主意,在 Chrome72 之前都是可以正常显示的。但是 Chrome72.0.3626.81中显示如下:

db5fdae638bc60f62c00c8d4934c400b.png

追溯

为什么会出现这样的问题呢?我们看一下规范( https://drafts.csswg.org/css-flexbox/#min-size-auto )flex 弹性盒子主轴上子元素的最小大小是内容的大小(视主轴方向为宽或高)。

那么我们再看一下上面的例子,area 的主轴是纵向的,子元素 item 的最小高度即是内容的高度,而 nest-item 被 content 撑开,content 有一个高度(600px,超出了容器的高度),那么 item 的最小高度也就超过了 600px。这样一来,一层层都是被内容撑开,也就没有出现滚动条了,这样似乎是符合规范预期的。

在 chromium 的 issue 反馈中,有人提到了这个问题( https://bugs.chromium.org/p/chromium/issues/detail?id=927066 ),根据回复,这正是官方为了让 Chrome 更加符合规范行为而做的调整。也就是说,Chrome72 之前的版本,这算是一个没有按照规范行为而出现的 bug。新的调整,其实就是让 flex 弹性盒子的子元素最小高度的默认行为应用

min-height:min-content

,就像官方回复中提到的那样,让子元素作为 flex 弹性盒子时却和普通盒子处理方式不同是会让人困惑的。


解决方法

既然知道了原因,那么如果我们还想使用这样的布局方式,该怎么做呢?

对的,我们给 item 指定一个最小高度,让它不使用默认的行为(即内容的高度),一般我们指定最小高度为0

min-height:0

。给 item 加上这个样式后,我们再看一下效果:

8b80db6354feb21fb2ef6f2398410aab.png

嗯,已经符合我们的预期了。为了验证规范中提到的对主轴方向的行为,我们修改一下代码,将主轴设置为水平方向试试,代码如下:




div {





box-sizing: border-box;




}




.flex {





display: flex;




flex-direction: row;




}




.area {





padding: 10px;




height: 300px;




width: 300px;




background-color: #3fb9ab;




color: #fff;




}




.item {





padding: 10px;




flex: 1;




background-color: #158c7e;




}




.nest-item {





flex: 1;




overflow: auto;




background-color: #046b5f;




}




.content {





padding: 10px;




width: 600px;




}







class="area flex">




area













class="item flex">






item



















class="nest-item">

















class="content">content




























效果如下:

95752920bb2dd15778ebce6bfcd9e0df.png

看来主轴为水平方向时,是符合规范预期行为的(Chrome72 及以前的版本都符合),那么我们给 item 加上一句样式

min-width:0

,效果如下:

2cbc69f3ac5e17d9e333d2903737efea.png

嗯,是符合我们预期的。


结语

好了,现在你已经知道是怎么一回事了,可是等等,你说你升级到Chrome72没有发现我说的问题?

那是因为官方注意到这个修改会影响到一些网站的正常显示,因此在 2019 年 2 月 6 日(正是春节假期间)发布的 Chrome72.0.3626.96 中,将这个问题还原回以前的行为了( https://chromium.googlesource.com/chromium/src/+/032ef9666487db1d04b656a095b041de8c6d2b63 )。

官方的意思是为了避免这个修改给某些网站带来的不好的影响,因此预留时间给大家修改,等到Chrome73将会发布这一改变。所以为了未来更好的浏览体验,检查一下你的页面吧!



版权声明:本文为weixin_33901614原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。