一起從頭學習Flex

網易考拉前端團隊發表於2017-09-08

前言

“其實我覺得flex很像現在的人——是適應性很好的生物,在家秋衣秋褲在外香肩外露。flex container看作一個環境或者大佬,flex-item是其中個體或者馬仔。個體如何存在很大程度上取決環境的設定,當然也會有一些出世的人 比如position: absolute; 存在感就有比較酷” —— 燉燉

背景:佈局模式

頁面拆開了看,無非是由眾多尺寸各異的box以不同層疊水平和順序組合而成。

CSS2.1定義了下面前4種佈局模式,不同的佈局模式下box內的渲染規則不同。

佈局 特性
block layout 塊級佈局 獨立的渲染區域,與外界無關
inline layout 行內佈局 為佈局文字設計
table layout 表格佈局 在表格格子布局二維資料
positioned layout 定位佈局 不考慮檔案流中其他元素,佈局有非常明確的位置
flex layout 彈性佈局 呈現複雜的應用與頁面

flex-layout和block-layout非常相似。

塊級佈局中一些比較複雜的屬性,比如浮動、多列,在彈性佈局中是沒有的;

反過來彈性佈局有一些很簡單但厲害的屬性去實現複雜的網頁佈局中常見的需求。

flex-container檔案

  1. 元素名:flex container
  2. 中文名:彈性容器、彈性盒
  3. 身份:大佬
  4. 年代:css3,chrome29就已經可以不加字首地支援了
  5. 權力:彈性佈局——指定容器中元素的佈局方式,子元素在其中是否收縮或伸展
  6. 被接受程度:所有的瀏覽器都支援flexbox(caniuse

    image
    image

     flex layout is split into three versions: 
     1. old version  display: box;
     2. transitional version: display:flexbox;
     3. present standard version: display:flex;
    
     Android
     2.3  began to support old version: display: -webkit-box;
     4.4 began to support standard version: display: flex;
    
     IOS
     6.1  began to support old version: display: -webkit-box;
     7.1 began to support standard version: display: flex;複製程式碼
  7. 如何成為大佬 flexdisplay:flex/inline-flex; 分別產生塊級和行內的彈性容器。

  8. 社會關係:彈性容器中的子元素——flex items
  9. 主要引數:主軸、側軸,主軸長度、側軸長度
    flexbox
    flexbox
  10. 速記幾個屬性:

    • flex-flow 子元素排列的方向和是否換行 flex-flow: [<flex-direction> <flex-wrap>]

      1. flex-direction 排列方向和順序(主軸側軸方向決定)

        flex-direction: row | row-reverse | column | column-reverse

      2. flex-wrap 主軸個數和排列順序

        flex-wrap: nowrap | wrap | wrap-reverse



        eg. flex-flow: row || column wrap || row-reverse wrap-reverse

    • justify-content 安排(決定)子元素在主軸上如何分配空白空間的方式

      justify-content: flex-start | flex-end | center | space-between | space-around

    • align-items 安排(決定)子元素在縱軸上的伸展方式

      align-items: flex-start | flex-end | center | baseline | stretch

    • align-content 多條主軸如何在縱軸方向上面排布,跟justify-content 在主軸方向對齊元素的方式相似,如果只有一行該屬性不生效

      align-content: flex-start | flex-end | center | space-between | space-around | stretch

flex-items檔案

  1. 元素名:flex item
  2. 中文名:彈性子元素
  3. 身份:flex container的馬仔
  4. 如何成為馬仔 flex-item:在flex container裡面的子元素自動成為flex item,直接包含在容器中的連續文字會被包裹成一個匿名的flex item,空白的item不會被渲染出來
  5. 職責:為其內容建立新的formatting context,flex item是flex-level的塊,所以使用彈性容器的彈性格式化上下文而不是BFC(比如在BFC中margin會坍塌在彈性格式化上下文中不會
  6. 比較酷的絕對定位的彈性子元素 特性速記
  7. 幾個重要屬性:

    • marginspaddings:flex item的margins不會重疊(應該儘量避免使用百分比的margins、paddings,在不同瀏覽器下表現不一樣,目前在IE/FF/Chrome還沒有測試出來差別啦) 百分比的基準是瀏覽器寬度

    • 有order的元素渲染順序會重置,相當於指定特定的子元素出現在什麼位置

    • visibility: collapse 看例子

    • flex 子元素的彈性

      flex: [ <flex-grow> <flex-shrink> <flex-basis>] 詳見flex縮寫探究

    • margin: auto 會“貪吃”掉所有空白的區域 例子

    • align-self 單獨設定子元素(包括絕對定位的子元素)在縱軸上的定位方式,可以覆蓋align-items屬性

      align-self: auto | flex-start | flex-end | center | baseline | stretch (auto是跟container的flex-items屬性一致)

flex縮寫的探究

flex: [ <flex-grow> <flex-shrink> <flex-basis>]

  • flex-grow 預設1 如何分配container中的空白空間,數值決定權重
  • flex-shrink 預設1 在空間不夠的時候如何收縮元素
  • flex-basis 指定flex-item的預設尺寸 百分比以父級容器寬度為基數計算(Flexbox Tester可以幫助理解flex item寬度的工具網站)
縮寫 flex-grow flex-shrink flex-basis
no declaration 0 1 auto
auto 1 1 auto
0 0 1 0%
1 1 1 0%
none 0 0 auto

彈性佈局不是塊級佈局

  1. float不生效
  2. 相鄰子元素的margin不會發生重疊
  3. 多列布局column-*不起作用
  4. 'float'和'clear'對flex item不產生浮動或者清除浮動的效果,也不會讓它脫離文件流
  5. vertical-align對於flex item沒效果
  6. 偽元素::first-line::first-letter不適用於彈性容器,彈性容器也不會成為其父元素的first-line或者first-letter

為什麼你的flexbox不管用

"瞭解一個人並不代表什麼,人是會變的"——《重慶森林》。
放在W3C規範和瀏覽器實現就是“瞭解一個屬性並不代表什麼,瀏覽器實現都是有差異的”。

W3C只是制定了規範,但是遵守程度和實現效果各個瀏覽器是有所差異的。當你清楚你想實現什麼效果而使用了對應的屬性卻發現不起作用,那麼很可能是瀏覽器的差異造成的。比如上面提到的flex縮寫,IE10的實現是不符合規範的

Declaration What it should mean What it means in IE 10
(no flex declaration) flex: 0 1 auto flex: 0 0 auto
flex: 1 flex: 1 1 0% flex: 1 0 0px
flex: auto flex: 1 1 auto flex: 1 0 auto
flex: initial flex: 0 1 auto flex: 0 0 auto

另外一個可能不常見但也能體現瀏覽器差異的是,巢狀的彈性容器的baseline不作為其他彈性子元素的對齊參考(可以在Firefox戳例子看看)。

“當你在構建頁面的時候使用了flexbox但是發現他並沒有出現你預想的效果,可以在這裡找到答案”——flexbugs

關於flex.css

flex.css就是對flex佈局的一種封裝,通過簡潔的屬性設定就能使得它完美的執行在移動端的各種瀏覽器,甚至能執行在ie10+的各種PC端瀏覽器中。是一種類似於標籤屬性宣告的方式,指定flex屬性。

<!-- 設定主軸方向 -->
<div class="flexbox" flex="dir: top">   
    ...
</div>複製程式碼
flex.css html css
dir: top flex-direction: cloumn
main: center justify-content: center
cross: top align-items: flex-start

試驗flex佈局的工具網站: flexbox playground and code generator

參考

  1. W3C flexbox
  2. flex.css快速入門,極速佈局
  3. flexbugs
  4. 使用彈性盒子進行高階佈局
  5. Flex 佈局教程:語法篇

by DDun

相關文章