前陣子在做公司的專案時,遇到一個用flex寫的layout,明明已經用flex-basis限制寬度,但還是因為layout裡面的內容物的文字和圖片而把某一個區塊撐開。那時一直想不透是為什麼,所以就開始找資料,才發現跟flex本身的特性有關。
防止flex item因為特殊情況被撐開
實作情境
以下是模擬當初在實作的情境,主要是一個被分為三欄的layout,每一欄都會被放入一個元件,其中中間的元件因為是放入類似文字編輯器的元件,所以這個元件內容並不是固定的,會動態的變動,也就有可能因為圖片過大,或出現無斷行文字而把中間這欄撐開。
=> container裡面分別有三個item,item2的flex-basis設定成300px,裡面放了一個含有10個30px的文字的component。
<範例HTML>
<範例css>
<範例實際畫面>
當有比較大的圖片出現時,會出現以下狀況
<HTML(放入圖片後)>
<實際畫面(放入圖片後)>
中間這欄會被撐開,不只有原先我們希望的300px寬。
問題發生原因&解決方式
為什麼會發生這個問題?
這邊先來了解一下這個問題發生的原因!會出現這樣的狀況主要是因為設定flex之後,容器裡面的item的max-width(flex-direction: row)或max-height(flex-direction: column)的預設值為auto,所以當內容物寬度或高度較大時,這一欄就會被撐開。到這裡,腦子動得比較快的人,可能還是會覺得哪裡怪怪的,這邊先暫時不延伸下去思考,先針對flex item被預設的特性下去做修改。
*被預設為auto的屬性是max-width還是max-height主要是看現在被設定的flex方向(主軸的方向),也就是item的排列方向是x軸還是y軸。
怎麼解決這個狀況?
前面提到跟max-width或max-height預設是auto有關,那這裡我們就只需要把它設定為0就可以了。在這個範例中,因為是主軸為x軸,所以要設定為0的是max-width。
這樣中間這一欄,就可以恢復成原本我們希望的300px了。但在這個情境中,圖片會被蓋住,這時候可以依照實際的需求搭配overflow來呈現。
(當時我實務中的需求,scroll的部分是設定在這一欄中的元件)
除了我這次的解法外,依照實際的確切情境,也可以透過overflow來解決這個狀況。
延伸思考
重新再回到剛剛前面提到的這個問題產生的原因,應該會有不少人覺得哪裡怪怪的,尤其是這個問題的重要部分-寬度的地方。明明每一欄的flex-basis都設定好了,而且合計是container的寬度,怎麼中間這欄可以被撐開呢?那其他欄位不就會被擠壓到嗎?
沒錯!這個部分也和flex的特性有關,也就是flex-shrink。當display設定為flex時,flex item的flex-shrink預設值會是1,意思就是當空間不足時,item就會被擠壓。這也就是讓中間欄位被撐開後,沒有導致其他item被擠倒container外的原因。
在這個情況下,如果將另外兩個item的flex-shrink設定為0,就會發生以下的狀況,也就是item超出container。
其實flex是我在實做中很常使用到的排版方式,但有時會因為自己沒有真正認識它,而踩到一些雷。
不過仔細想想也就是因為flex有這樣能屈能伸(?)的特性,才會在非常好用的同時,偶爾出現這一些奇特的現象,但只要再多花一點時間了解它,就會越用越順手。
參考範例在這裡
貼心小提醒!!
因為是亂亂寫筆記,真的就是純紀錄之前實作時,如何解決曾經卡住過的問題,所以主要都是解決問題的方式為主,不會有太多詳細說明。
留言列表