【譯】Flexbox徹底指南

該文章爲原創翻譯,原文可訪問A Complete Guide to Flexbox

本人能力尚缺,經驗稍淺,翻譯中存在的不足之處望你們批評指正,以便及時更正。
郵箱:440981b05j0.cdb@sina.cn
Github:Duggudcss

  文章描述的是CSS flexbox佈局綜合指南。該徹底指南解釋了有關flexbox的全部內容,重點介紹了父元素(flex容器)和子元素(flex項目)的全部可能的不一樣屬性。它還包括歷史記錄,演示,模式和瀏覽器支持圖表。html

背景

  Flexbox佈局(靈活盒子)模塊(截至2017年10月的W3C候選推薦標準)旨在提供一種更有效的方式來佈置,對齊和分配容器中項目之間的空間,即便它們的大小未知或是動態變化的( 這也是「flex」這個詞的由來)。css3

  Flex佈局的主要思想是使容器可以改變其項目的寬度、高度以及順序,以最好地填充可用空間(主要是爲了適應全部類型的顯示設備和屏幕尺寸)。Flex容器擴展項目以填充可用空間,或縮小它們以防止溢出。git

  最重要的是,與常規佈局(基於垂直的塊和基於水平的內聯塊)相反,flexbox佈局與方向無關。雖然前者適用於頁面,但它缺少靈活性來支持大型或複雜的應用程序(特別是在方向更改,調整大小,拉伸,縮小等方面)。github

  注意:Flexbox佈局最適合應用程序的組件和小規模佈局,而Grid佈局則適用於更大規模的佈局。web

基礎與術語

父的屬性(彈性容器)

                父的屬性(彈性容器) 瀏覽器

子的屬性(彈性項目)
                 子的屬性(彈性項目)

display

  這定義了一個flex容器;內聯或塊取決於給定的值。它爲全部直接子項目提供了flex上下文。bash

<!--css-->
.container {
  display: flex; /* or inline-flex */
}
複製代碼

  注意: CSS列對flex容器沒有影響。app

order

image
  默認狀況下,flex項目按源順序排列。可是, order屬性能夠控制它們在Flex容器中的顯示順序。

flex-direction

image
  這將創建主軸(main-axis),從而定義Flex項目放置在Flex容器中的方向。除了可選wrapping外,flexbox採用單向佈局概念。能夠將flex項看做是水平行或垂直列的佈局。

