目錄
- flex是什么
- 容器的屬性
- item 的屬性
- 一些疑惑和解答
flex是什么
根據規范中的描述可知道,Flexbox 模塊提供了一個有效的布局方式,即使不知道視窗大小或者未知元素情況之下都可以智能的,靈活的調整和分配元素和空間兩者之關的關系,簡單的理解,就是可以自動調整,計算元素在容器空間中的大小,
flex分為兩個部分,即容器(Container)和專案(item),一旦將一個元素設定為 flex container,那么其子元素默認全部變為flex item,然后我們就可以通過在 container 設定一些屬性來控制其 item 的布局,當然,item 自身也有一些 flex 屬性,是只針對自己的屬性,
要將一個元素設定為容器,只要在其 css 里添加 display:flex 或者 display:flex-inline 即可
在介紹 flex 的屬性前,還有一些基本概念需要介紹,這里就借用網上的一幅圖來說明

如圖,其實已經很清晰明了了,容器內有兩條軸,分別叫主軸(main axis)和交叉軸(cross axis),一般情況下 item 沿主軸方向排列,flex默認主軸為橫向,交叉軸為縱向,還有 main start、main end、cross start、cross end 這四個分別表示主軸和交叉軸的起始位置和結束位置,
容器的屬性
容器有六個屬性,flex-direction、flex-wrap、flex-flow、justify-content、align-items、align-content,
- flex-direction
flex-direction 有四個值:row、column、row-reverse、column-reverse,這個屬性用于設定主軸方向,row 為默認值,表示主軸為橫軸,方向從左到右;column 表示主軸為縱軸,方向從上到下;后兩個分別表示從右到左和從下到上的主軸, - flex-wrap
flex-wrap 有三個值:nowrap、wrap、wrap-reverse,這個屬性設定如何換行,nowrap(默認)表示不換行,此時若主軸方向item總長度超過容器長度,則壓縮 item 主軸方向長度,wrap 表示換行,當 item 總長度超過容器長度時就換行,wrap-reverse 表示反向換行,換行后最靠近 cross end 的為第一行、然后是第二行...... - flex-flow
flex-flow 為前面兩個的簡寫版本,即可以同時在此屬性里設定前面兩個屬性的值,如:flex-flow: nowrap row; - justify-content
justify-content 有五個值:flex-start、flex-end、center、space-between、space-around,此屬性用于調整主軸方向上 item 的對齊方式,flex-start 和 flex-end 分別表示向 main start 和 main end 對齊;center 為主軸方向上的居中對齊;space-between 表示同時向 main start 和 main end 對齊,即兩端對齊,并且兩個 item 之間主軸方向上的間距相等;space-around 表示每個專案兩側之間的距離相等 - align-items
align-items 有五個值:flex-start、flex-end、center、stretch、baseline,此屬性用于調整交叉軸方向上專案的對齊方式,前面三個值和 justify-content 對應的值效果是一樣的,只是方向換成了交叉軸,stretch 為默認值,當 item 交叉軸方向的長度沒有設定或為auto時就會在交叉軸方向填滿容器,baseline 則表示文字對齊,即以 item 中的第一行文字為基準對齊 - align-content
align-content 有六個值:flex-start、flex-end、center、space-around、space-between、stretch,此屬性定義了多根軸線的對齊方式,當只有一根軸線時此屬性無效,此屬性主要針對交叉軸方向,其值在上面都有提到,這里就不贅述了
item 的屬性
item 有六個屬性:order、flex-grow、flex-shrink、flex-basis、flex、align-self
- order,order 設定同一容器里沿主軸方向的排列順序,可以利用此屬性做交換的影片
- flex-grow,此屬性設定該 item 在主軸方向有剩余空間時的放大比例,默認為0,即不放大,注意:這里的放大計算原理是先計算主軸上的剩余空間 rest_space,然后計算這條軸上所有 item 的 flex-grow 之和 grow_sum,最后給每個專案 item[i] 的主軸長度增加 rest_space * ( grow[i] / grow_sum ),即先計算出該 item 放大比例占所有 item 放大比例的百分比,然后該 item 增加 該百分比乘以主軸剩余長度,需要注意的是,當主軸方向沒有剩余空間時,該屬性無效
- flex-shrink,此屬性和 flex-grow 正好相反,此屬性設定該 item 在主軸方向沒有剩余空間時的縮小比例,默認值為1,即空間不足時縮小,如果設定為0,則空間不足時會超出容器,我原本以為計算原理和 flex-grow基本相同,后來發現有一點不對,經過網上查詢資料發現,flex- shrink 的計算公式略有區別,flex-shrink 首先要計算權重 TW = E(basis[i] * shrink[i]),也就是所有 item 的 basis * shrink 之和,然后每個 item 的實際長度為 basis[i] - [ (basis[i] * shrink[i] ) / TW ] * need_space,其中,basis 為專案設定長度(見下面的4),shrink 為縮放值,need_space 為需要所有 item 減少的總長度,需要注意的是:flex-shrink 為0的 item 是不會縮放的,通常這會導致 item 超出容器,
- flex-basis,此屬性指示在分配多余空間前 item 占的長度,默認情況下為 auto,即設定的width,需要注意的是,如果沒有多余空間的話,會按照上面第3條的規則縮放;是否有多余空間是根據主軸上所有 item 的flex-basis 之和來計算的,不是按照 width 來計算的!
- flex,此屬性為 flex-grow、flex-shrink、flex-basis 三個屬性的簡寫,有兩個快捷值:auto( 1 1 auto) 和 none( 0 0 auto ),
- align-self,此屬性可取六個值:flex-start、flex-end、center、baseline、stretch、auto,此屬性設定單獨的排列行為,此屬性的值的含義前面容器屬性部分都有提到,此處不贅述,
一些疑惑和解答
在學習flex的時候,不自覺產生了一些使用方面的疑惑,下面就是我的一些疑惑和結果
- justify-content 是針對主軸方向的排列,一開始想當然認為是多個 item 的情況,后面突然想起,如果是一個 item 的話,其排序規則又是怎樣的呢?
首先 flex-start、flex-end 和 center 還比較好理解,只有一個專案的時候會貼著 main start、main end 或者在 main start 和 main end 的中間,那么其值為 space-between 和 space-around的時候呢,前者表示兩端對齊,后者表示等間距對齊,在只有一個專案的情況下會怎么出現什么結果呢?結果如下

