在CSS Flexbox中,爲何沒有「 justify-items」和「 justify-self」屬性?

考慮伸縮容器的主軸和橫軸: css

在此處輸入圖片說明 資料來源: W3C html

要沿主軸對齊彈性項目,有一個屬性: css3

要沿十字軸對齊彈性項目,須要三個屬性: spring

在上圖中,主軸是水平的,而橫軸是垂直的。 這些是flex容器的默認方向。 瀏覽器

可是,這些方向能夠很容易地與flex-direction屬性互換。 編輯器

/* main axis is horizontal, cross axis is vertical */
flex-direction: row;
flex-direction: row-reverse;

/* main axis is vertical, cross axis is horizontal */    
flex-direction: column;
flex-direction: column-reverse;

(交叉軸始終垂直於主軸。) ide

在描述軸的工做方式時,個人觀點是,任一方向彷佛都沒有什麼特別之處。 主軸,橫軸在重要性方面均相等,而且flex-direction使其易於來回切換。 佈局

那麼,爲何十字軸具備兩個附加的對齊屬性? flex

爲何將align-contentalign-items合併爲主軸的一個屬性? flexbox

爲何主軸沒有得到「 justify-self屬性?


這些屬性將有用的方案:

  • 將flex項目放在flex容器的角落
    #box3 { align-self: flex-end; justify-self: flex-end; }

  • 使一組flex項右對齊( justify-content: flex-end ),但使第一個justify-content: flex-end項向左對齊( justify-self: flex-start

    考慮帶有一組導航項和徽標的標題部分。 經過justify-self ,徽標能夠在左側對齊,而導航項保持在最右側,而且整個對象能夠平滑調整(「彎曲」)以適應不一樣的屏幕尺寸。

  • 在三個flex項目的行中,將中間項目粘貼到容器的中心( justify-content: center ),並將相鄰的項目與容器邊緣對齊( justify-self: flex-startjustify-self: flex-end )。

    請注意,若是相鄰項目的寬度不一樣,則justify-content屬性上的space-aroundspace-between值將不會使中間項目以容器爲中心。

#container { display: flex; justify-content: space-between; background-color: lightyellow; } .box { height: 50px; width: 75px; background-color: springgreen; } .box1 { width: 100px; } .box3 { width: 200px; } #center { text-align: center; margin-bottom: 5px; } #center > span { background-color: aqua; padding: 2px; }
<div id="center"> <span>TRUE CENTER</span> </div> <div id="container"> <div class="box box1"></div> <div class="box box2"></div> <div class="box box3"></div> </div> <p>note that the middlebox will only be truly centered if adjacent boxes are equal width</p>

jsFiddle版本


在撰寫本文時,在flexbox規範中尚未說起justify-selfjustify-items

可是,在CSS Box Alignment Module中 ,這是W3C還沒有完成的建議,用於創建一套通用的對齊屬性以供全部Box模型使用,其中包括:

在此處輸入圖片說明 資料來源: W3C

您會注意到,考慮了justify-selfjustify-items ... 但對於flexbox卻沒有


最後,我重申主要問題:

爲何沒有「證實項目」和「自我證實」屬性?


#1樓

這是在www樣式列表中提出的,Tab Atkins(規範編輯器) 提供了一個解釋緣由的答案 。 我會在這裏詳細說明。

首先,讓咱們首先假設咱們的flex容器是單行的( flex-wrap: nowrap )。 在這種狀況下,主軸和橫軸之間顯然存在對齊差別-主軸上堆疊了多個項目,但在橫軸上僅堆疊了一個項目。 所以,在橫軸上有一個可自定義的「 align-self」項是有意義的(由於每一個項目都是單獨對齊的),而在主軸上則沒有意義(由於在那裏,項目統一排列)。

對於多行flexbox,相同的邏輯適用於每一個「 flex line」。 在給定的行中,項目在橫軸上單獨對齊(由於在橫軸上每行只有一個項目),而在主軸上則是統一排列。


這是短語的另外一種表達方式:所以, 全部 *-self*-content *-self屬性都與如何在事物周圍分配額外的空間有關。 但關鍵的區別是, *-self版本的狀況下, 只能有一個在該軸一個單一的東西 ,而*-content版本時,有在軸可能不少事情 。 單物與多物場景是不一樣類型的問題,所以它們具備不一樣類型的可用選項,例如, *-content space-around值/ space-between值對*-content有意義,但對於*-self卻不適用*-self

SO:在flexbox的主軸上,有不少東西能夠分配空間。 所以,一個*-content屬性是有道理的有,但不是*-self屬性。

相反,在交叉軸,咱們既是*-self*-content屬性。 一個決定了咱們如何在許多彎曲線( align-content )周圍分配空間,而另外一個( align-self )肯定了如何在給定的彎曲線內在交叉軸上的各個彎曲項目周圍分配空間。

(我在這裏忽略*-items屬性,由於它們只是爲*-self創建默認值。)


#2樓

我知道這不是答案,可是我想爲這個問題作出貢獻。 若是他們能夠爲flexbox發佈justify-self以使其真正具備靈活性,那將是很好的。

我相信,當軸上有多個項目時, justify-self行爲的最合乎邏輯的方式是使其自身與最近的鄰居(或邊緣)對齊,以下所示。

我真正但願W3C注意到這一點,至少會考慮一下。 =)

