React-native初體驗之一個完整的Flexbox指南

本文由大漠根據Chris Coyier的《A Complete Guide to Flexbox》所譯,整個譯文帶有我們自己的理解與思想,如果譯得不好或不對之處還請同行朋友指點。如需轉載此譯文,需註明英文出處:http://css-tricks.com/snippets/css/a-guide-to-flexbox,以及作者相關信息

——作者:Chris Coyier

——譯者:大漠

Flexbox佈局(Flexible Box)模塊旨在提供一個更加有效的方式制定、調整和分佈一個容器裏的項目佈局,即使他們的大小是未知或者是動態的。(這裏我們稱爲Flex)。

Flex佈局主要思想是讓容器有能力讓其子項目能夠改變其寬度、高度(甚至順序),以最佳方式填充可用空間(主要是爲了適應所有類型的顯示設備和屏幕大小)。Flex容器會使子項目(伸縮項目)擴展來填滿可用空間,或縮小他們以防止溢出容器。

最重要的是,Flexbox佈局方向不可預知,他不像常規的佈局(塊就是從上到下,內聯就從左到右)。而那些常規的適合頁面佈局,但對於支持大型或者雜的應用程序(特別是當他涉及到取向改變、縮放、拉伸和收縮等)就缺乏靈活性。

注:Flexbox佈局最適合應用程序的組件和小規模的佈局,而網格佈局更適合那些更大規模的佈局。

基本要素

因爲Flexbox是整個模塊,而不是一個屬性,它涉及很多東西,包括其整個組屬性。他們當中一部分是容器(父元素,稱爲“伸縮容器”),另一部分是子元素(稱爲“伸縮項目”)。

常規佈局是基於塊和內聯流方向,而Flex佈局是基於flex-flow流。請看看來自w3c規範中的這張圖,解釋了flex佈局的主要思想。

一個完整的Flexbox指南

根據伸縮項目排列方式不同,主軸和側軸方向也有所變化

一個完整的Flexbox指南

——大漠

基本上,伸縮項目是沿着主軸(main axis),從主軸起點(main-start)到主軸終點(main-end)或者沿着側軸(cross axis),從側軸起點(cross-start)到側軸終點(cross-end)排列。

  •  主軸(main axis):伸縮容器的主軸,伸縮項目主要沿着這條軸進行排列布局。小心,它不一定是水平的;這主要取決於“justify-content”屬性(詳細見下文)。
  •  主軸起點(main-start)和主軸終點(main-end):伸縮項目放置在伸縮容器內從主軸起點(main-start)向主軸終點(main-start)方向。
  •  主軸尺寸(main size):伸縮項目在主軸方向的寬度或高度就是主軸的尺寸。伸縮項目主要的大小屬性要麼是寬度,要麼是高度屬性,由哪一個對着主軸方向決定。
  •  側軸(cross axis):垂直於主軸稱爲側軸。它的方向主要取決於主軸方向。
  •  側軸起點(cross-start)和側軸終點(cross-end):伸縮行的配置從容器的側軸起點邊開始,往側軸終點邊結束。
  •  側軸尺寸(cross size):伸縮項目的在側軸方向的寬度或高度就是項目的側軸長度,伸縮項目的側軸長度屬性是「width」或「height」屬性,由哪一個對着側軸方向決定。

屬性

display:flex | inline-flex;(適用於伸縮容器,也就是伸縮項目的父元素)

這個是用來定義伸縮容器,是內聯還是塊取決於設置的值。這個時候,他的所有子元素將變成flex文檔流,稱爲伸縮項目。

display: other values | flex | inline-flex;	

請注意:

  •  CSS的columns在伸縮容器上沒有效果。
  •  float、clear和vertical-align在伸縮項目上沒有效果。

flex-direction(適用於伸縮容器,也就是伸縮項目的父元素)

這個主要用來創建主軸,從而定義了伸縮項目放置在伸縮容器的方向。

flex-direction: row | row-reverse | column | column-reverse	
  •  row(默認值):在“ltr”排版方式下從左向右排列;在“rtl”排版方式下從右向左排列。
  •  row-reverse:與row排列方向相反,在“ltr”排版方式下從右向左排列;在“rtl”排版方式下從左向右排列。
  •  column:類似 於row,不過是從上到下排列
  •  column-reverse:類似於row-reverse,不過是從下到上排列。

主軸起點與主軸終點方向分別等同於當前書寫模式的始與結方向。其中“ltr”所指文本書寫方式是“left-to-right”也就是從左向右書寫;而“rtl”所指的剛好與“ltr”方式相反,其書寫方式是“right-to-left”,也就是從右向左書寫。

——大漠

flex-wrap(適用於伸縮容器,也就是伸縮項目的父元素)

這個主要用來定義伸縮容器裏是單行還是多行顯示,側軸的方向決定了新行堆放的方向。

