CSS Flexbox 可視化手冊

翻譯:瘋狂的技術宅
原文: https://medium.com/swlh/css-f...

本文首發微信公衆號:jingchengyideng
歡迎關注,天天都給你推送新鮮的前端技術文章javascript


介紹

Flexbox是 Flexible Box Module(彈性盒模型)的縮寫。 是一種能夠輕鬆控制html元素之間的空間分佈和對齊的佈局模型。css

Flexbox同一時間只能控制行或列中的一個維度。對於二維控制須要 CSS 網格佈局。html

clipboard.png

首先給出以下模板:前端

<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 屬性默認爲blockjava

clipboard.png

彈性項目

display: flex 應用於 .container div 時,全部直接子div都變爲 flex-items,並得到新的行爲ios

  • 它們將顯示在同一行中,由於flex-direction默認爲row
  • 它們將會從左到右顯示

clipboard.png

  • 其中的項目不會自動伸展來適應整個寬度(主軸),爲了作到這一點,它們會縮小。

clipboard.png

  • 項目會被拉伸以適合交叉軸(在此示例中爲高度)。 若是這些項目的高度不一致,它們將會伸展到最高的那個高度
  • flex-basis 默認爲 auto(項目寬度將由其內容決定)
  • flex-wrap 默認爲nowrap(若是容器的寬度不足以適合這些項目,它們不會換行,而是會溢出)

出於可視化的目的,讓咱們拉伸容器使其佔據整個高度。npm

彈性容器

display:flex 使容器擴展至整個可用寬度。 這點與 display:inline-flex 相反,它使容器縮小到內容的寬度。json

clipboard.png

彈性方向

一旦被聲明爲 flex 容器,就能夠認爲該元素具備兩個軸:主軸與交叉軸。 主軸由flex-direction屬性定義。 交叉軸垂直於前者。gulp

flex-direction 屬性有四個值:rowrow-reversecolumncolumn-reverse瀏覽器

其默認值爲row,它從左到右水平設置主軸,交叉軸從上到下垂直截取。 相似地, column 值從頂部到底部垂直設置主軸,從左到右設置交叉軸。 這兩個選項的相反屬性使主軸反轉180°。 交叉軸保持不變。

能夠經過下圖觀察這些值的 flex-items 行爲:

clipboard.png

Flex Wrap

當容器中的空間不足以容納其中的彈性項目時,能夠用 flex-wrap 來處理。

在默認狀況下,flex-wrap 被設置爲 nowrap,這意味着若是容器不能適應在其內的行中原始寬度的項目,則這些項目將會縮小來進行適應。 若是它們由於某種緣由沒法收縮,則會溢出容器。

把項目寬度設置爲300px,nowrap 選項會輸出如下結果:

clipboard.png

其中,每一個項目都會縮小到大約 70px 來適合容器。

當屬性被更新爲wrap時,如今項目的寬度其實是原始值300px。 當第一行不足以容納300px時,則該項目將換行到新的一行,而不是溢出容器。 應該把其中的每一行都視爲單獨的彈性容器。 一個容器中的空間分佈不會影響到與其相鄰的其餘容器。

clipboard.png

可是爲何彈性項目會佔據整個屏幕高度呢? 在第一部分中,容器高度設置爲 100vh ,所以可用空間被平均分爲四行,來適合 300px 項目的須要。 若是咱們沒有設置 100vh,容器的高度則會遵循項目內容的高度,以下圖所示:

clipboard.png

另外一個選項是wrap-reverse,它會反轉交叉軸。 經過 flex-direction 屬性從上到下設置,wrap-reverse 將其轉換爲從下到上。

clipboard.png

經過使用 flex-direction:column 反轉主軸,不適應的元素會被換到另外一列,剩餘空間被均勻分割。

clipboard.png

wrap-reverse 選項會沿着列方向將交叉軸從右向左反轉,產生如下輸出:

clipboard.png

因爲flexbox是單維度佈局,因此在進行反轉時,項目從下到上進行排列(對於行方向),但保持左右結構,只改變了交叉軸。

彈性流

flex-directionflex-wrap 能夠在一個屬性當中聲明:flex-flow:[direction][wrap]