在此處輸入圖片說明

這樣,您可使項目真正居中,而無需考慮左右框的大小。 當其中一個盒子到達中心盒子的位置時,它會簡單地將其推入,直到沒有更多的空間可分配。

在此處輸入圖片說明

製做出色佈局的簡便性無窮無盡,請看一下這個「複雜」示例。

在此處輸入圖片說明


#3樓

沿主軸對齊彈性項目的方法

如問題所述:

要沿主軸對齊彈性項目,有一個屬性: justify-content

要使彈性項沿橫軸align-content ,有三個屬性: align-contentalign-itemsalign-self

而後問題問:

爲何沒有justify-itemsjustify-self屬性?

一個答案多是: 由於沒有必要。

flexbox規範提供了兩種沿主軸對齊彈性項目的方法:

  1. justify-content關鍵字屬性,以及
  2. auto邊距

證實內容

justify-content屬性將flex項目沿flex容器的主軸對齊。

它應用於flex容器,但僅影響flex項目。

有五個對齊選項:

  • flex-start start〜Flex項目包裝在行的開頭。

    在此處輸入圖片說明

  • flex-end end〜Flex項目包裝在行尾。

    在此處輸入圖片說明

  • center 〜柔性物品被包裝到生產線的中心。

    在此處輸入圖片說明

  • space-between 〜Flex的項都均勻地隔開,具備對齊到容器的一個邊緣對準到相對的邊緣的最後一個項目的第一項。 第一項和最後一項使用的邊緣取決於flex-direction寫入模式ltrrtl )。

    在此處輸入圖片說明

  • space-around 〜與space-between相同,但兩端均留有一半大小的間隔。

    在此處輸入圖片說明


自動保證金

使用auto邊距 ,能夠將彈性項目居中,隔開或打包成子組。

與應用於flex容器的justify-content不一樣,flex項具備auto邊距功能。

它們經過消耗指定方向上的全部可用空間來工做。


將一組彈性項目向右對齊,但將第一項向左對齊

