深入理解CSS彈性盒模型flex


前面的話

  CSS3引入了一種新的布局模型——flex布局。flex是flexible box的縮寫,一般稱之為彈性盒模型。和CSS3其他屬性不一樣,flexbox並不是一個屬性,而是一個模塊,包括多個CSS3屬性。flex布局提供一種更加有效的方式來進行容器內的項目布局,以適應各種類型的顯示設備和各種尺寸的屏幕

 

版本更迭

  flexbox布局的語法規范經過幾年發生了很大的變化。從2007年07月,flex第一版本的工作草案發布,到2012年09月,flex最新版本成為候選推薦。flex主要經歷了三個版本

【1】舊版本 display:box | inline-box;

   IE瀏覽器不支持,windows下的safari瀏覽器只支持舊版本的寫法且需要添加前綴,移動端可以兼容到andriod2.1-4.3和ios3.2-6.1也需要添加前綴

【2】混合版本 display:flexbox | inline-flexbox;

  該版本只有IE10支持,且需要添加前綴-ms-

【3】新版本 display: flex | inline-flex

  該版本兼容IE11+、firefox、safari、chrome、opera及移動端,但移動端ios7.1-8.4需要添加前綴-webkit-

 

display

  要讓一個元素變成伸縮容器,需要使用display屬性。采用flex布局的元素,稱為伸縮容器(flex container),容器內的子元素稱為伸縮項目(flex item)

  [注意]瀏覽器會將任何直接在伸縮容器里的連續文字塊包起來成為匿名伸縮項目

  使用flex布局實現上是使元素FFC化(flex formatting context伸縮格式化上下文),FFC是普通流的一種。而浮動流和定位流以及CSS其他屬性對FFC是有影響的,主要表現在以下幾點:

  [1]float、clear和vertical-align屬性在伸縮項目上沒有效果

  [2]伸縮容器的margin與其內容的margin不會重疊

  [3]text-align屬性在伸縮容器上沒有效果,因為其只可應用於塊級block容器

  [4]另外,columns屬性伸縮容器上沒有效果

  彈性盒模型的兩種容器塊級伸縮容器和內聯伸縮容器的區別類似於block和inline-block的區別,一個獨占一行,另一個非獨占一行

//彈性盒模型: 塊級伸縮容器 | 內聯伸縮容器
//新版本
display: flex | inline-flex;
//混合版本
display: flexbox | inline-flexbox;
//舊版本
display: box | inline-box;

基本概念

  伸縮容器默認存在兩條軸: 水平的主軸(main axis) 和垂直的側軸(cross axis)

  [注意]主軸方向不一定是水平的,它主要取決於flex-direction屬性

  主軸起點叫main start,主軸終點叫main end;側軸起點叫cross start,側軸終點叫cross end

  伸縮項目默認沿主軸排列。單個伸縮項目占據的主軸空間叫main size ,占據的側軸空間叫cross size

  [注意]伸縮項目的main size和cross size主要由寬度或高度決定

 

伸縮容器

  以下6個屬性作用在伸縮容器上

  伸縮流方向 flex-direction

  伸縮流換行 flex-wrap

  伸縮流(包括方向與換行) flex-flow

  主軸對齊 justify-content

  側軸對齊 align-items

  堆棧伸縮行 align-content

【1】伸縮流方向:指定主軸的方向(即伸縮項目在伸縮容器中的排列方向)

//伸縮流方向: 水平方向 | 反向水平 | 垂直方向 | 反向垂直
//新版本同混合版本
flex-direction: row[默認] | row-reverse | column | column-reverse
//舊版本
box-orient: horizontal(水平) |vertical(垂直) |inline-axis[默認](內聯軸方向) |block-axis(塊級軸方向)
box-direction: normal(正常) | reverse(反向) 

  [注意]伸縮流方向與direction和writing-mode有關系