.flex-container {
  flex-flow : column wrap;
}

項目之間的縫隙

讓咱們回到row/wrap。 能夠經過設置項目的 width:33.3333% 來填充整個容器:

clipboard.png

可是若是你但願在子div 之間有一個間隙,它們就不會按照你想的那樣換行:

clipboard.png

這個小麻煩這能夠經過 CSS 函數 calc() 來解決:

.flex-item {
  width: calc(33.33333% - 40px);
  margin: 20px;
}

clipboard.png

爲了消除容器邊緣的空間,能夠在容器上使用負邊距:

.flex-container {
  margin: -20px;
}

clipboard.png

排序

order 屬性容許更改出現的可視排序項目。排序被分配給組。 默認狀況下全部的彈性項目都設置爲 order: 0,這意味着全部項目都屬於同一組,而且它們將按照原始順序定位。 在兩個或多個組的狀況下,組會相對於它們的整數值進行排序。

在下面的例子中,有三個 ordinal groups-1, 01,按此順序進行排列。

.box-3 { order: 1; }
.box-7 { order: 1; }
.box-8 { order: -1; }

clipboard.png

此屬性可視地從新分配項目,但在交互時保持其原始源位置,例如使用Tab鍵遍歷它們。 若是物品訂購對可訪問性有影響,則能夠考慮這一點。 flex-direction 也是如此。

clipboard.png

對齊

clipboard.png
(此圖反覆上傳老是出錯,請你們移步原文查看)

在Flexbox中,沿着軸的項目對齊和空間分佈能夠受到四個屬性的控制:

  • justify-content: 對齊主軸中的全部項目
  • align-items: 對齊交叉軸中的全部項目
  • align-self: 對齊交叉軸中的單個項目
  • align-content: 控制交叉軸上柔性線之間的空間

justify-content

clipboard.png

適用於容器,justify-content 處理項目在主軸上的對齊方式。六個最經常使用的選項包括: flex-startflex-endcenterspace-aroundspace-betweenspace-evenlyflex-start是默認值。.

align-items

clipboard.png

也適用於容器, align-items 屬性處理交叉軸方向上的對齊。它的默認值是 stretch 其它的選項是 flex-startflex-endcenterbaseline

stretch 選項使全部項目伸展到容器高度(若是設置)或最高項目的高度[5]。 第一張圖片顯示容器高度設置爲 100vh,未設置第二個高度。

align-content

clipboard.png

這是做用在 flex 容器的四個屬性中的最後一個,align-content 在交叉軸中的彈性線之間分配空格。 做爲後者,它的初始值是 stretchjustify-content,它接受如下選項: flex-start, flex-end, center, space-around, space-between, space-evenly

align-self

clipboard.png

align-items 屬性實際上經過在容器內的全部 flex 項目上設置 align-self 來實現。 經過單獨設置 align-self,能夠覆蓋全局值。 它接受與align-items和'auto'相同的值[5]。

auto 選項經過 align-itemsalign-self 重置爲容器全局定義的值。

調整 Flexbox 的大小

項目的尺寸和伸展性能夠經過三種屬性來控制: flex-growflex-shrinkflex-basis。 這三個都做用於主軸。

  • flex-grow:若是有額外的空間,每一個項目應該如何放大
  • flex-shrink:若是沒有足夠的空間,應該如何縮小每一個項目
  • flex-basis:在設置上述兩個屬性以前,該項目的大小應該是多少

flex-grow

由此屬性設置的 flex grow factor (彈性增加因子)用來處理項目大小相對於彼此的比率。

默認值爲 0,這意味着若是還有可用空間,就把它放在最後一個項目以後。

clipboard.png

在上面的例子中,direction 被設置爲 row,每一個彈性項目的 width 被設置爲 60px。 因爲容器寬是 980px,因此剩餘的可用空間爲 680px。 這個空間被稱爲positive free space (正自由空間)。

若是將 flex-grow 設置爲1,正可用空間量會在彈性項目之間平均分配。 每一個項目的寬度將會增長 136px,總寬度爲196px

clipboard.png

經過將 flex-grow: 2 應用到第三個項目,它會獲得比其它項目多出兩倍的可用正自由空間,即286px,其餘項目仍爲173px