問題的場景:

  • 使一組flex項右對齊( justify-content: flex-end ),但使第一個justify-content: flex-end項向左對齊( justify-self: flex-start

    考慮帶有一組導航項和徽標的標題部分。 經過justify-self ,徽標能夠在左側對齊,而導航項保持在最右側,而且整個對象能夠平滑調整(「彎曲」)以適應不一樣的屏幕尺寸。

在此處輸入圖片說明

在此處輸入圖片說明


其餘有用的方案:

在此處輸入圖片說明

在此處輸入圖片說明

在此處輸入圖片說明


將彈性項目放在角落

問題的場景:

  • 將flex項目放置在角落.box { align-self: flex-end; justify-self: flex-end; } .box { align-self: flex-end; justify-self: flex-end; }

在此處輸入圖片說明


將彈性項目垂直和水平居中

在此處輸入圖片說明

margin: autojustify-content: centeralign-items: center的替代方法。

代替在flex容器上的此代碼:

.container {
    justify-content: center;
    align-items: center;
}

您能夠在flex項目上使用它:

.box56 {
    margin: auto;
}

居中溢出容器的flex項目居中時,此替代方法頗有用。


將彈性項目居中,將第二個彈性項目居中於第一個和邊緣之間

flex容器經過分配可用空間來對齊flex項目。

所以,爲了建立平衡 ,以便中間物品能夠在容器中居中放置單個物品,必須引入平衡。

在下面的示例中,引入了不可見的第三柔性項目(框61和68)以平衡「真實」項目(框63和66)。

在此處輸入圖片說明

在此處輸入圖片說明

固然,就語義而言,此方法並非什麼好事。

另外,您可使用僞元素代替實際的DOM元素。 或者,您可使用絕對定位。 此處介紹了全部三種方法: 居中對齊和底部對齊的彈性項目

注意:僅當最外層項目的高度/寬度相等時,以上示例纔有效(就真正居中而言)。 若是彈性商品的長度不一樣,請參見下一個示例。


當相鄰項目的大小不一樣時,將彈性項目居中

問題的場景:

  • 在三個flex項目的行中,將中間項目粘貼到容器的中心( justify-content: center ),並將相鄰的項目與容器邊緣對齊( justify-self: flex-startjustify-self: flex-end )。

    請注意,若是相鄰項目的寬度不一樣,則justify-content屬性上的space-aroundspace-between值將不會使中間項目相對於容器居中( 請參見demo )。

如前所述,除非全部flex項目的寬度或高度相同(取決於flex-direction ),不然中間項目沒法真正居中。 這個問題爲justify-self屬性(固然是設計用來處理任務)提供了強有力的justify-self

#container { display: flex; justify-content: space-between; background-color: lightyellow; } .box { height: 50px; width: 75px; background-color: springgreen; } .box1 { width: 100px; } .box3 { width: 200px; } #center { text-align: center; margin-bottom: 5px; } #center > span { background-color: aqua; padding: 2px; }
<div id="center"> <span>TRUE CENTER</span> </div> <div id="container"> <div class="box box1"></div> <div class="box box2"></div> <div class="box box3"></div> </div> <p>The middle box will be truly centered only if adjacent boxes are equal width.</p>

這是解決此問題的兩種方法:

解決方案1:絕對定位

flexbox規範容許彈性項目的絕對定位 。 這使得中間項目能夠完美地居中,而不考慮其同級大小。

請記住,與全部絕對定位的元素同樣,這些項目也會從文檔流中刪除。 這意味着它們不會佔用容器中的空間,而且可使它們的兄弟姐妹重疊。

在如下示例中,中間項目以絕對定位爲中心,而外部項目保持流入。 可是,能夠經過相反的方式實現相同的佈局:將中間項目justify-content: centerjustify-content: center並絕對定位外部項目。

在此處輸入圖片說明

解決方案2:嵌套式Flex容器(無絕對定位)

.container { display: flex; } .box { flex: 1; display: flex; justify-content: center; } .box71 > span { margin-right: auto; } .box73 > span { margin-left: auto; } /* non-essential */ .box { align-items: center; border: 1px solid #ccc; background-color: lightgreen; height: 40px; }
<div class="container"> <div class="box box71"><span>71 short</span></div> <div class="box box72"><span>72 centered</span></div> <div class="box box73"><span>73 loooooooooooooooong</span></div> </div>

運做方式以下:

  • 頂級div( .container )是一個flex容器。
  • 如今,每一個子div( .box )都是一個彈性項目。
  • 每一個.box項都指定了flex: 1以便平均分配容器空間。
  • 如今,這些項目佔用了該行中的全部空間,而且寬度相等。
  • 使每一個項目成爲一個(嵌套的)flex容器,並添加justify-content: center
  • 如今,每一個span元素都是一個居中的flex項目。
  • 使用彈性auto邊距左右移動外部span

您也能夠放棄justify-content而僅使用auto邊距。

可是justify-content能夠在這裏工做,由於auto邊距始終是優先事項。 從規格:

8.1。 auto邊距對齊

在經過justify-contentalign-self以前,任何正的自由空間都會分配給該維度中的自動邊距。


證實內容:空間相同(概念)

回到正justify-content一分鐘,這裏是一個更多選擇的想法。

  • space-same same〜 space-betweenspace-around 。 Flex項目的間距是均勻的(例如space-between ),除了兩端沒有半角空格(如space-around )外,兩端都有全角空格。

可使用flex容器上的::before::after僞元素來實現此佈局。

在此處輸入圖片說明

(信用: @oriol表明代碼, @crl表明標籤)

更新:瀏覽器已開始實現space-evenly ,從而完成了上述任務。 有關詳細信息,請參見此帖子: 伸縮項目之間的間距相等


PLAYGROUND (包括上面全部示例的代碼)


#4樓

justify-self ,可是在Chrome Canary中,而不在Chrome穩定版本中。 甚至justify-items

在此處輸入圖片說明

但據我所知,這些屬性也不起做用。 所以,可能Google事先將其保存了以用於未來的CSS版本。 只能但願他們會盡快添加屬性。


#5樓

我知道這不使用flexbox,可是對於三個項目的簡單用例(一個在左邊,一個在中心,一個在右邊),可使用display: grid輕鬆實現display: griddisplay: grid上的grid-area: 1/1/1/1;grid-area: 1/1/1/1; 在孩子justify-self ,並justify-self這些孩子justify-self定位justify-self

<div style="border: 1px solid red; display: grid; width: 100px; height: 25px;"> <div style="border: 1px solid blue; width: 25px; grid-area: 1/1/1/1; justify-self: left;"></div> <div style="border: 1px solid blue; width: 25px; grid-area: 1/1/1/1; justify-self: center;"></div> <div style="border: 1px solid blue; width: 25px; grid-area: 1/1/1/1; justify-self: right;"></div> </div>
相關文章
相關標籤/搜索