1. 程式人生 > >CSS3--彈性盒模型(display:flex)

CSS3--彈性盒模型(display:flex)

盒模型的概念並不是很陌生。
在傳統的佈局中,block不會是把塊在垂直方向上從上到下排列;inline是在水平方向排列。
而現在要介紹的CSS3的彈性盒模型並沒有這樣的限制,可以有開發人員自由操作。

優勢:彈性盒模型可以用簡單的方式免租很多常見的佈局要求。對響應式佈局有很好的適應。開發人員只是宣告佈局應具有的行為,而不需要給出具體的實現方式,瀏覽器會負責完成實際的佈局。(主流瀏覽器都得到了支援)

.div{
    display:-webkit-box;
    display:-moz-box
    -webkit-box-orient:horizontal
}

這種寫法是之前的寫法,雖然可以使用,但每次都需要加上瀏覽器字首,比較麻煩,而且在display:flex出來以後基本就拋棄了。

這是開始是乾貨
關於彈性盒模型的定義,和好處說明什麼的可以看下我前面推薦的文章,在這裡我就不多說了,直接說用法。

基本佈局
基本佈局可以說是一個容器(父元素)包含若干個條目(子元素)這種形式。

<div class="boxcontainer">
    <div class="item" style="background-color: red">1</div>
    <div class="item" style="background-color: yellow">2</div>
    <div class
="item" style="background-color: blue">3</div> <div class="item" style="background-color: orange">4</div> </div>

容器
這裡寫圖片描述

1、容器有兩個軸,主軸和交叉軸。主軸和交叉軸並不是固定為水平放下和垂直方向的,是可以定義的(這樣就靈活了)。
2、主軸尺寸:如果主軸為水平則相當於原塊元素的width。同理交叉軸尺寸就相當於height(注意前提是主軸定義為水平方向),若主軸為垂直,則主軸尺寸為height。
3、主軸起始,主軸結束可以理解為主軸開始結束的地方,同理交叉軸。

因為彈性佈局時靈活的,所以理解上訴基本概念可以很好的去學習它的屬性和值等。

條目
就是容器中的各部分,它們的基本排布又容器的屬性定義,不過一些小的變動自己也可以調整。

CSS樣式申明適用於容器或條目。

容器基本屬性
先看段程式碼

.boxcontainer{
    display:flex;
    flex-direction:row;
    flex-wrap:wrap;
}

display:flex 宣告為彈性盒模型 不用解釋就如display:block/inline一樣
flex-direction:用來確定主軸的方向。
1. row(預設) 主軸為水平方向。排列順序與文件順序相同,即從左到右
2. row-reverse: 主軸為水平 排列順序與文件誰許相反。
3. column 主軸為垂直方向,排列順序為從上到下
4. column-reverse 主軸為垂直,排列順序從下到上。
看一下具體例子:
row時:
這裡寫圖片描述
row-reverse:
這裡寫圖片描述
可以看得出來只是開始的位置變了,有點類似float:right但不是。

column
這裡寫圖片描述
column-reverse:
這裡寫圖片描述

這裡我們看下row和column的不同,因為我並沒有設定條目的大小,當為column時,會想我們認識的塊一樣佔滿整個橫向空間,但當為row時 其實就像 float:left 一樣 他們排列在一塊了。

這是對主軸方向的設定,有的時候我們需要做類似選項卡那樣的導航欄的時候就可以用row,但是要做某東和某寶的垂直導航的時候就可以將主軸設為column。
這也應證了我們之前說的一句話:開發人員只是宣告佈局應具有的行為,而不需要給出具體的實現方式,瀏覽器會負責完成實際的佈局。是不是很厲害。

flex-wrap
當條目總尺寸超過主軸尺寸時採取的行為。
1. nowrap(預設) 條目沾滿容易的主軸方向,不換行,所以可能出現重疊或超出容器的現象
2. wrap 分行(簡單地說),與交叉軸方向一致(如果交叉軸是水平則出現在右側,相信你們能理解)
3. wrap-reverse 分行,只不過方向與交叉軸方向相反(若交叉軸是垂直方向,則分出的行在前一行的上方,若交叉軸是水平的,則出現在左側)

