Chrome 73致使的flex佈局崩壞

現象

項目中會存在以下幾種嵌套flex結構:css

<style> /* 通用樣式 */ .card { width: 200px; height: 300px; margin: 20px; border: 1px solid #999; } .flex { display: flex; flex-direction: column; } .header { flex: none; height: 40px; border-bottom: 1px solid #333; } .scroll { overflow-y: auto; } .p { margin: 10px; height: 400px; background-color: rgba(0, 0, 0, 0.2); } </styl> <!-- 佈局一 --> <div class="card flex"> <div class="header">Header</div> <div class="flex"> <div class="scroll"> <div class="p"></div> </div> </div> </div> <!-- 佈局二 --> <div class="card flex"> <div class="flex"> <div class="header">Header</div> <div class="scroll" style="flex-grow:1;"> <div class="p"></div> </div> </div> </div> 複製代碼

這在Chrome 73以前的實際展現效果以下(手頭的Electron——Chrome 69): html

都是符合指望的結果,scroll是能夠滾動的區域,然而,Chrome 73的展現效果倒是:
父元素的高度都被子元素撐開了,致使scroll元素沒法滾動。what? why? 納尼?

緣由

究其緣由,規範有關高度的解釋在這一章節,簡單歸納就是:chrome

flex元素的最小大小(視主軸方向決定是高仍是寬)是內部內容的大小。即,min-height/min-width默認值是「auto」。瀏覽器

emmm...讀「規範」千遍,其義自見。當再三理解這個結論後發覺,彷佛,新版Chrome的實現是符合規範的!確實,Chrome的此舉改動就是爲了讓瀏覽器的flex佈局行爲更貼近規範。編輯器

Chrome社區的這個issue:Flexbox rendering changed between chrome 71 and 72,對上面的問題(佈局二),進行了激烈的討論,甚至最終致使了官方的回滾。ide

至於咱們爲何後知後覺,直到73才大面積暴露該問題,下文花絮會展開解釋。佈局

不過,跟着規範走是徹底的政治正確,怎麼說都對!開發者只能順應潮流去改變。flex

修復

其實,當看到這個現象後,個人心裏並無經歷太大的波動,由於min-width曾經已經給我上過預備課了(詳見下文花絮)。因此我很快就找到了解放方式。flexbox

找到最外層被撐開的元素,上文兩種佈局裏,都是scroll的直屬父元素,對其增長min-height: 0的屬性便可修復異常佈局。spa

若是min-height的行爲實在沒法理解的話,overflow: hidden(非visible)也能達到一樣的功效。overflow平時用的比較多,相對會更有體感,以下例:

<div style="height: 200px;overflow: scroll;">
  <div style="height: 400px"></div>
</div>
複製代碼

當父元素設置了overflow:hidden/scroll,展現時,父元素就會隱藏子元素的溢出部分。

固然,flex佈局中的overflow,它的實際做用也就是把min-height設置爲0。

此外,還能夠對子元素,上文示例中即scroll元素,設置height: 100%來修復。但當層級比較多時,須要將該屬性一層層往下傳遞,不夠環保。

花絮

問題是順利修復了,下面是一些插曲~

1. Chrome 71->72->73

這個改動首發於Chrome 72,但爲何直到Chrome 73才被咱們注意到?由於Chrome 72發佈後,因爲反響強烈,Chrome決定先回滾改動,給開發者更多的時間來適應該改動。

然而Chrome 72的發佈,以及72的後續回滾發佈都發生在中國春節假期期間,沒什麼用戶反饋,對於中國開發者,例如我,徹底沒注意到此次預警。。。

2. min-width的學前教育

爲何說我已經被min-width提早教育過?

我實現過相似編輯器的tab:

這裏就是嵌套的flex橫向佈局,在默認樣式下,滾動區會被子元素撐開,也就是此時,我第一次領略了當初就以爲很奇怪的min-width: 0的寫法。

那爲何那時就須要顯式聲明父元素的min-width呢?此外,此次升級所形成的誤傷都是發生在縱向佈局的flex上,那橫向佈局的flex有影響嗎?

答案其實很狗血,由於Chrome對於min-width的默認值,從很早期就設置爲符合規範的「auto」了。。。

參考

  1. Flexbox sets height of inside element to 0
  2. MDN min-height
  3. MDN min-width
相關文章
相關標籤/搜索