標題是來自這個 flexbox.io 這個網站的頁首
網路上有非常多的資源了,例如:
而現在的支援度更是已經高到做夢都會笑了:
( 截圖來源:http://caniuse.com/#search=flex )
尤其在手機上不用考慮 IE,更是可以放心大膽得用。
這個樣式現在也被廣泛利用在各種版面上,例如:facebook 手機版導航列 / google 搜尋頁等。
使用 flexbox 的 facebook 手機版導航列
使用 flexbox 的 google 搜尋頁部份切版
這篇將用一個簡單的實例,闡述 flexbox 的基本觀念。
首先必須要講到 layout mode。
CSS 固有的模式有四種:block / inline / table / positioned。
曾經流行的 table-based layout / div-based layout,都能達到一些效果。
但隨著 RWD 概念興起,網頁 / app 的版面設計越來越多變,大家意識到了我們需要更全面的佈局方式。
Flexbox 全名 Flexible Box,是 2009 年由 W3C 提出的新模式,
能夠更簡潔處理 layout,並有效地解決很多過去不容易處理的問題 ( 例如:垂直置中 )。
如同上面的段落所說,flexbox 對於版面來說,是個更簡潔、更完整的模式。
對工程師來說,可以少寫一點 code 來達成一樣 ( 甚至更好 ) 的效果。
以 Gallery 的效果為例,如果想要在不使用 js 的前提下達到以下的效果:
圖片最小為 200px
一列的圖片數為 Math.floor(100% / 200px) ( 原諒我想不到更好的說詞了 Orz )
- 預設一列一張圖片
- 容器寬度 > 400px 時,預設一列兩張 ( 最後一列可能只有一張 )
- 容器寬度 > 600px 時,預設一列三張 ( 最後一列可能只有一張或兩張 )
- ... 以此類推
圖片的寬度平分整列的寬度
- 一列一張圖時,寬度為 100%
- 一列兩張圖時,寬度為 50%
- ... 以此類推
我沒有想到使用 float 的方法 ( ̄艸 ̄")
( CSS 現在還沒有支援 max / min )
但使用 flexbox,可以用少少的 code 做到這個效果:Gallery Sample
以下就以剛剛的 Gallery 為例,一邊撰寫樣式,一邊說明基本的 flexbox 概念。
想做到的效果:
- 圖片最小為 200px
- 一列的圖片數為 Math.floor(100% / 200px)
- 圖片的寬度平分整列的寬度
開始之前,我先寫了一些 基本的 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 了,
首先要 定義 flex container ( step 1 )
在這個例子中,我把 .gallery
設定成 flex container。
.gallery {
display: flex;
}
接著就馬上可以看到一些效果了 (,, ・∀・)ノ゛
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 之間惱人的小間隔 )
接下來就是關鍵的一步: 設定 flex item 的 flex-grow 屬性 ( step 4 )
.img-container {
// ...
flex-grow: 1;
}
然後就大功告成了~!! 縮放視窗,就能看到不錯的效果。
從大螢幕到小螢幕的效果依序如下:
1
2
3
4
5
值得一提的是,flex-grow 會自己計算剩下的空間,並判斷出要長大多少。
所以想要在 設定 item 上的 margin / padding ,設定一點間隔的話,也可以輕鬆做到。
明天的文章中,預計將進一步介紹各種 flex container / flex item 的相關屬性。