這裡說的方向全都是用主軸方向,交叉軸方向,而不像以前的從左到右或從上到下,因為交叉軸 主軸是可變的, 畢竟單行盒模型靈活靈活嘛。

可能本來大家理解的,一看我的解釋又迷糊了,所以簡單粗暴直接上圖。
主軸為水平,交叉軸為垂直的情況(flex-direction:row):
nowrap
這裡寫圖片描述
wrap
這裡寫圖片描述
wrap-reverse
這裡寫圖片描述
主軸為垂直,交叉軸為水平的情況(flex-direction:column):
nowrap
這裡寫圖片描述
wrap
這裡寫圖片描述
wrap-reverse
這裡寫圖片描述

說明一下 我這裡條目的大小並沒有設定,只是為了演示wrap的效果將設了容器的width(主軸尺寸)或height。還是想大家好好理解下主軸和交叉軸的概念。
其他的屬性演示我不在寫兩種(主軸水平和主軸垂直),如果看了上圖還不理解主軸方向的朋友,建議自己敲一下。

flex-flow
其實是flex-direction和flex-wrap的合寫
flex-flow: row wrap

容器中的條目
以下css是用在條目上的而非容器上

條目的順序

.item{
    order:1;
}

order:值 值位數字,可以為負數,值小的位置排在前面
這個很好理解,如上面的圖,正常順序1234,如果我給4加order:-1 那麼順序就會變成4123;

條目的彈性尺寸(3個屬性)
flex-basis:接受的值與width值一樣,用來確定條目初始主軸的尺寸。
當容器主軸為水平時:設定basis值會使條目水平尺寸有變化。
這裡寫圖片描述
這裡寫圖片描述
當容器主軸為垂直時:設定basis值會使條目垂直尺寸有變化。
這裡寫圖片描述
這裡寫圖片描述

item{
    flex-basis:auto
    width:50px;
}

當flex-basis:為auto時, 則條目的寬度等於width或height的值(主軸水平)

flex-grow
表示當容器有多餘空間時,這是不同條目之間分配的比例。
值:是一個沒有單位的非負數,預設是1;平均獲得剩餘空間。
這裡寫圖片描述
以這個為例,如果他們的flex-grow為1、2、3、4的話,那麼這4個條目會額外獲得空白部分的1/10 2/10 3/10 4/10。會變成這樣
這裡寫圖片描述
來點數學哈哈。
比如空白剩餘100px, 那麼1會在他原來基礎上加上10px,一次類推加20px 30px 40px。這樣就會使條目充滿容器,而隨著容器尺寸的改變,空白尺寸也會改變,所以條目尺寸就會改變,所以對適應性佈局很合適。

flex-shrink
和flex-grow類似,只不過是當容器空間不足的時候,縮小個條目。
這裡寫圖片描述
分別使用flex-shrink:1、2、3、4後
這裡寫圖片描述

在實際操作中我發現,當我不寫flex-shrink時也不會超出容易,因為預設flex-shrink:1,只有設為0才會出現超出的樣子。
flex-shrink:1、2、3、4 會等比例的所以,所以1縮的最少,而4縮的最多。原理同grow。

flex
flex 可以同時宣告 -basis -grow -shrink
格式”none | [ <’flex-grow’> <’flex-shrink’>? || <’flex-basis’> ]”

.item{
    flex:1 1 auto;
}
.tiem{
    flex:1  //預設 flex-grow:1 flex-shrink:1 flex-basis 值為0%
}

注意:在容器分配額外空間時是以”行”為單位的。
容器先根據”flex-wrap”的屬性值來確定是單行佈局或多行佈局,然後把條目分配到對應的行中,最後在每一行內進行空白空間的分配。
看一個栗子:
容器990px 裡面有4個條目 width:300px

.boxcontainer {
 width: 990px;
}

.item {
 width: 300px;
 flex: auto;
}

這裡的flex 的意思是 flex-grow:1 -shrink:1 -basis:auto;
這裡寫圖片描述
由於容器的寬度只有 990px,所以在一行中只能排列 3 個條目,而剩下的 1 個條目則會被排列到單獨的一行中。在 3 個條目的行中,多餘的空間 90px 被平均分配給 3 個條目;而在一個條目單獨的行中,多餘的 690px 被該條目完全佔據。

