原文連接:Everything You Need To Know About Alignment In Flexbox, by Rachel Andrewcss
在 本系列的第一篇文章 中,我解釋了當在元素上聲明 display: flex
的時候,發生了什麼。這一次我將帶領你們瀏覽一下對齊屬性(alignment properties),看看它們是如何在 Flexbox 中起做用的。若是你曾困惑不知道該使用 align-*
屬性仍是 justify-*
屬性的話,我但願本文可以幫你解決這個困惑。設計模式
在整個 CSS 佈局歷史中,如何能自如地在兩個軸上對齊元素多是 Web 設計領域的最讓人頭大的問題了。所以第一次看見 Flexbox 中對齊項目的功能時,是很是使人興奮的。好比,下面兩行 CSS 便能輕鬆作到居中對齊:安全
See the Pen Smashing Flexbox Series 2: center an item by Rachel Andrew佈局
你可能認爲這些屬性僅是做爲 Flexbox 佈局中的對齊屬性使用的,事實上不是,這些屬性如今都定義在了 Box Alignment 規範 中。這個規範描述了這些對齊屬性是如何在不一樣的佈局上下文(layout contexts)中起做用的。也就是說,咱們能夠在 CSS 網格(Grid)中使用在彈性佈局中用到的這些對齊屬性——固然,將來可能還會有其餘的佈局上下文出現。所以,將來 Flexbox 中新的對齊功能將會在 Box Alignment 規範中定義,而不是在 Flexbox 規範中。post
許多人跟我說在使用 Flexbox 過程當中,很容易被「這裏該使用 align-
屬性仍是 justify
屬性?」的問題搞懵圈。這裏告訴你一個簡單的記憶方法:flex
justify-
操做的是主軸(main axis)對齊,對齊方向與 flex-direction
方向一致。align-
操做的是交叉軸(cross axis)對齊,對齊方向與 flex-direction
方向垂直。這裏咱們使用的是「主軸」和「交叉軸」,而沒有說「水平方向」或「垂直方向」,是由於前者(兩根軸)的方向跟物理方向並非關聯的。flexbox
咱們從主軸對齊開始講起。在主軸上對齊,咱們使用的是 justify-content
屬性。這個屬性把全部的 Flex 項目當成一組,控制項目之間的空間分配。spa
justify-content
的初始值是 flex-start
。這就是爲何,在聲明 display: flex
以後,全部的 Flex 項目都是在彈性線(flex line) 的起始處對齊的。當 flex-direction
是 row
且處於從左到右的語言環境的時候(好比英語),這個起始處就位於左邊。設計
Flex 項目在起始處對齊3d
須要注意的是,justify-content
僅在有剩餘空間可供分配的狀況下才起做用。若是在主軸上,Flex 項目分配完畢後,已無可供分配的剩餘空間,justify-content
不會起任何做用。
無空間可供分配
若是咱們給 justify-content
使用的是 flex-end
,那麼全部項目都是在彈性線末尾對齊,剩餘空間位於頭部。
Flex 項目在末尾處對齊
剩餘空間的分配還有更多方式。好比,咱們能夠空間在 Flex 項目之間平均分配,須要用到 justify-content: space-between
。這種狀況下,第一個和最後一個 Flex 項目會靠在容器邊緣,而後剩餘空間會在項目之間均等分配。
剩餘空間在項目之間平均分配
也可使用 ustify-content: space-around
。這種狀況下,剩餘空間會在每一個項目的兩邊分配。
剩餘空間在每一個項目的兩邊分配
譯註:由於每一個項目兩邊都分到了同樣的空間。所以,項目間的間距會是項目與容器邊緣間距的兩倍。圖中的容器設置了
padding
值,所以看出的效果可能沒那麼明顯,在此告知你們。
Box Alignment 規範還爲 justify-content
屬性定義了一個新值 space-evenly
,它並未出如今 Flexbox 規範中。使用了這個值後,項目與容器之間、項目與項目之間的分配的空間大小是同樣的。
項目均勻分佈於容器內
下面的 demo 展現了在不一樣取值狀況下的項目分配:
See the Pen Smashing Flexbox Series 2: justify-content with flex-direction: row by Rachel Andrew
flex-direction
取值 column
的時候,這些值的做用效果是同樣的。固然了,除非你給 Flex 容器一個高度或者容器自己是 block-size 的,不然是沒有額外空間可供非配的。請看下面的 demo:
See the Pen Smashing Flexbox Series 2: justify-content with flex-direction: column by Rachel Andrew
若是 Flex 容器使用了 flex-wrap: wrap
,咱們就能獲得多行(multiple flex lines) 顯示的 Flex 項目,align-content
就是處理在交叉軸上行之間的剩餘空間分配。固然,前提是在交叉軸上存在剩餘空間可供分配。在下面的例子中,交叉軸以列的形式在塊方向(block direction)上佈局,我把容器的高度設置爲 60vh
了,這比 Flex 項目所須要的空間要多,這樣咱們就有空間在垂直方向上進行分配了。
咱們可使用下圖裏列舉的值,佈局交叉軸上的對齊:
See the Pen Smashing Flexbox Series 2: align-content with flex-direction: row by Rachel Andrew
若是 flex-direction
取值 column
,則 align-content
將按以下方式佈局:
See the Pen Smashing Flexbox Series 2: align-content with flex-direction: column by Rachel Andrew
相似於 justify-content
,align-content
是把多行當作一個組來分配剩餘空間的。
閱讀 Box Alignment 規範,發現有一個簡寫屬性 place-content
,這個屬性是 justify-content
屬性和 align-content
屬性的簡寫形式。place-content
接收兩個值,第一個值指定 align-content
,第二個值指定 justify-content
;若是隻指定一個值的話,兩個屬性都設置爲這個值。所以:
.container {
place-content: space-between stretch;
}
/* 等效於 */
.container {
align-content: space-between;
justify-content: stretch;
}
/* 若是是這樣使用的 */
.container {
place-content: space-between;
}
/* 則等效於 */
.container {
align-content: space-between;
justify-content: space-between;
}
複製代碼
咱們已經知道,能夠將一組 Flex 項目或將多行彈性線(flex lines)做爲組進行對齊。可是還有一個小小的需求,就是但願在交叉軸上以彼此關聯的方式對 Flex 項目作對齊。Flex 容器會有一個高度,這個高度多是由最高的那個 Flex 項目決定的。
容器的高度是由第三個項目的高度決定的
固然,也能夠直接給 Flex 容器一個高度:
直接在容器上定義了高度
其餘 Flex 項目之因此會伸展與最高項同樣的高度,是由於 align-items
屬性的初始值是 stretch
。項目在交叉軸上伸展,直到尺寸和 Flex 容器的尺寸同樣。
咱們要注意到 align-items
的做用點是哪裏。對於多行 Flex 容器,每一行都像是一個新的 Flex 容器,那一行裏最高的 Flex 項目將決定改行其餘項目的高度。
除了初始值 stretch
,還可使用 flex-start
,此屬性會讓 Flex 項目沿着容器的起點處對齊,不會伸展到與容器同樣的高度了。
Flex 項目沿着交叉軸的起點處對齊
而 flex-end
則讓 Flex 項目沿着交叉軸的終點處對齊。
Flex 項目沿着交叉軸的終點處對齊
若是使用的是 center
,則全部項目的沿着中心對齊。
在交叉軸上居中對齊項目
還能夠基於基線對齊。與上面的基於項目中心線對齊不一樣,這是根據文本的基線對齊的:
基線對齊
能夠查看下圖,發現不一樣值產生的效果:
See the Pen Smashing Flexbox Series 2: align-items by Rachel Andrew
align-items
的意思是一次設置全部 Flex 項目的對齊方式。實際是把全部 Flex 項目的 align-self
屬性作了統一的設置。你也能夠在單個 Flex 項目上使用 align-self
屬性,指定在行(flex line)內與其它 Flex 項目不一樣的對齊方式。
在下例中,咱們在 Flex 容器上將 align-items
屬性設置爲 center
,而且爲第一個和最後一個項目分別指定了單獨的對齊方式。
See the Pen Smashing Flexbox Series 2: align-self by Rachel Andrew
譯註:
原文做者這裏的解釋有點牽強。詳細可參考 stackoverflow 上的回答:In CSS Flexbox, why are there no 「justify-items」 and 「justify-self」 properties?。
總結下來的話,就是沒有必要,由於使用下面即將要說的 auto margin 方案就能解決。規範中也是介紹使用 auto margin 解決主軸上部分項目的個性化對齊問題的。
一個常見的問題是,如何在主軸對齊一個項目或者一組項目。爲何 Flexbox 主軸上沒有 -self
屬性?若是你知道 justify-content
和 align-content
是用來分配剩餘空間的,那麼可能就能搞懂爲何沒有 self-alignment 屬性了。咱們把 Flex 項目當作一組,並對可用空間進行分配——在組的頭部或者尾部或者再項目之間。
咱們能夠思考下 justify-content
和 align-content
屬性在 CSS Grid 佈局中的做用。這兩個屬性在 Grid 中是用來分配*網格軌跡之間(between grid tracks)*的間距的。它們把軌跡當作是一個組,這些屬性就是用來分配這些軌跡之間的間距的。因爲咱們同時在 Grid 和 Flexbox 中對一個組進行操做,所以咱們不能單獨針對一個項目來作一些不一樣的事情。然而,有一種方法能夠實現當您在主軸上請求 self
屬性時所要求的那種佈局,那就是使用 auto margin。
若是你有過用 CSS 居中顯示一個塊元素的經驗(經過給內容頁設置左右 margin
爲 auto
),你就已經理解 auto margin 實現居中的行爲。若是咱們設置了一個方向上的 margin: auto
,那麼這個 margin
會盡量的佔據該方向的空間大小。在使用 margin
居中塊元素的例子中,咱們將左右 margin
都設置爲了 auto
,它們每一個都儘量的爭奪空間,最終將塊元素推倒了中間的位置。
auto margin 在主軸對齊上一樣表現優秀,它能夠實現單個項目或者一組項目的對齊。下例中,我實現了一個常見的設計模式——我使用 Flexbox 實現了一個導航欄,項目顯示爲一行,使用了初始值 justify-content: start
。我想讓最後一個項目顯示在彈性線(flex line)的末尾(固然,前提假設是這一行上有足夠的空間)。
我選中了這個項目,而且給了它 margin-left: auto
。這就是說項目的左邊會佔據儘量多的空間,也就是說這個項目會被推倒了右邊。
See the Pen Smashing Flexbox Series 2: alignment with auto margins by Rachel Andrew
若是在主軸上使用了 auto margin,justify-content
就會失去效果,由於 auto margin 會佔據全部原本要給 justify-content
分配的空間。
每一個對齊方法都有一個詳細的回退對齊,這是在請求的對齊不能實現的狀況下發生的事。例如,若是在容器中只有一個項目,而且使用了 justify-content: space-between
,那麼結果如何?答案是會使用回退對齊 flex-start
,而後發現這個項目在 Flex 容器的起點處對齊了;對 justify-conrtent: space-around
的狀況,回退對齊是 center
。
當前規範中,咱們還沒法修改回退對齊,若是你想讓 space-between
的回退方案採用 center
而非 flex-start
的話,是作不到的。 規範中有一個 Note 提到將來的版本中可能會支持。
Box Alignment 規範最近新增了 Safe 和 Unsafe 對齊的概念,對應關鍵字 safe
和 unsafe
。
下面的代碼中,最後一項對於 Flex 容器來講太寬了,且對齊方式不安全。Flex 容器位於頁面左側,當溢出超出頁面邊界時,發現這一項被切斷了。
.container {
display: flex;
flex-direction: column;
width: 100px;
align-items: unsafe center;
}
.item:last-child {
width: 200px;
}
複製代碼
不安全的對齊方式致使的對齊結果可能致使數據丟失
而安全對齊方式會避免數據丟失的出現,將溢出轉移到另外一邊。
.container {
display: flex;
flex-direction: column;
width: 100px;
align-items: safe center;
}
.item:last-child {
width: 200px;
}
複製代碼
安全對齊避免數據丟失
See the Pen Smashing Flexbox Series 2: safe or unsafe alignment by Rachel Andrew
對齊屬性起源於 Flexbox,可是如今位於獨立的規範中,並可用於其餘佈局上下文中。如下幾個關鍵事實將幫助你記住如何在 Flexbox 中使用它們:
justify-
主軸對齊,align-
交叉軸對齊;align-content
和 justify-content
屬性時須要有額外的剩餘空間;align-content
和 justify-content
屬性把 Flex 項目當作一組來處理。所以對這些屬性而言,沒有針對單個項目的 -self
對齊屬性。align-items
用於統一設置 Flex 項目上的 align-self
屬性。在 Flex 項目上使用 align-self
用於單獨設置此項目的對齊方式。(完)