Chrome72嵌套flex佈局修改,你的網站可能會發生布局錯亂

起源

2019年1月29日,Chrome72正式版(72.0.3626.81)發佈,本次發佈帶來了一個改變,且沒有在更新日誌中說起,該改變致使某些網站發生了佈局錯亂。該改變主要針對的是嵌套的flex佈局,下面咱們一塊兒看下是怎麼回事。css

問題

首先,咱們有一個嵌套的flex佈局,代碼以下:html

<style> 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; } </style>
<div class="area flex">
    area
    <div class="item flex">
        item
        <div class="nest-item">
            <div class="content">content</div>
        </div>
    </div>
</div>
複製代碼

但願實現這樣的效果:父容器area有一個指定的高度,且它是一個flex彈性盒子,它內部有一個子元素item,使用 flex: 1 指定了佔滿剩餘空間,且item也是一個flex彈性盒子,它內部還有一個一樣佔滿剩餘空間的嵌套子元素nest-item,經過設置 overflow: auto 讓它的內容超出後顯示滾動條。效果以下:佈局

這樣佈局的想法很簡單,即經過設置彈性盒子子元素的擴展比率,能獲得一個自動佔滿剩餘空間高度的容器,再在這個容器中放須要顯示的內容,在某些狀況下,這確實是一個比較不錯的主意,在Chrome72以前都是能夠正常顯示的。可是Chrome72.0.3626.81中顯示以下:flex

追溯

爲何會出現這樣的問題呢?咱們看一下規範( drafts.csswg.org/css-flexbox… )flex彈性盒子主軸上子元素的最小大小是內容的大小(視主軸方向爲寬或高)。網站

那麼咱們再看一下上面的例子,area的主軸是縱向的,子元素item的最小高度便是內容的高度,而nest-item被content撐開,content有一個高度(600px,超出了容器的高度),那麼item的最小高度也就超過了600px。這樣一來,一層層都是被內容撐開,也就沒有出現滾動條了,這樣彷佛是符合規範預期的。google

在chromium的issue反饋中,有人提到了這個問題( bugs.chromium.org/p/chromium/… ),根據回覆,這正是官方爲了讓Chrome更加符合規範行爲而作的調整。也就是說,Chrome72以前的版本,這算是一個沒有按照規範行爲而出現的bug。新的調整,其實就是讓flex彈性盒子的子元素最小高度的默認行爲應用 min-height: min-content ,就像官方回覆中提到的那樣,讓子元素做爲flex彈性盒子時卻和普通盒子處理方式不一樣是會讓人困惑的。flexbox

解決方法

既然知道了緣由,那麼若是咱們還想使用這樣的佈局方式,該怎麼作呢?spa

對的,咱們給item指定一個最小高度,讓它不使用默認的行爲(即內容的高度),通常咱們指定最小高度爲0 min-height: 0。給item加上這個樣式後,咱們再看一下效果:日誌

嗯,已經符合咱們的預期了。爲了驗證規範中提到的對主軸方向的行爲,咱們修改一下代碼,將主軸設置爲水平方向試試,代碼以下:code

<style> 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; } </style>
<div class="area flex">
    area
    <div class="item flex">
        item
        <div class="nest-item">
            <div class="content">content</div>
        </div>
    </div>
</div>
複製代碼

效果以下:

看來主軸爲水平方向時,是符合規範預期行爲的(Chrome72及之前的版本都符合),那麼咱們給item加上一句樣式 min-width: 0 ,效果以下:

嗯,是符合咱們預期的。

結語

好了,如今你已經知道是怎麼一回事了,但是等等,你說你升級到Chrome72沒有發現我說的問題?

那是由於官方注意到這個修改會影響到一些網站的正常顯示,所以在2019年2月6日(正是春節假期間)發佈的Chrome72.0.3626.96中,將這個問題還原回之前的行爲了( chromium.googlesource.com/chromium/sr… )。

官方的意思是爲了不這個修改給某些網站帶來的很差的影響,所以預留時間給你們修改,等到Chrome73將會發布這一改變。因此爲了將來更好的瀏覽體驗,檢查一下你的頁面吧!

相關文章
相關標籤/搜索