flex入門—瞭解這些flex屬性

LT_bear發表於2018-05-29

傳統的頁面佈局

  在flex出現之前,雙列布局,三列布局,動態盒居中,絕對居中佈局等常見的佈局均是採用dispaly+float+定位來佈局的,一般包括以下幾種佈局策略:

  1. normal flow(文件流:塊級元素從上到下,行內元素從左到右)
  2. float + clear
  3. position relative + absolute
  4. display inline-block
  5. 負margin(擴大寬度,產生位移,如一行裡的多個column)

flex來了

  flex-即flexible,彈性的,靈活的,又叫彈性盒佈局(flexible box layout),這種佈局方式主要有以下特點:

  1. 塊級佈局側重垂直方向,行內佈局側重水平方向,而flex是與方向無關的(來源於後續提到的一個重要屬性flex-direction)
  2. flex佈局可以實現空間自動分配、自動對齊(彈性靈活的體現,與後續提到的flex-grow,flex-shrink,flex-basis屬性有很大關係)
  3. flex適用於簡單的線性佈局(左右或上下佈局),更復雜的佈局需要用grid佈局(如瀑布流佈局)

基本概念

flex入門—瞭解這些flex屬性

  關於flex佈局中,有以下幾個基本常識值得注意:

  1. 如圖所示flex佈局中有兩條軸線貫穿了外層容器,分別為主軸和側軸(這裡主軸不一定是水平方向的軸線,具體有flex-direction而定,即主軸和側軸的方向是不一定的,也印證了flex佈局是方向無關的)
  2. 主軸的尺寸為main size,側軸的尺寸為cross size
  3. 主軸的起點和終點分別為main start和main end,對應的側軸的起點和終點分別為cross start和cross end
  4. 應用了display:flex屬性的元素叫做 flex container,即flex容器,它裡面的子元素叫做flex item
  5. flex 容器的寬度總是自動擴張到最大值(注意是寬度,不管主軸是哪個方向,它的寬度總是會擴張到最大值,即使這個容器元素是行內元素如span,而子元素的寬度受多個屬性影響,如flex-direction,align-items,flex-grow等,有時候看起來容器元素的寬度並不等於item元素寬度的和,如下圖2所示)
  6. flex 容器內的子元素即flex-item在不指定height,width的情況下總是自動收縮的(height本來就自動收縮,但當父元素display:flex後,這些子元素的寬度也都自動收縮,而沒有了原本塊級元素在寬度上自動擴張的特性),同樣的,這裡不區分主軸的方向,height,width總是自動收縮
  7. display:flex以後 float,clear,vertical-align等屬性均失效

flex container的六大屬性

flex-direction—方向

  flex-direction 指定了子元素排列的方式,可以為row(按行展示)/column(按列展示)/inherit/row-reverse/column-reverse

例1. 當flex-direction為row時,顯示效果如下:

flex入門—瞭解這些flex屬性
圖2

其中html和css程式碼如下:

<div class="container">
    <div class="item">item1</div>
    <div class="item">item2</div>
</div>

.container{
  display:flex;
  border:1px solid red;
  height:300px;
}
.item{
  border:1px solid black;
}
複製程式碼

例2.當為.container新增flex-direction:cloumn屬性後,排列效果如下:

flex入門—瞭解這些flex屬性
圖3

  圖2,圖3中的flex-item都沒有指定width和height值,但我們通過border可以看到看到,圖2中的垂直方向的空間自動填滿了container的寬度,即container此時在主軸方向的長度,圖3中的水平方向的空間自動填滿了container的高度,同樣的,這也是container此時在側軸方向的長度,這個現在和後續提到的align-items有關,不過我們暫時可以做出如下總結: 預設情況下,flex-item元素在其側軸方向的長度總是自動擴張的(當然,後續會知道,只是預設情況,稍微改變align-items屬性值,表現就會不一樣~)

flex-wrap

  用於控制是否可以換行(按row排列時)/列(按column排列時),當flex-wrap是nowrap時,所有items總是自動縮小而不會換行(列)

