Flex佈局應用

Aitter發表於2019-03-04

CSS3為我們提供了一種可伸縮的靈活的web頁面佈局方式-flexbox佈局,它具有很強大的功能,可以很輕鬆實現很多複雜佈局。然而Flex屬性較多,不便於記憶,而在專案中,佈局使用頻繁,那麼可以將flex抽離為一個佈局工具類,簡化使用方式,快速應用於專案,減少記憶成本。

Flex介紹

Flex佈局,可以簡便、完整、響應式地實現各種頁面佈局。目前,它已經得到了所有瀏覽器的支援。
Flex是 Flexible Box 的縮寫,意為”彈性佈局”,用來為盒狀模型提供最大的靈活性。

基本概念

採用Flex佈局的元素為,稱為 Flex容器,容器的直接子元素稱為 Flex專案,容器預設有兩個軸心線,用於專案的對齊與排列,水平主軸為 main axis,垂直主軸為 cross axis,主軸的開始位置為 start, 結束位置為 end

主軸和交叉軸的判定:如果flex-direction為row,則主軸是水平方向,如果是column,則主軸是垂直方向

Flex佈局應用

CSS屬性說明

將任意元素的 display 屬性設定為 flex,可將其轉換為Flex容器
設為Flex容器後,子元素的 floatclearvertical-align 屬性將失效

Flex容器屬性

主軸方向:水平排列(預設) | 水平反向排列 | 垂直排列 | 垂直反向排列
flex-direction: row | row-reverse | column | column-reverse;

換行:不換行(預設) | 換行 | 反向換行(第一行在最後面)
flex-wrap: nowrap | wrap | wrap-reverse;

flex-direction屬性和flex-wrap屬性的簡寫形式,預設值為row nowrap
flex-flow: <flex-direction> || <flex-wrap>;

主軸對齊方式:起點對齊(預設) | 終點對齊 | 居中對齊 | 兩端對齊 | 分散對齊
justify-content: flex-start | flex-end | center | space-between | space-around;

交叉軸對齊方式:拉伸對齊(預設) | 起點對齊 | 終點對齊 | 居中對齊 | 第一行文字的基線對齊
align-items: stretch | flex-start | flex-end | center | baseline;

多根軸線對齊方式:拉伸對齊(預設) | 起點對齊 | 終點對齊 | 居中對齊 | 兩端對齊 | 分散對齊
align-content: stretch | flex-start | flex-end | center | space-between | space-around;
複製程式碼

Flex專案屬性

順序:數值越小越靠前,預設為0
order: <number>; 

放大比例:預設為0,如果有剩餘空間也不放大,值為1則放大,2是1的雙倍大小,以此類推
flex-grow: <number>; 

縮小比例:預設為1,如果空間不足則會縮小,值為0不縮小
flex-shrink: <number>;

專案自身大小:預設auto,為原來的大小,可設定固定值 50px/50%
flex-basis: <length> | auto;

flex-grow, flex-shrink 和 flex-basis的簡寫,預設值為0 1 auto
兩個快捷值:auto (1 1 auto) 和 none (0 0 auto)
flex:none | [ <`flex-grow`> <`flex-shrink`>? || <`flex-basis`> ]

專案自身對齊:繼承父元素(預設) | 起點對齊 | 終點對齊 | 居中對齊 | 基線對齊 | 拉伸對齊
align-self: auto | flex-start | flex-end | center | baseline | stretch;
複製程式碼

flex.css的使用

使用data屬性來設定css樣式,便於相容現有的專案,避免樣式重名。

Flex容器配置項

標籤屬性使用方式: data-flex="xxx xxx xxx"

配置項

排列形式: row | column
間距: gutter
內容水平垂直居中: center
可換行: wrap
主軸對齊方式: main-start | main-center | main-end | main-between | main-around
交叉軸對齊方式: cross-start | cross-center | cross-end | cross-baseline | cross-stretch
多軸對齊方式: start | end | center | between | around | stretch
響應式: full
複製程式碼

Flex專案的配置項

標籤屬性使用方式: data-cell="xxx xxx xxx"

配置項

元素自身對齊方式: start | end | center | baseline | stretch
固定寬度: 1/2 | 1/3 | 1/4 | 1/5 | 1/6
排序: order[1-10]
複製程式碼

使用

基礎柵格系統

每項寬度相同,自然平分,高度預設都相同

<div data-flex="gutter">
  <div data-cell><div class="item">auto</div></div>
  <div data-cell><div class="item">auto</div></div>
  <div data-cell><div class="item">auto</div></div>
  <div data-cell><div class="item">auto</div></div>
  <div data-cell><div class="item">auto</div></div>
</div>
複製程式碼

相對的固定寬度與自適應寬度

<div data-flex="gutter row">
  <div data-cell="1/2"><div class="item">1/2</div></div>
  <div data-cell><div class="item">auto</div></div>
  <div data-cell><div class="item">auto</div></div>
</div>
複製程式碼

響應式

響應式柵格系統通過新增媒體查詢到柵格元素或柵格容器來實現。
當滿足媒體查詢的條件時,柵格系統就能自動調整。

<div data-flex="full gutter">
  <div data-cell><div class="item">full/auto</div></div>
  <div data-cell><div class="item">full/auto</div></div>
  <div data-cell><div class="item">full/auto</div></div>
</div>
複製程式碼

專案對齊