flex-wrap: nowrap | wrap | wrap-reverse	
  •  nowrap(默認值):伸縮容器單行顯示,“ltr”排版下,伸縮項目從左到右排列;“rtl”排版上伸縮項目從右向左排列。
  •  wrap:伸縮容器多行顯示,“ltr”排版下,伸縮項目從左到右排列;“rtl”排版上伸縮項目從右向左排列。
  •  wrap-reverse:伸縮容器多行顯示,“ltr”排版下,伸縮項目從右向左排列;“rtl”排版下,伸縮項目從左到右排列。(和wrap相反)

flex-flow(適用於伸縮容器,也就是伸縮項目的父元素)

這個是“flex-direction”和“flex-wrap”屬性的縮寫版本。同時定義了伸縮容器的主軸和側軸。其默認值爲“row nowrap”。

flex-flow: <‘flex-direction’> || <‘flex-wrap’>	

justify-content(適用於伸縮容器,也就是伸縮項目的父元素)

這個是用來定義伸縮項目沿着主軸線的對齊方式。當一行上的所有伸縮項目都不能伸縮或可伸縮但是已經達到其最大長度時,這一屬性纔會對多餘的空間進行分配。當項目溢出某一行時,這一屬性也會在項目的對齊上施加一些控制。

justify-content: flex-start | flex-end | center | space-between | space-around	
  •  flex-start(默認值):伸縮項目向一行的起始位置靠齊。
  •  flex-end:伸縮項目向一行的結束位置靠齊。
  •  center:伸縮項目向一行的中間位置靠齊。
  •  space-between:伸縮項目會平均地分佈在行裏。第一個伸縮項目一行中的最開始位置,最後一個伸縮項目在一行中最終點位置。
  •  space-around:伸縮項目會平均地分佈在行裏,兩端保留一半的空間。

一個完整的Flexbox指南

align-item(適用於伸縮容器,也就是伸縮項目的父元素)

這個主要用來定義伸縮項目可以在伸縮容器的當前行的側軸上對齊方式。可以把他想像成側軸(垂直於主軸)的“justify-content”。

align-items: flex-start | flex-end | center | baseline | stretch	
  •  flex-start:伸縮項目在側軸起點邊的外邊距緊靠住該行在側軸起始的邊。
  •  flex-end:伸縮項目在側軸終點邊的外邊距靠住該行在側軸終點的邊 。
  •  center:伸縮項目的外邊距盒在該行的側軸上居中放置。
  •  baseline:伸縮項目根據他們的基線對齊。
  •  stretch(默認值):伸縮項目拉伸填充整個伸縮容器。此值會使項目的外邊距盒的尺寸在遵照「min/max-width/height」屬性的限制下儘可能接近所在行的尺寸。

一個完整的Flexbox指南

align-content(適用於伸縮容器,也就是伸縮項目的父元素)

這個屬性主要用來調準伸縮行在伸縮容器裏的對齊方式。類似於伸縮項目在主軸上使用“justify-content”一樣。

注:請注意本屬性在只有一行的伸縮容器上沒有效果。

align-content: flex-start | flex-end | center | space-between | space-around | stretch	
  •  flex-start:各行向伸縮容器的起點位置堆疊。
  •  flex-end:各行向伸縮容器的結束位置堆疊。
  •  center:各行向伸縮容器的中間位置堆疊。
  •  space-between:各行在伸縮容器中平均分佈。
  •  space-around:各行在伸縮容器中平均分佈,在兩邊各有一半的空間。
  •  stretch(默認值):各行將會伸展以佔用剩餘的空間。

一個完整的Flexbox指南

order(適用於伸縮項目,也就是伸縮容器的子元素)

默認情況下,伸縮項目是按照文檔流出現先後順序排列。然而,“order”屬性可以控制伸縮項目在他們的伸縮容器出現的順序。

order: <integer>	

flex-grow(適用於伸縮項目,也就是伸縮容器的子元素)

根據需要用來定義伸縮項目的擴展能力。它接受一個不帶單位的值做爲一個比例。主要用來決定伸縮容器剩餘空間按比例應擴展多少空間。

如果所有伸縮項目的“flex-grow”設置了“1”,那麼每個伸縮項目將設置爲一個大小相等的剩餘空間。如果你給其中一個伸縮項目設置了“flex-grow”值爲“2”,那麼這個伸縮項目所佔的剩餘空間是其他伸縮項目所佔剩餘空間的兩倍。

flex-grow: <number> (默認值爲: 0)	

負值同樣生效。

flex-shrink(適用於伸縮項目,也就是伸縮容器的子元素)

根據需要用來定義伸縮項目收縮的能力。

flex-shrink: <number> (默認值爲: 1)	

負值同樣生效。

flex-basis(適用於伸縮項目,也就是伸縮容器的子元素)