左邊表示 space-around 的結果,右邊表示 space-between 的結果,可以看出,由于 space-around 要求專案兩側的距離相等,因此只有一個專案時左右距離各占一半,和center的效果是一致的;而 space-between在只有一個專案不能同時對齊左右端的情況下,選擇了左對齊,
結論:當只有一個專案時,space-around 的效果等同于 center,space-between 的效果等同于 flex-start - align-items值為 stretch 時,假如 item 在交叉軸方向的長度沒有設定,并且在交叉軸方向不止一個 item (即在主軸方向有換行),這時會出現什么結果呢?
這個問題的結果非常有趣,我原以為只要交叉軸方向上只有一個 item 的會直接填滿整個容器,而有兩個 item 的就平分容器,然后結果卻如下圖

原因大概是因為 stretch 的拉伸針對的是整個軸,而上圖是雙軸線,實際上 stretch 的效果是正確的
結論:只要交叉軸方向有大于2個 item,即使交叉軸方向只有一個 item,這個 item 依然不會充滿容器,而是和主軸方向上的 item 長度一致 - align-items值為 baseline 時,若 item 沒有文字會出現什么結果?
這個問題的結果也很有趣,直接上結果

可以看出,沒有文字的 item 可以認為是文字在最底部的 item
結論:沒有文字的 item 可以認為是文字在最底部的 item - align-content 說明為單軸線時無效,那么什么時候為單軸線,什么時候為多軸線?
經過我的實驗,所謂的單軸線應該就是說沒有換行的情況下,只有一行有 item ,此時 align-content 無效,那么由此反推,交叉軸方向上 item 的最大個數即主軸數,主軸方向上 item 的最大個數即交叉軸數,如下圖,這就是雙軸線

- justify-content、align-items 和 align-content 似乎差不多?
首先就他們可以取的值而言, align-content 似乎是 align-items 和 justify-content 的大雜燴,后面兩個屬性可以取得值 align-content 都可以取,更為巧合的是,取 align-items 的 align 和 justify-content 的 content 就組成了 align-content,這倒是挺有趣的,
但是三者之間還是區別比較明顯的,justify-content 就不說了,它的區別最明顯,它是針對主軸的,而其他兩個是針對交叉軸的,那么同樣針對交叉軸的 align-content 和 align-items 有什么區別呢?
首先看看定義,align-content 相較于 align-items 有一個明顯的不同,那就是它不支持單軸線的操作,下圖是單軸線情況下 align-items 和 align-content 的區別

可以看出,單軸線情況下 align-content 根本沒起作用,而此時 align-items 就起到了非常關鍵的作用,接下來再看看多軸線情況下會發生什么

于是兩者之間的區別已經躍然紙上了,首先,align-content 單軸線無效,而 align-items 單軸線和多軸線都有效(但多線軸情況下其本質還是對單線軸的設定),當兩者同時使用且發生沖突時,align-content 的優先級別更高,也就是說,沖突時 align-content 的操作會覆寫掉 align-items 的操作
結論:
- justify-content 是針對主軸的,而 align-content 和 align-items 是針對交叉軸的
- align-content 不支持單軸線,align-items 本質就是對每條軸線的操作
- 操作沖突時,align-items 的操作會被 align-content 覆寫掉
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/466021.html
標籤:Html/Css