flex-flow

  flex-direction和flex-wrap的縮寫,如flex:row wrap實際上同時設定了 flex-direction:row和flex-wrap:wrap;

justify-content

  主軸方向的對齊方式,可取:flex-start/flex-end/center/space-around/space-between,預設為flex-start

align-items

  側軸方向的對齊方式,可取:flex-start/flex-end/center/stretch/baseline,預設為stretch(填滿父空間,前提是不指定height值,當指定了height值時,會以該值為主),也就是之前提到的預設情況下,flex-item元素在其側軸方向的長度總是自動擴張的

align-itmes:stretch和height同時存在時

  為了測試指定height時,align-items:stretch還是否會對元素項產生效果,進行了以下測試:

 <div class="outer">
    <div>item1</div>
    <div>item2</div>
    <div>item3</div>
    <div>item4</div>
</div>

.outer{
    align-items:stretch;
}
.outer div:nth-child(1){
  height:200px;
}
複製程式碼
flex入門—瞭解這些flex屬性

  如圖所示,由於align-items是stretch(也是預設值),所以除item1元素外的所有元素在側軸方向都自動拉伸到最大了,而item1之所以沒有自動拉伸,是因為對其顯示設定了高度,此時可以理解為height屬性的優先順序要更高。

align-content

  align-content屬性和justify-content,align-items是類似的,都是控制item元素之間的擺放方式,只是該屬性只有在主軸方向上有多個軸線時才有效,如flex-direction是row時,如果item有換行則align-cnotent屬性值有效,當flex-direction是clolumn時,如果item有換列,則align-content有效,其中屬性值可以取flex-start/flex-end/center/space-around/space-between/stretch

注意:justify-content是用於控制屬於不同的主軸線(可以想象為平行與主軸線)的元素在側軸方向的的排列方式,其屬性值包含space-around/space-between,沒有stretch,而align-items是用於控制單個元素在側軸方向的擺放的,其屬性值包含stretch,不含space-around/space-between,align-content則用於控制當同一個側軸有多個元素時,這些元素之間的擺放方式,它們即可取space-around/space-between,又可取stretch(當每一個側軸都只穿過一個元素時(即沒有多個主軸線,沒換行/列),該屬性失效)

align-content和align-items屬性同時指定時

  以flex-direction:row時為例,當item有多行時,align-content和align-items是同時有效的,align-content控制行於行之間的排列關係,align-items控制元素在一行中的位置,可以看下以下例子:

html和css部分如下:


  <div class="outer">
    <div>item1</div>
    <div>item2</div>
    <div>item3</div>
    <div>item4</div>
  </div>

.outer{
  display:flex;
  border:1px solid red;
  height:300px;
  align-items:center;
  flex-wrap:wrap;
  align-content:flex-end;
}
.outer div{
  width:200px;
  border:1px solid black;
}
.outer div:nth-child(1){
  height:200px;
}

複製程式碼

效果如下所示:

flex入門—瞭解這些flex屬性
圖4

  可以看到,現在item1和item2是處於一行的,item3和item4是處於一行的,由於align-content是flex-end,所以所有行依次排列在側軸的終點處,同時由於align-items為center,所以item2處於它所在行的垂直方向的中點處(原來並非相對於它的父元素垂直居中,而是相對於它所在的行垂直居中)

  接下來,再看一下把align-items:center去掉的效果

flex入門—瞭解這些flex屬性
圖5

  如圖5所示,和剛才不同的是,item2在沒有指定高度的情況下自動拉伸為何item1的高度(指定了200px)一樣了,其實還是因為align-items的效果,它雖然沒有顯示指定,但它的預設值是stretch,所以在它所處的行中在垂直方向自動拉伸了。

  所以,當align-content有效時,不要以為align-items就無效了,只是它們的作用不同而已,一個控制不同行元素相對於父元素(flex-container)的排列方式,一個用於控制元素在所處行中的垂直方向的位置(這裡指的flex-direction為row,flex-direction為column時請自行推算~)