【2】伸縮流換行:指定伸縮項目溢出伸縮容器時是否換行

//伸縮行換行:不換行 | 換行 | 反轉換行
//新版本同混合版本
flex-wrap: nowrap[默認] | wrap | wrap-reverse
//舊版本,沒有瀏覽器支持box-lines屬性,所以在舊版本中無法實現伸縮項目換行顯示
box-lines: single[默認] | multiple | N/A

  [注意]此時,CSS允許使用overflow屬性來處理溢出內容的顯示方式

  [注意]伸縮項目的排列順序同樣與direction和wrinting-mode有關系

【3】伸縮流:伸縮流方向與伸縮行換行的縮寫

//伸縮流: 伸縮流方向 | 伸縮行換行
//新版本同混合版本
flex-flow: <flex-direction> | <flex-wrap> 
[默認值] flex-flow: row nowrap
//舊版本無對應屬性

【4】主軸對齊:用來設置伸縮容器當前行伸縮項目在主軸方向的對齊方式,指定如何在伸縮項目之間分布伸縮容器額外空間

  當一行上的所伸縮項目不能伸縮或可伸縮已達到最大長度時,這一屬性才會對伸縮容器額外空間進行分配。當伸縮項目溢出某一行時,這一屬性也會在項目的對齊上施加一些控制

//主軸對齊方式: 左對齊 | 居中對齊 | 右對齊 | 兩端對齊 | 擴散對齊
//新版本
justify-content: flex-start[默認] | center | flex-end | space-between | space-around
//混合版本
flex-pack: start[默認] | center | end | justify | distribute
//舊版本
box-pack: start[默認] | center | end | justify | N/A

  [注意]主軸對齊方式與direction、writing-mode、flex-flow都有關

【5】側軸對齊:用來設置伸縮容器當前行在側軸方向的對齊方式

//側軸對齊方式: 頂邊對齊 | 中間對齊 | 底部對齊 | 基線對齊 | 伸縮項目拉伸填充整個伸縮容器
//新版本
align-items: flex-start | center | flex-end | baseline | stretch[默認]
//混合版本
flex-align: start | center | end | baseline | stretch[默認]
//舊版本
box-align: start | center | end | baseline | stretch[默認]

  [注意]如果伸縮項目有width/height屬性將優先於側軸對齊為拉伸的方式

  [注意]側軸對齊方式與direction、writing-mode、flex-flow都有關

【6】堆棧伸縮行:指定多個伸縮項目行在側軸的對齊方式

//側軸對齊方式: 頂邊對齊 | 中間對齊 | 底部對齊 | 兩端對齊 | 擴散對齊 | 伸縮項目拉伸填充整個伸縮容器
//新版本
align-content: flex-start | center | flex-end | space-between | space-around | stretch[默認]
//混合版本
flex-line-pack: start | center | end | justify | distribute | stretch[默認]
//舊版本無對應屬性

  [注意]該屬性只有在flex-wrap:wrap | wrap-reverse;且伸縮項目存在多行時才生效

  [注意]堆棧伸縮行與direction、writing-mode、flex-flow都有關

伸縮項目

  一個伸縮項目就是伸縮容器的一個子元素。伸縮容器中的文本也被視為一個伸縮項目。以下6個屬性設置在伸縮項目上。

  自身側軸對齊方式 align-self

  伸縮基准值 flex-basis

  擴展比率 flex-grow

  收縮比率 flex-shrink

  伸縮性 flex

  顯示順序 order

【1】自身側軸對齊方式:單個伸縮項目在側軸的對齊方式,該屬性可以覆蓋伸縮容器的側軸對齊方式

  [注意]對於匿名伸縮項目,align-self的值永遠與其關聯的伸縮容器的align-items的值相同