這個用來設置伸縮基準值,剩餘的空間按比率進行伸縮。

flex-basis: <length> | auto (默認值爲: auto)	

負值不合法。

flex(適用於伸縮項目,也就是伸縮容器的子元素)

這是“flex-grow”、“flex-shrink”和“flex-basis”三個屬性的縮寫。其中第二個和第三個參數(flex-shrink、flex-basis)是可選參數。默認值爲“0 1 auto”。

flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]	

align-self(適用於伸縮項目,也就是伸縮容器的子元素)

用來在單獨的伸縮項目上覆寫默認的對齊方式。

屬性值的介紹請參閱“align-items”的屬性值。

align-self: auto | flex-start | flex-end | center | baseline | stretch

實例

讓我們先從一個非常簡單的例子開始,解決一個幾乎每天都會碰到的問題:完美的居中。如果你使用flexbox,沒有比這更簡單的方法。

.parent {
  display: flex;
  height: 300px; /* Or whatever */
}

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

這個依賴於設置“margin”值爲“auto”值,自動獲取伸縮容器中剩餘的空間。所以設置垂直方向margin值爲“auto”,可以使伸縮項目在伸縮容器的兩上軸方向都完全集中。

現在我們來使用一些其他的屬性。

考慮使用6個列表項,並且爲了視覺審美給他設置了一個固定大小尺寸,但他們也有可能可以自動獲取尺寸大小。我們希望他們能均勻的、很好的分佈在水平軸上,就算當我們調整瀏覽器,他們也依然顯示得很好(不使用媒體查詢)。

.flex-container {
  /* 我們第一步要創建一個flex文檔流(創建伸縮容器) */
  display: flex;
  
  /* 然後我們定義伸縮流方向,並且可以換行
   * 記得我們要這樣設置:
   * flex-direction: row;
   * flex-wrap: wrap;
   */
  flex-flow: row wrap;
  
  /* 然後我們定義瞭如何分配伸縮容器的剩餘空間 */
  justify-content: space-around;
}	

完成。其他的一切都不過是一些美化外觀樣式。下面是在codepen上展示的一個例子。到codepen上查看,並試着調整你瀏覽器窗口去看發生什麼事?

allowtransparency="true" data-height="400" frameborder="0" height="400" scrolling="no" src="http://codepen.io/HugoGiraudel/embed/3e86f7ea0ae954e541f0431fa20f04f1?type=result&height=400&safe=true" style="box-sizing: inherit; width: 923px; border-style: none; border-width: initial; overflow: hidden;">

讓我們試試別的。假設我們網站頂部有一個右對齊的導航,但是我們希望它在小屏幕和小型設備中能單列居中顯示。非常簡單。

/* Large */
.navigation {
  display: flex;
  flex-flow: row wrap;
  /* 所有列面向主軸終點位置靠齊 */
  justify-content: flex-end;
}

/* Medium screens */
@media all and (max-width: 800px) {
  .navigation {
    /* 當在中等屏幕中, 導航項目居中顯示,並且剩餘空間平均分佈在列表之間 */
    justify-content: space-around;
  }
}

/* Small screens */
@media all and (max-width: 500px) {
  .navigation {
    /* 在小屏幕下, 我們沒有足夠空間行排列,但我們可以換成列排列 */
    flex-direction: column;
  }
}	
allowtransparency="true" class="cp_embed_iframe" data-height="100" frameborder="0" height="100" scrolling="no" src="http://codepen.io/HugoGiraudel/embed/f6b906545dadb0a12567433c9f406343?type=result&height=100&safe=true" style="box-sizing: inherit; width: 923px; border-style: none; border-width: initial; overflow: hidden;">

讓我們嘗試一些更靈活性的伸縮項目!關於移動先行,3列布局與頁眉頁腳全屏。和獨立的文檔順序。

.wrapper {
  display: flex;
  flex-flow: row wrap;
}

/* 設置所有標籤寬度爲100% */
.header, 
.main, 
.nav, 
.aside, 
.footer {
  flex: 1 100%;
}

/* 我們利用文檔流順序,考慮移動端先行
 * 在這個例子中的順序:
 * 1. header
 * 2. nav
 * 3. main
 * 4. aside
 * 5. footer
 */

/* Medium screens */
@media all and (min-width: 600px) {
  /* 兩個邊欄在同一行 */
  .aside { flex: 1 auto; }
}

/* Large screens */
@media all and (min-width: 800px) {
  /* 設置左邊欄在主內容左邊
   * 設置主內容區域寬度是其他兩個側邊欄寬度的兩倍
   */
  .main { flex: 2 0px; }
  
  .aside-1 { order: 1; }
  .main    { order: 2; }
  .aside-2 { order: 3; }
  .footer  { order: 4; }
}	
發佈了23 篇原創文章 · 獲贊 66 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章