flex item的六大屬性

flex-grow:多餘空間自動分配比例

  用於控制當主軸方向空間過多時,元素在主軸方向的長度自動增加;如果多個元素同時指定了flex-grow,則多餘的空間會按照各自flex-grow值的比例自動分配

預設值:0

flex-shrink:超出空間自動收縮比例

  當主軸方向空間不夠時,使元素在主軸方向的長度自動收縮(即使為元素項設定了顯示寬度width值,依然會根據需要自動收縮,不同於之前container中的align-items屬性值stretch會低於height的優先順序),以使得總長度能夠適應container的長度(當應用了flex-wrap:wrap時,一般是不會自動收縮的,因為這時候自動換行/列了,不會空間不夠)

預設值:1

flex-shrink和flex-wrap配合使用

  flex-shrink的概念已經明瞭,看上去功能比較單一,不過不同的屬性值之間的搭配還是會帶來很多樣化得效果的,尤其是這裡就來看一下flex-shrink和flex-wrap的配合使用。

flex-shrink:0和flex-wrap:nowrap

  下面看一下flex-shrink為0並且container沒有設定flex-wrap屬性時的效果:

  html和css如下:

 <div class="outer">
    <div>item1</div>
    <div>item2</div>
    <div>item3</div>
    <div>item4</div>
  </div>

.outer{
  display:flex;
  border:1px solid red;
  height:300px;
  align-content:flex-end;
}
.outer div{
  width:150px;
  
  border:1px solid black;
  flex-shrink:0;
}
.outer div:nth-child(1){
  height:200px;
}
.outer div:nth-child(2){
}

複製程式碼
flex入門—瞭解這些flex屬性
圖6

  如上圖所示,當設定item的flex-shrink為0時,說明子元素項不會自動收縮,造成的結果就是所有元素項按自身原本的尺寸依次排列,可能會有主軸上總長度超出container在該放向的長度的可能。

flex-shrink:1和flex-wrap:nowrap

  接下來,將css中設定的flex-shrink:0去掉(等同於設定了flex-shrink:1,因為這是預設值),此時效果如下:

flex入門—瞭解這些flex屬性
圖7

  如上圖所示,此時,各子元素項的寬度(在主軸方向的長度)明顯收縮了(小於為其設定的width:150px),這就是因為預設的flex-shrink:1使得超出的部分均分在了所有子元素項的寬度上。

flex-shrink:1和flex-wrap:wrap

  最後,再為container新增flex-wrap:wrap看下是否又會有什麼不同呢?

flex入門—瞭解這些flex屬性
圖8

  如圖8所示,此時子元素項懂得在合適的位置自動換行了,因此也就不存在寬度超出父元素寬度範圍的情況了,所以即使設定了flex-shrink也不會出現長度收縮了~

flex-basis 原始大小

  我們都知道為container設定了display:flex後,子元素項的寬度正是恰好包裹自身內容的寬度,相當於是自動的,設定flex-basis後則類似於設定了width值,可以顯示指定寬度,取值可以為絕對單位或是百分比(可用於柵格效果)

預設值:auto

flex 縮寫

  flex屬性即為flex-grow,flex-shrink,flex-basis三個屬性的縮寫

order 指定次序

  order用於指定子元素項在兄弟元素中排列的順序,應用該屬性可以簡單的實現雙飛翼佈局

align-self 自身的對齊方式(特殊化自身元素)

  align-self指定元素自身在側軸上的對齊方式,可以用來覆蓋align-items屬性的值對自身設定的效果

flex入門—瞭解這些flex屬性
圖9

  如圖9所示,當align-items為stretch,item1的align-slef為center時,除item1外的所有元素在側軸方向的對齊方式都是自動延伸的,而item1元素因為應用了align-slef:center,明顯是垂直居中的。

  想了解不同佈局的flex實現方式的話,請戳進一步瞭解flex佈局—來實現這些常見佈局吧~

相關文章