下圖顯示了把項目的 flex-grow 屬性值設置爲其內容對應的數字時的情形。

clipboard.png

flex-shrink

當沒有足夠的可用空間來容納全部容器時,用 flex-shrink 處理項目大小。 它經過縮小這些項目來劃分它們之間的 negative free space (負自由空間)。

下圖顯示的是寬度爲 980px 的容器,它容納了5個寬度爲 300px的物品。 因爲沒有空間容納所需的總寬度 1500px,因此默認的flex shrink factor(彈性收縮係數)的值爲1,這樣會使每一個項目的寬度均勻縮小到196px

clipboard.png

經過將第三項的比率設置爲2,它縮小爲其他項目大小的二分之一。

clipboard.png

本節的最後一張圖顯示了將每一個項目的內容值對應的數字設定爲 flex-shrink 的值時的情形。

flex-basis

flex-basis 是在實際設置可用空間以前,檢查每一個項目原本應具備的大小的屬性。 默認值爲 auto,項寬度由 width 屬性顯式設置,或者取其內容寬度。 它也接受像素值。

下面的動圖顯示了一個800px寬的容器和五個設置爲 flex-basis:160px 的彈性項目。 這告訴瀏覽器:若是在理想狀態下,有足夠的空間來放置全部的項目,就遵循它們的160px寬度,而且沒有正/負可用空間;若是沒有足夠的空間的話,那麼 flex-shrink 默認爲1,全部項目均勻收縮; 若是有額外的空間,flex-grow 默認爲0,而且剩餘的空間放在最後一個項目以後。

clipboard.png

下一個動圖展現了把項目1設置爲flex-shrink:10,項目4設置爲flex-grow:10。對於負自由空間,項目1的寬度減小10倍。 對於正空閒空間,第4項的寬度是其餘空間的10倍。

clipboard.png

flex-basis 也接受值 content,此時不管其寬度是否被設置,計算自由空間時所考慮的寬度依據是項目中的內容。

flex

flex 屬性是按順序排列的 flex-growflex-shrinkflex-basis 的簡寫,它接受如下預約義值:

  • initial:重置爲 flexbox 的默認值,等同於 flex: 0 1 auto
  • auto:flex-items可以根據須要增加/縮小,等同於 flex: 1 1 auto
  • none:固定項目,等同於 flex: 0 0 auto
  • flex: 1:flex-items 具備伸縮的能力,flex-basis 設置爲零,等同於 flex: 1 1 0

Autoprefixer

對於跨瀏覽器的兼容性問題,設置具備具備必要前綴的屬性是很是重要的,以確保可以支持全部瀏覽器。

手動自動爲每一個屬性添加前綴多是一項很是繁瑣的任務,也使樣式很難維護。使用 Gulp 可以替你自動執行這些任務。

爲了可以使用Gulp,咱們必須將它做爲依賴添加到項目當中。 這項工做是在 package.json 文件中完成的,它負責跟蹤項目依賴及其版本。 在終端中輸入下列命令來建立文件:

nmp 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

添加如下內容:

// gulpfile.js

var gulp = require('gulp');
var autoprefixer = require('gulp-autoprefixer');
var options = { browsers: ['last 2 versions'], cascade: false };

gulp.task('styles', function() {
  return gulp.src('./styles.css')
             .pipe(autoprefixer(options))
             .pipe(gulp.dest('build'));
});

gulp 會從 styles.css 中提取內容並經過 gulp-autoprefixer 傳遞它。 處理結果會保存在build文件夾下。

參考

  1. What the Flexbox Course
  2. Basic concepts of flexbox — 25/03/2018
  3. Mastering Wrapping of Flex Items — 26/03/2018
  4. Ordering Flex Items — 26/03/2018
  5. Aligning Items in a Flex Container — 26/03/2018
  6. StackOverflow — 27/03/2018
  7. Controlling Ratios of Flex Items Along the Main Axis — 28/03/2018
  8. Gulp
  9. Gulp Autoprefixer

本文首發微信公衆號:jingchengyideng

歡迎掃描二維碼關注公衆號,天天推送我翻譯的技術文章

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

相關文章
相關標籤/搜索