iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 2
1
自我挑戰組

30 天 CSS 隨手筆記系列 第 2

30 天 CSS 隨手筆記 - 第 02 天 - WTF... Flexbox~!! ( 1 / 3 - what & why & how )

前言

標題是來自這個 flexbox.io 這個網站的頁首
flexbox.io 出的貼紙

網路上有非常多的資源了,例如:

  1. CSS Flexible Box Layout Module Level 1 :: W3C
  2. A Complete Guide to Flexbox :: CSS Tricks
  3. Laying Out A Flexible Future For Web Design With Flexbox :: SMASHING MAGAZINE
  4. ( 中文 ) 學習 Flexbox 版面配置 :: Rhadow's Tech Note

而現在的支援度更是已經高到做夢都會笑了:
flexbox 的支援率已經非常高了
( 截圖來源:http://caniuse.com/#search=flex )
尤其在手機上不用考慮 IE,更是可以放心大膽得用。

這個樣式現在也被廣泛利用在各種版面上,例如:facebook 手機版導航列 / google 搜尋頁等。

使用 flexbox 的 facebook 手機版導航列
使用 flexbox 的 facebook 手機版導航列
使用 flexbox 的 google 搜尋頁部份切版
使用 flexbox 的 google 搜尋頁部份切版

這篇將用一個簡單的實例,闡述 flexbox 的基本觀念。


What - Flexbox 是什麼?

首先必須要講到 layout mode。

CSS 固有的模式有四種:block / inline / table / positioned。
曾經流行的 table-based layout / div-based layout,都能達到一些效果。
但隨著 RWD 概念興起,網頁 / app 的版面設計越來越多變,大家意識到了我們需要更全面的佈局方式。

Flexbox 全名 Flexible Box,是 2009 年由 W3C 提出的新模式,
能夠更簡潔處理 layout,並有效地解決很多過去不容易處理的問題 ( 例如:垂直置中 )。


Why - 為什麼要使用 Flexbox?

如同上面的段落所說,flexbox 對於版面來說,是個更簡潔、更完整的模式。
對工程師來說,可以少寫一點 code 來達成一樣 ( 甚至更好 ) 的效果。

以 Gallery 的效果為例,如果想要在不使用 js 的前提下達到以下的效果:

  1. 圖片最小為 200px

  2. 一列的圖片數為 Math.floor(100% / 200px) ( 原諒我想不到更好的說詞了 Orz )

    • 預設一列一張圖片
    • 容器寬度 > 400px 時,預設一列兩張 ( 最後一列可能只有一張 )
    • 容器寬度 > 600px 時,預設一列三張 ( 最後一列可能只有一張或兩張 )
    • ... 以此類推
  3. 圖片的寬度平分整列的寬度

    • 一列一張圖時,寬度為 100%
    • 一列兩張圖時,寬度為 50%
    • ... 以此類推

我沒有想到使用 float 的方法 ( ̄艸 ̄")
( CSS 現在還沒有支援 max / min )

但使用 flexbox,可以用少少的 code 做到這個效果:Gallery Sample


How - 如何使用 Flexbox?

以下就以剛剛的 Gallery 為例,一邊撰寫樣式,一邊說明基本的 flexbox 概念。

想做到的效果:

  1. 圖片最小為 200px
  2. 一列的圖片數為 Math.floor(100% / 200px)
  3. 圖片的寬度平分整列的寬度

開始之前,我先寫了一些 基本的 HTML 和 CSS ( step 0 )
( 設定背景顏色、圖片寬度設為 100% 等 )

例子中的 HTML 如下:

div.gallery
    div.img-container>img
    div.img-container>img
    div.img-container>img
    div.img-container>img
    div.img-container>img

可以看到,目前每個 div.img-container 都還是 display: block 的樣式。

flexbox practice - step 0

再來就開始使用 flexbox 了,
首先要 定義 flex container ( step 1 )
在這個例子中,我把 .gallery 設定成 flex container。

.gallery {
    display: flex;
}

接著就馬上可以看到一些效果了 (,, ・∀・)ノ゛

flexbox practice - step 1

flex container 的下一層元素,會自動成為 flex item。
這些 flex item 預設會塞在同一列中;寬度超過 100% 時,會依比例分配父元素的寬度。
( 詳細的屬性,預計會寫在明天的文章中 =D )

不過因為我最後想要的效果不是 全部放在一行
所以要告訴瀏覽器 flex items 的寬度超過 100% 時,自動折行 ( step 2 )

.gallery {
    // ...
    flex-wrap: wrap;
}

這時版面又恢復成跟 step 0 一樣了
不過不用擔心,我們接著就要處理 flex item

在這個例子中,.img-container 是我們的 flex item
我在這邊先 設定一個預設寬度給他 ( step 3 )

.img-container {
    width: 200px;
}

現在則可以看到類似 inline-block 的效果 ( 不過不用擔心 block 之間惱人的小間隔 )

flexbox practice - step 3

接下來就是關鍵的一步: 設定 flex item 的 flex-grow 屬性 ( step 4 )

.img-container {
    // ...
    flex-grow: 1;
}

然後就大功告成了~!! 縮放視窗,就能看到不錯的效果。
撒花撒花撒花撒花撒花

從大螢幕到小螢幕的效果依序如下:

1
flexbox practice - step 4 - 1
2
flexbox practice - step 4 - 2
3
flexbox practice - step 4 - 3
4
flexbox practice - step 4 - 4
5
flexbox practice - step 4 - 5

值得一提的是,flex-grow 會自己計算剩下的空間,並判斷出要長大多少。
所以想要在 設定 item 上的 margin / padding ,設定一點間隔的話,也可以輕鬆做到。

flexbox practice - step 5


明天的文章中,預計將進一步介紹各種 flex container / flex item 的相關屬性。


上一篇
30 天 CSS 隨手筆記 - 第 01 天 - 前言
下一篇
30 天 CSS 隨手筆記 - 第 03 天 - WTF... Flexbox~!! ( 2 / 3 - 屬性介紹 )
系列文
30 天 CSS 隨手筆記30

1 則留言

0
JerryHong
iT邦新手 5 級 ‧ 2016-12-18 01:57:20

一起加油!

我要留言

立即登入留言