<!--css-->
.container {
  flex-direction: row | row-reverse | column | column-reverse;
}
複製代碼
  • row(默認): ltr表示從左至右;rtl表示從右至左;
  • row-reverse(反向行: rtl表示從左至右;ltr表示從右至左;
  • column: 與row同樣,只是方向從上至下;
  • column reserse: 與row reserse同樣,只是方向從下至上。

flex-wrap

image
  默認狀況下,flex項目都會嘗試在一行中自適應佈局。你能夠根據須要利用此屬性更改它並容許項目進行換行。

<!--css-->
.container{
  flex-wrap: nowrap | wrap | wrap-reverse;
}
複製代碼
  • nowrap: 全部的flex項目會在同一行;
  • wrap: flex項目將從上到下被換行成多行;
  • wrap-reverse:flex項目將從下到上被換行成多行;

  更多可視化flex-wrap例程可訪問visual demos of flex-wrap hereide

flex-flow(適用於父flex元素)

  這是一個簡寫的flex-directionflex-wrap屬性,它們共同定義了flex容器的主軸(main-axis)和交叉軸(across-axis)。默認值爲 row nowrap

<!--css-->
flex-flow: <‘flex-direction’> || <‘flex-wrap’>
複製代碼

flex-grow

image
  這定義了flex項在必要時增加的能力。可取無單位值做爲比例值。它規定了項目應該佔用flex容器內可用空間的數量。若是全部項目都將 flex-grow設置爲1,則容器中的剩餘空間將平均分配給全部子項目。若是其中一個子項目的值設爲2,那麼將佔用兩倍於其餘子項目的空間(或者至少會嘗試這樣作)。

<!--css-->
.item {
  flex-grow: <number>; /* default 0 */
}
複製代碼

  flex-grow設置爲負值時無效。

flex-shrink

  這定義了flex項在必要時收縮的能力。

<!--css-->
.item {
  flex-shrink: <number>; /* default 1 */
}
複製代碼

  flex-shrink設置爲負值時無效。

flex-basis

這定義了剩餘空間分佈以前元素的默認大小。它能夠是長度(例如20%,5rem等)或關鍵字。auto關鍵字的意思是「查看個人寬度或高度屬性」(這是由main-size關鍵字臨時完成的,直到棄用)。 content關鍵字的意思是「根據項目的內容調整大小」,這個關鍵字尚未獲得很好的支持,所以很難測試它,也很難知道它的兄弟屬性max-contentmin-contentfit-content的功能。

<!--css-->
.item {
  flex-basis: <length> | auto; /* default auto */
}
複製代碼

  若是設置爲0,則不考慮內容周圍的額外空間。若是設置爲auto,則根據其彈性增加值分佈額外的空間。點擊查看示例圖表

flex

  這是flex-growflex-shrinkflex-basis組合的簡寫。第二個和第三個參數(flex-shrinkflex-basis)是可選的。默認值是0 1 auto

<!--css-->
.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
複製代碼

  建議你使用這個簡寫屬性,而不是設置各個獨立屬性。簡寫能夠智能地設置其餘值。

justify-content

image
  這定義了沿主軸的對齊方式。當一行中的全部flex項不管是不靈活的,或者是靈活的但已經達到自身最大值時,它能夠幫助分配剩餘的可用空間。此外,當flex項目溢出行時,它還對對齊方式進行了一些控制。

<!--css-->
.container {
  justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
}
複製代碼
  • flex-start: flex項目在行開始處緊密排列;
  • flex-end:flex項目在行結尾處緊密排列;
  • center:flex項目行居中排列;
  • space-between:flex項目均勻分佈;第一項在起始行,最後一項在結束行;
  • space-around:flex項目在行中均勻分佈,項目周圍的空間相等。注意,咋一看,空間是不相等的,由於全部的項在兩邊都有相等的空間。第一項在容器邊緣有一個單位的空間,可是與下一項之間有兩個單位的空間,由於下一項有它自身空間。

align-self

image

  這容許爲單個flex項目重置默認的對齊方式(或由align-items指定的對齊方式)。

  請參閱align-items說明以瞭解可用的值。

<!--css-->
.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
複製代碼

注意: floatclearvertical-align對flex項沒有影響。

align-items

image

  這定義了flex項在當前行的cross- axis軸(c垂直於main-axis軸)上佈局的默認行爲。能夠將其視爲justify-content做用於cross- axis軸的版本。

<!--css-->
.container {
  align-items: stretch | flex-start | flex-end | center | baseline;
}
複製代碼
  • stretch (default): 拉伸以填充容器(仍然遵循最小寬度/最大寬度)
  • flex-start: flex項目的橫軸方向起始邊距(margin)邊緣位於橫軸起始行處;
  • flex-end:flex項目的橫軸方向結束邊距(margin)邊緣位於橫軸結尾行處;
  • center: flex項目沿橫軸居中對齊;
  • baseline: flex項目根據baseline基線對齊;

align-content

image

  當cross-axis軸存在額外空間時,這會對flex項目沿cross-axis軸進行行對齊,相似於justify-content沿main-axis軸對flex項目進行對齊。

  注意:當只有flex項目只有一行時,此屬性不起做用。

<!--css-->
.container {
  align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
複製代碼
  • flex-start: 行於flex容器開始處緊密排列;
  • flex-end: 行於flex容器末尾處緊密排列;
  • center: 行於flex容器居中緊密排列;
  • space-between: 行均勻分佈;第一行位於容器的開末尾頭,而最後一行位於容器的末尾;
  • space-around:行均勻分佈,每行周圍的空間相等;
  • stretch (default): 行伸展以佔據剩餘空間。

例子

  讓咱們以一個很是簡單的例子開始,解決一個幾乎天天都會遇到的問題:完美居中。若是您使用flexbox,它將變得不能更簡單。

<!--css-->
.parent {
  display: flex;
  height: 300px; /* Or whatever */
}

.child {
  width: 100px;  /* Or whatever */
  height: 100px; /* Or whatever */
  margin: auto;  /* Magic! */
}
複製代碼

  這取決於flex容器中設置爲「auto」的margin會吸取額外的空間。所以,設置垂直邊距爲auto將使項目完美地在兩個軸上居中排列。

  如今讓咱們添加更多的屬性。考慮一個包含6個項目的列表,它們的尺寸都是固定的,可是能夠自動調整大小。咱們但願它們均勻地分佈在橫軸上,以便在調整瀏覽器大小時一切正常(不使用媒體查詢!)。

<!--css-->
.flex-container {
  /* We first create a flex layout context */
  display: flex;
  
  /* Then we define the flow direction 
     and if we allow the items to wrap 
   * Remember this is the same as:
   * flex-direction: row;
   * flex-wrap: wrap;
   */
  flex-flow: row wrap;
  
  /* Then we define how is distributed the remaining space */
  justify-content: space-around;
}
複製代碼

  Done.其餘都只是一些樣式問題。下面是一個測試例程。請訪問CodePen,試着調整窗口大小,看看會發生什麼。

  咱們試下別的例子。想象一下,咱們的網站頂部有一個靠右對齊的導航,但咱們但願它中型屏幕上居中,在小型設備上則呈現爲單列導航。這也足夠簡單。

<!--css-->
/* Large */
.navigation {
  display: flex;
  flex-flow: row wrap;
  /* This aligns items to the end line on main-axis */
  justify-content: flex-end;
}

/* Medium screens */
@media all and (max-width: 800px) {
  .navigation {
    /* When on medium sized screens, we center it by evenly distributing empty space around items */
    justify-content: space-around;
  }
}

/* Small screens */
@media all and (max-width: 500px) {
  .navigation {
    /* On small screens, we are no longer using row direction but column */
    flex-direction: column;
  }
}
複製代碼

  讓咱們使用flex項目的靈活性來作更好的實現!好比移動優先的3列布局,具備全寬度的頁眉和頁腳。與源順序無關。

<!--css-->
.wrapper {
  display: flex;
  flex-flow: row wrap;
}

/* We tell all items to be 100% width, via flex-basis */
.wrapper > * {
  flex: 1 100%;
}

/* We rely on source order for mobile-first approach
 * in this case:
 * 1. header
 * 2. article
 * 3. aside 1
 * 4. aside 2
 * 5. footer
 */

/* Medium screens */
@media all and (min-width: 600px) {
  /* We tell both sidebars to share a row */
  .aside { flex: 1 auto; }
}

/* Large screens */
@media all and (min-width: 800px) {
  /* We invert order of first sidebar and main
   * And tell the main element to take twice as much width as the other two sidebars 
   */
  .main { flex: 2 0px; }
  .aside-1 { order: 1; }
  .main    { order: 2; }
  .aside-2 { order: 3; }
  .footer  { order: 4; }
}
複製代碼

帶前綴的Flexbox

  Flexbox須要一些供應商的前綴來支持儘量多的瀏覽器。它不只包括帶有供應商前綴的前置屬性,實際上還有徹底不一樣的屬性和值名稱。這是由於隨着時間的推移,Flexbox規範已經發生了變化,建立了"old", "tweener", and "new"版本。

  或許處理這個問題的最好方法是使用新的(也是最終的)語法,並經過Autoprefixer運行CSS, Autoprefixer能夠很好地處理回退。

  另外,這裏有一個Sass @mixin來幫助添加一些前綴,這也讓你知曉須要處理的事情:

<!--scss-->
@mixin flexbox() {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
}

@mixin flex($values) {
  -webkit-box-flex: $values;
  -moz-box-flex:  $values;
  -webkit-flex:  $values;
  -ms-flex:  $values;
  flex:  $values;
}

@mixin order($val) {
  -webkit-box-ordinal-group: $val;  
  -moz-box-ordinal-group: $val;     
  -ms-flex-order: $val;     
  -webkit-order: $val;  
  order: $val;
}

.wrapper {
  @include flexbox();
}

.item {
  @include flex(1 200px);
  @include order(2);
}
複製代碼

相關屬性

其餘資源

Bugs

  Flexbox固然也有bugs。我見過的最好bugs收集是Philip Walton和Greg Whitworth的Flexbugs。它是開源的,你能夠跟蹤全部的數據,因此我認爲最好查看一下。

瀏覽器支持

  按「版本」劃分:

  • (new)指規範中的最新語法(例如display: flex;)
  • (tweener)是指2011年的一種非官方語法(例如display: flexbox;)
  • (old)指2009年起的舊語法(例如:display: box;)

image

  黑莓瀏覽器10+支持新語法。

  更多有關如何混合使用語法以得到最佳瀏覽器支持的信息,可訪問CSS-TricksDevOpera

相關文章
相關標籤/搜索