條目對其
條目在容器中的對齊方式,3種方式
一、自動空白邊
即“margin:auto” 容器中的空白部分 會被margin所佔據,
比如容器100px,它的唯一條目為10px,那麼空白為90px 如果設定條目的margin-left:auto;即等於margin-left:90px 條目就會出現在右側

二、主軸方向上對齊
justify-content
這種對齊方式發生在修改條目的彈性尺寸和自動處理空白後。當某一行還有剩餘空間的時候justify-content就會分配這些空間。
看下他的值

  1. flex-start 條目集中於該行的起始位置。第一個條目與其所在行在主軸起始方向上的邊界保持對齊,其餘的條目按照順序依次排列。
  2. flex-end 條目集中於該行的結束方向。最後一個條目與其所在行在主軸結束方向上的邊界保持對齊,其餘的條目按照順序依次排列。
  3. center 條目集中於該行的中央。條目都往該行的中央排列,在主軸起始方向和結束方向上留有同樣大小的空白空間。如果空白空間不足,則條目會在兩個方向上超出同樣的空間。
  4. space-between 第一個條目與其所在行在主軸起始方向上的邊界保持對齊,最後一個條目與其所在行在主軸結束方向上的邊界保持對齊。空白空間在條目之間平均分配,使得相鄰條目之間的空白尺寸相同。
  5. space-around 類似於 space-between,不同的是第一個條目和最後一個條目與該行的邊界之間同樣存在空白空間,該空白空間的尺寸是條目之間的空白空間的尺寸的一半。
    這裡寫圖片描述

三、交叉軸方向上的對齊
align-items

  1. flex-start 條目與其所在行在交叉軸起始方向上的邊界保持對齊。
  2. flex-end 條目與其所在行在交叉軸結束方向上的邊界保持對齊。
  3. center 條目的空白邊盒子(margin box)在交叉軸上居中。如果交叉軸尺寸小於條目的尺寸,則條目會在兩個方向上超出相同大小的空間。
  4. baseline 條目在基準線上保持對齊。在所有條目中,基準線與交叉軸起始方向上的邊界距離最大的條目,它與所在行在交叉軸方向上的邊界保持對齊。
  5. stretch 如果條目的交叉軸尺寸的計算值是”auto”,則其實際使用的值會使得條目在交叉軸方向上儘可能地佔滿。
    這裡寫圖片描述

交叉軸空白處理
align-content:交叉軸方向上有空白時,對齊容器中的行
類似於justify-content,只不過align-content是對交叉軸,並且當容器只有單行時,此屬性不起作用。

  1. flex-start 行集中於容器的交叉軸起始位置。第一行與容器在交叉軸起始方向上的邊界保持對齊,其餘行按照順序依次排列。
  2. flex-end 行集中於容器的交叉軸結束位置。第一行與容器在交叉軸結束方向上的邊界保持對齊,其餘行按照順序依次排列。
  3. center 行集中於容器的中央。行都往容器的中央排列,在交叉軸起始方向和結束方向上留有同樣大小的空白空間。如果空白空間不足,則行會在兩個方向上超出同樣的空間。
  4. space-between 行在容器中均勻分佈。第一行與容器在交叉軸起始方向上的邊界保持對齊,最後一行與容器在交叉軸結束方向上的邊界保持對齊。空白空間在行之間平均分配,使得相鄰行之間的空白尺寸相同。
  5. space-around 類似於 space-between,不同的是第一行條目和最後一個行目與容器行的邊界之間同樣存在空白空間,而該空白空間的尺寸是行目之間的空白空間的尺寸的一半。
  6. stretch 伸展行來佔滿剩餘的空間。多餘的空間在行之間平均分配,使得每一行的交叉軸尺寸變大。
    這裡寫圖片描述

寫到這裡就解釋了我之前寫過的 div水平居中問題
外層div(容器) : display:flex justify-content:center align-items:center
內部div(條目不分行)
實際上就是容器內容條目 水平居中:justity-content 垂直居中 align-items:center