//側軸對齊方式: 自動 | 頂邊對齊 | 中間對齊 | 底部對齊 | 基線對齊 | 伸縮項目拉伸填充整個伸縮容器
//新版本
align-self: auto[默認] | flex-start | center | flex-end | baseline | stretch
//混合版本
flex-item-align: auto[默認] | start | center | end | baseline | stretch
//舊版本無對應屬性

  [注意]如果align-self的值為auto,則其計算值為伸縮項目的伸縮容器的align-items值

  [注意]如果伸縮項目的任一個側軸上的外邊距為auto,則該伸縮項目在伸縮容器的剩余空間內居中對齊,且align-self沒有效果。

【2】伸縮基准值: 伸縮項目在主軸方向上的初始大小

//新版本
flex-basis: <length> | auto[默認]
//混合版本
positive-flex: <number>[默認為1]
//舊版本無對應屬性

  如果flex-basis的值為0,表示伸縮項目在主軸方向上的初始大小為0,分配所有空間;如果flex-basis的值為auto,表示伸縮項目在主軸方向上的初始大小為設置寬度(如果沒有設置寬度,則為內容寬度),再分配剩余空間

  [注意]flex-basis的<length>值可以是一個數字后面跟着px、em等單位,也可以是一個百分數,相對於其父伸縮容器的主軸長度

【3】擴展比率: 當伸縮容器的額外空間為正值時,此伸縮項目相對伸縮容器里其他伸縮項目能擴展的空間比例

//新版本
flex-grow: <number>[默認為0]
//混合版本
positive-flex: <number>[默認為0]
//舊版本無對應屬性

  若flex-grow的值為0表示即使存在剩余空間也不放大;若所有項目的flex-grow屬性都為1,則它們將等分剩余空間(如果有的話);若一個項目的flex-grow屬性為2,其他項目都為1,則前者占據的剩余空間將比其他項多一倍

【4】收縮比率:當伸縮容器的額外空間為負值時,此伸縮項目相對於伸縮容器里其他伸縮項目能收縮的空間比例

//新版本
flex-shrink: <number>[默認為1]
//混合版本
negative-flex: <number>[默認為0]
//舊版本無對應屬性

  如果所有項目的flex-shrink屬性都為1,當空間不足時,都將等比例縮小。如果一個項目的flex-shrink屬性為0,其他項目都為1,則空間不足時,前者不縮小。

  [注意]伸縮基准值、擴展比率和收縮比率都可以為小數,但不能為負數

【5】伸縮性:是擴展比率、收縮比率和伸縮基准值的縮寫

    flex: none => flex: 0 0 auto;//表示寬度為原始寬度,不發生擴展或收縮
    flex: auto => flex: 1 1 auto;//表示除了占據原先的寬度外,還要分配剩余寬度(包括擴展或收縮)
    flex: 0 => flex: 0 1 0%;//表示收縮為最小寬度
    flex: 1 => flex: 1 1 0%;//表示分配所有寬度(包括擴展或收縮)
    flex: 0 auto => flex: 0 1 auto;(默認值)//表除了占據原先的寬度外,還要分配剩余寬度(只收縮,不擴展)
    flex: 0 1 => flex: 0 1 0%;

  [注意]當flex為關鍵字none或存在auto時,flex-basis為auto;若flex只有數字值,則flex-basis為0%;

//新版本
flex: none | [<flex-grow> <flex-shrink>? || <flex-basis>]
//混合版本
flex: none | [<pos-flex> <neg-flex>? || <preferred-size>]
//舊版本
box-flex: <number>

【6】顯示順序: 定義伸縮項目的排列順序,數值越小,排列越靠前

  [注意]伸縮容器中的伸縮項目默認顯示順序是遵循文檔在源碼中出現的先后順序(HTML文檔的DOM結構中的先后順序)

//新版本
order: <number>[默認為0]
//混合版本
flex-order: <number>[默認為0]
//舊版本
box-ordinal-group: <integer>[默認為1]

  [注意]order的屬性值可以是負數,但不能是小數


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM