- 原文地址:Flexbox Fundamentals
- 原文做者:Marina-ferreira
整理自 MDN web docs 的筆記,同時參考了 Web Bos 上的什麼是 Flexbox系列視頻。css
Flexbox 是 Flexible Box Module
的縮寫。 它是一種佈局模型,容許咱們方便地控制 html 元素之間的空間分佈和對齊 [2]。html
Flexbox 一次只能控制一個維度的定位(行或者列)。二維定位的控制須要依靠網格佈局 [2]。ios
給出如下模板:git
<body> <div class="container"> <div class="box box-1">1</div> <div class="box box-2">2</div> <div class="box box-3">3</div> <div class="box box-4">4</div> <div class="box box-5">5</div> <div class="box box-6">6</div> <div class="box box-7">7</div> <div class="box box-8">8</div> <div class="box box-9">9</div> <div class="box box-10">10</div> </div> </body>
上面 div 的行爲默認遵循正常的 html 文檔流,所以從上到下、從左到右進行渲染,而且會佔據整個 body 的寬度,由於它們的 display
屬性默認是 block
。github
當爲 .container
div 設置 display: flex
時,全部的直接子 div 將成爲彈性項目,而且得到新的行爲 [2]:web
flex-direction
默認值爲 row
,所以它們會呈一行排列
flex-basis
默認值爲 auto
(項目寬度將取決於其自身的內容)flex-wrap
默認值爲 nowrap
(若是容器的寬度不足以囊括全部的項目,則項目不會換行,只會溢出)出於可視化的目的,咱們拉伸容器以佔據整個高度。npm
display: flex
使容器拓展整個可用寬度;與之相對的,display: inline-flex
使容器寬度塌陷至與內容寬度相等。json
一旦聲明爲彈性容器,咱們就能夠將元素看做位於兩條軸中。一條是由 flex-direction
定義的主軸,一條是與前者垂直的交叉軸 [2]。gulp
flex-direction
屬性有四個值: row
, row-reverse
, column
和 column-reverse
.瀏覽器
默認值是 row
,它將主軸設置爲從左到右的水平方向,而交叉軸從上到下與之垂直相交。同理,column
將主軸設置爲從上到下的垂直方向,而交叉軸則是從左到右。對這兩個值添加 reverse
,則主軸將反轉 180°,而交叉軸保持不變 1。
能夠經過下圖觀察這些值對應的彈性項目行爲:
當容器空間不足以容納所有彈性項目時,利用 flex-wrap
屬性處理彈性項目 [3]。
flex-wrap
的默認值爲 nowrap
,這意味着若是容器不能在保留項目原始寬度的同時將它們排列成一行的話,項目將會收縮以進行適應。若是因爲某些緣由沒法收縮,則項目會溢出容器外 1。
經過給項目設置 300px 的寬度,nowrap
選項輸出下面這個結果:
其中,每一個項目收縮到大約 70px 以適應容器。
當屬性值更新爲 wrap
時,項目的寬度將等於原先的值,300px。當第一行的寬度不足以容納 300px 時,項目再也不溢出容器外,而是會換行 [3]。每一行都應該被視爲是一個獨立的彈性容器,任何一個容器內的空間分佈均不會影響與之相鄰的其餘容器 [2]。
可是爲何彈性項目會佔據整個屏幕的高度呢?在第一部分,容器高度被設置爲 100vh,所以可用空間被這四行平分以適應 300px 的項目。假如咱們沒有設置 100vh,則容器高度將等於項目內容的高度,以下圖所示 [1]:
另外一個選項是 wrap-reverse
,它將會反轉交叉軸。經過屬性 flex-direction
設置的從上到下的方向會被 wrap-reverse
轉化爲從下到上 [1]。
經過 flex-direction: column
反轉主軸,容納不下的元素將會換行至另外一列,同時剩餘空間會被平分 [1]。
wrap-reverse
選項與 column
方向搭配使用,則將反轉交叉軸的方向爲從右到左,產生以下輸出:
彈性佈局是一維佈局,雖然在反轉換行的時候,項目會從下到上排列(在方向爲 row 的狀況下),可是依然保持着從左到右的結構。改變的只有交叉軸。
flex-direction
和 flex-wrap
能夠在一個單屬性中進行聲明: flex-flow: [direction] [wrap]
[2]。
.flex-container { flex-flow : column wrap; }
回到主軸方向爲 row 且進行換行的狀況。經過給項目設置 width: 33.3333%
,容器可以徹底被填滿。
可是當你讓子 div 之間有空隙時,它們將不會像預期的那樣進行換行:
能夠經過使用 CSS 函數 calc()
解決這個問題 [1]:
.flex-item { width: calc(33.33333% - 40px); margin: 20px; }
爲了消除容器邊緣的空間,這裏對容器設置負外邊距 [3]:
.flex-container { margin: -20px; }
order
屬性容許修改項目的呈現順序。順序是以組爲單位進行分配的。默認狀況下全部的彈性項目都設置爲 order:0
,這意味着全部的項目位於同一組,而且它們會按照原始順序進行定位。若是有兩個或者兩個以上的組,那麼各組將會相對於它們的整數值進行排序 [4]。
在下面的例子中,有三個順序組
, -1
, 0
和 1
,它們按照以下順序排列。
.box-3 { order: 1; } .box-7 { order: 1; } .box-8 { order: -1; }
表面上,這個屬性從新分配了項目,但在諸如使用 tab 鍵對它們進行遍歷的交互中則依然保留它們的原始位置。若是項目順序與可訪問性有關的話,這一點是須要考慮的。同理, flex-direction
也是這樣 [4]。
在彈性佈局中,沿着軸的項目對齊和空間分佈能夠經過四個屬性控制 [5]:
justify-content
:將全部項目在主軸上對齊align-items
:將全部項目在交叉軸上對齊align-self
:將單個項目在主軸上對齊align-content
:控制交叉軸上各條線之間的空間
justify-content
是一個在主軸上處理項目的容器屬性。最經常使用的 6 個值是: flex-start
, flex-end
, center
, space-around
, space-between
, space-evenly
。其中,默認值爲 flex-start
。
align-items
一樣是一個容器屬性,它在交叉軸上處理項目的對齊。 默認值是 stretch
,其餘值是 flex-start
, flex-end
, center
和 baseline
[5]。
若是設置了容器高度,則 stretch
屬性值會使全部的項目伸展至與容器等高;若是沒有設置,則全部項目與最高的項目等高 [5]。上面第一張圖片中容器高度設置爲 100vh
,第二張圖片則沒有設置高度。
align-content
是第四個也是最後一個容器屬性,它在交叉軸上分配各條線之間的空間。做爲最後一個屬性,它的初始值爲 stretch
,而且和 justify-content
同樣接受如下幾個屬性值:flex-start
, flex-end
, center
, space-around
, space-between
, space-evenly
[5]。
align-items
屬性其實是經過給容器內的全部項目設置 align-self
而生效的。經過單獨設置 align-self
,能夠覆蓋先前設置的總的屬性值。該屬性和 align-items
擁有相同的可選值,可是還多了一個 ‘auto’ [5]。
auto
會重置 align-self
的值,使之從新等於經過 align-items
給容器全局定義的值 [5]。
項目的大小和彈性能夠經過三個屬性控制:flex-grow
,flex-shrink
和 flex-basis
。這些屬性都在主軸上發揮做用 [2]。
flex-grow
:若是有額外空間,每一個項目應該如何伸展flex-shrink
:若是空間不足,每一個項目應該如何收縮flex-basis
:在設置以上兩個屬性以前項目的大小該屬性設置的是彈性增加係數
,這是一個用於處理項目之間相對大小的比率 [7]。
默認值是 0,這意味着若是有剩餘空間,就把這個空間放在最後一個項目的後面 [1]。
在上面的例子中,direction
設置爲 row
,每一個彈性項目的寬度是 60px
。因爲容器的寬度是 980px
,所以有 680px
的可用空間,這個空間稱爲 正向自由空間
[7]。
經過將 flex-grow
設置爲 1
,正向自由空間將會被彈性項目平分。每一個項目的寬度都會增長 136px
,總的寬度是 196px
[7]。
經過給第三個項目設置 flex-grow: 2
,它得到的可用正向自由空間是其餘項目的兩倍,即比起其餘項目的 173px
,它的總寬度爲 286px
[7]。
下圖中,項目的 flex-grow
屬性設置爲自身的內容值。
當容器沒有足夠空間來容納全部項目時,使用 flex-shrink
處理項目大小。所以,它經過收縮項目來處理它們的負向自由空間 [7]。
以下圖所示,980px
的容器存放着 5 個 300px
寬度的容器。因爲沒有足夠空間來容納所須要的 1500px
,默認的彈性收縮係數
1
會使每一個項目收縮至 196px
。
經過給第三個項目設置 2
的比率,它會比其它項目小兩倍。
下圖中,每一個項目以自身內容值做爲彈性收縮比率。
flex-basis
屬性會在實際設置可用空間以前檢查每一個項目應該具備的大小。默認值是 auto
,項目寬度要麼經過 width
顯式設置,要麼等於內容寬度。它一樣也接受像素值 [7]。
下面的 gif 展現了一個 800px
寬度的容器和 5 個設置了 flex-basis: 160px
的彈性項目。這告訴瀏覽器:理想狀況下有足夠的空間放置全部的項目,項目的 160px
寬度將會獲得保留,而且沒有正向/負向自由空間。若是沒有足夠的空間,因爲 flex-shrink
默認爲 1
,全部的項目會均勻地收縮。若是有剩餘的空間,因爲 flex-grow
默認爲 0
,剩餘空間會放置在最後一個項目的後面。
下面的 gif 中,項目 1 設置爲 flex-shrink: 10
,項目 4 設置爲 flex-grow: 10
。對於負向自由空間,項目 1 減少的寬度是其它項目減少寬度的 10 倍;對於正向自由空間,項目 4 增長的寬度是其它項目增長寬度的 10 倍。
flex-basis
還能夠接受值 content
。此時,不管有沒有設置 width
,自由空間計算都只會基於項目內容去計算寬度。若是你不打算在計算時考慮項目寬度,則將其設置爲 0
。
flex
是 flex-grow
, flex-shrink
和 flex-basis
的簡寫屬性 [2]。
它接受下面的預約於值:
initial
:重置爲彈性佈局的默認值,與 flex: 0 1 auto 效果同樣auto
:彈性項目能夠根據須要伸展/收縮,與 flex: 1 1 auto 效果同樣none
:使項目失去彈性,與 flex: 0 0 auto 效果同樣flex: 1
:彈性項目能夠伸展/收縮,而且 flex-basis
設置爲 0 ,與 flex: 1 1 0 效果同樣考慮到跨瀏覽器兼容性,給屬性加上全部必要的前綴很重要,這能夠確保提供全面的支持 [1]。
手動給每一個屬性添加前綴是一項很是繁瑣的任務,而且還會徒增樣式維護的難度。做爲替代方法,Gulp 能夠自動化地完成這些任務。
要使用 Gulp,咱們須要將其做爲依賴項添加到項目中。這是經過 package.json
文件完成的,它負責跟蹤依賴項及其版本。經過終端建立文件類型 [1]:
🌹 npm init
在提示下輸入信息,點擊回車鍵進行確認。輸出文件大概相似下面這樣:
{ "name": "project-name", "version": "1.0.0", "description": "Project description", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "Author Name", "license": "ISC" }
全局安裝 gulp :
🌹 npm install gulp -g
安裝 gulp 和 gulp-autoprefixer 做爲項目的依賴性:
🌹 npm install gulp --save-dev 🌹 npm install gulp-autoprefixer --save-dev
它們會出如今 package.json
文件的 devDependencies
鍵下。
建立一個 gulpfile.js
文件:
🌹 touch gulpfile.js
添加下面內容 [9]:
//gulpfile.js var gulp = require('gulp'); var autoprefixer = require('gulp-autoprefixer'); gulp.task('styles', function() { return gulp.src('./styles.css') .pipe(autoprefixer({ browsers: ['last 2 versions'], cascade: false })) .pipe(gulp.dest('build')); });
gulp
從 styles.css
中提取內容並經過 gulp-autoprefixer
進行傳遞。輸出文件保留在 build
文件夾下。
譯者注: 彈性項目:Flex Items 彈性容器:Flex Container 彈性方向:Flex Direction 彈性換行:Flex Wrap 彈性流:Flex Flow 彈性項目大小:Flexbox Sizing