置頂對齊
專案預設是置頂對齊的,手動新增可以使用 cross-start

<div data-flex="gutter">
  <div data-cell> <div class="item">置頂對齊</div></div>
  <div data-cell> <div class="item">Pellentesque sagittis vel erat ac laoreet. Phasellus ac aliquet enim, eu aliquet sem.</div></div>
  <div data-cell> <div class="item">置頂對齊</div></div>
</div>
複製程式碼

置底對齊

<div data-flex="gutter cross-end">
  <div data-cell> <div class="item">置底對齊</div></div>
  <div data-cell> <div class="item">Pellentesque sagittis vel erat ac laoreet. Phasellus ac aliquet enim, eu aliquet sem.</div></div>
  <div data-cell> <div class="item">置底對齊</div></div>
</div>
複製程式碼

垂直居中對齊

<div data-flex="gutter cross-center">
  <div data-cell> <div class="item">居中對齊</div></div>
  <div data-cell> <div class="item">Pellentesque sagittis vel erat ac laoreet. Phasellus ac aliquet enim, eu aliquet sem.</div></div>
  <div data-cell> <div class="item">居中對齊</div></div>
</div>
複製程式碼

混合對齊
為個別專案自身設定獨立的對齊方式

<div data-flex="gutter">
  <div data-cell="start"> <div class="item">居頂對齊</div></div>
  <div data-cell="start"> <div class="item">Pellentesque sagittis vel erat ac laoreet. Phasellus ac aliquet enim, eu aliquet sem.</div></div>
  <div data-cell="center"> <div class="item">居中對齊</div></div>
  <div data-cell="end"> <div class="item">居底對齊</div></div>
</div>

複製程式碼

主軸起點對齊

<div data-flex="gutter main-start">
  <div data-cell="1/5"> <div class="item">居左對齊</div></div>
</div>
<div data-flex="gutter main-center">
  <div data-cell="1/5"> <div class="item">居中對齊</div></div>
</div>
<div data-flex="gutter main-end">
  <div data-cell="1/5"> <div class="item">居右對齊</div></div>
</div>
複製程式碼

主軸兩端對齊

<h5>兩端對齊</h5>
<div data-flex="gutter main-between">
  <div data-cell="1/5"> <div class="item">兩端對齊</div></div>
  <div data-cell="1/5"> <div class="item">兩端對齊</div></div>
  <div data-cell="1/5"> <div class="item">兩端對齊</div></div>
</div>
複製程式碼

主軸分散對齊

<h5>分散對齊</h5>
<div data-flex="gutter main-around">
  <div data-cell="1/5"> <div class="item">分散對齊</div></div>
  <div data-cell="1/5"> <div class="item">分散對齊</div></div>
  <div data-cell="1/5"> <div class="item">分散對齊</div></div>
</div>
複製程式碼

無限巢狀

柵格可以無限巢狀在另一個柵格中

<div data-flex="gutter">
  <div data-cell>
    <div class="item">
      <div data-flex="gutter">
        <div data-cell><div class="item">1</div></div>
        <div data-cell>
          <div class="item">
            <div data-flex="gutter">
              <div data-cell><div class="item">2</div></div>
              <div data-cell><div class="item">2</div></div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div data-cell="1/4"><div class="item">1/4</div></div>
</div>
複製程式碼

自定義順序

<div data-flex="gutter">
  <div data-cell="order5"><div class="item">1</div></div>
  <div data-cell="order3"><div class="item">2</div></div>
  <div data-cell="order2"><div class="item">3</div></div>
  <div data-cell="order1"><div class="item">4</div></div>
  <div data-cell="order4"><div class="item">5</div></div>
</div>
複製程式碼

相容性

flex在演化過程有三個版本,舊版本 display:box | inline-box, 混合版本 display:flexbox | inline-flexbox, 新版本 display: flex | inline-flex

.box{
	display: -webkit-box; /* 老版本語法: Safari, iOS, Android browser, older WebKit browsers. */
	display: -moz-box; /* 老版本語法: Firefox (buggy) */
	display: -ms-flexbox; /* 混合版本語法: IE 10 */
	display: -webkit-flex; /* 新版本語法: Chrome 21+ */
	display: flex; /* 新版本語法: Opera 12.1, Firefox 22+ */
}
複製程式碼

舊版相對於新版的主要區別:flex專案必須是block,沒有換行設定,沒有反向設定,主軸沒有space-around,順序值從1開始

關於新舊版的詳情對比可參考下面兩篇

這裡我們使用 postcss 外掛 autoprefixer 來自動處理新舊版的相容,配置如下:

autoprefixer({
	browsers: [
	  `ie >= 8`,
	  `ie_mob >= 10`,
	  `ff >= 26`,
	  `chrome >= 30`,
	  `safari >= 6`,
	  `opera >= 23`,
	  `ios >= 5`,
	  `android >= 2.3`,
	  `bb >= 10`
	]
})
複製程式碼

** 這裡只做了語法上的相容,但是舊版所沒有的特性仍然要警慎使用,參考上面的區別,相信以後隨著瀏覽器的升級,差別會越來越小 **

示例

flex.css 的具體原始碼,請參考示例

See the Pen <a href=`http://codepen.io/togglelt/pen/BpPJQP/`>Flex佈局應用</a> by LT (<a href=`http://codepen.io/togglelt`>@togglelt</a>) on <a href=`http://codepen.io`>CodePen</a>.

參考閱讀