[CSS Note] - 第一次 Flex 就上手

網頁佈局

Introduction & 前言

相信只要接觸切版的人,都聽過現代人都已經在使用 Flexbox 排版了,如果還在用 Float 不如學著用 Flexbox,排版會輕鬆很多。

如果你已經試著想要著手暸解 Flexbox 不妨參考看看接下來的文章,也許沒辦法讓你變成 Flexbox 神手,但或許你能找到一根還能用的釣竿…

首先還是要提醒,Flexbox 適用於較小區塊的排版,如果是較大的區塊,比如 Header、Sidebar、Content、Footer 這樣的排版,還是建議使用 Grid 來做排版。

Flexbox 的歷史 及 為什麼要學?

俗話說 『飯在吃,也要知道飯哪裡來的』;Flexbox2009 年開始,但剛開始瀏覽器支援度其實沒有很高,一直到 2015、2016 開始趨於穩定,到現在幾乎是所有瀏覽器都已經支援了,基於下面四點我非常推薦切版人一定要好好學習:

  1. 排版簡單

  2. 排版快速

  3. 易上手

  4. 裝置支援度高

看來還是只有IE不乖 但算合格了


Summary & 摘要

一直想寫一篇關於 Flexbox 的文章,碰巧最近六角學院的課程剛好會使用 Flex,而且課前任務就是要完成 Flex 課程的兩項排版,趁著這次把該記得筆記記下來,就跟著我一起開心學 Flex 吧!

  1. 基礎認識

  2. 屬性介紹

  3. 實作練習


基礎認識

幾乎每篇 Flexbox 文章都說到必須先認識一個基礎概念, Flexbox 可以主要分為兩大類:

  1. Flex container (容器)

  2. Flex item (子項目)

看圖最容易懂

想要將一個元素設定為 Flex container 其實很簡單,在元素上加入 display: flexdisplay: inline-flex 即可。兩個差別類似 display: blockdisplay: inline-block 的差別,下面有詳細介紹。

1
2
3
4
5
<div class="container">    //- => 外容器
<div class="box"></div> //- => 子項目
<div class="box"></div> //- => 子項目
<div class="box"></div> //- => 子項目
</div>
1
2
3
.container {
display: flex;
}

題外話 block 及 inline-block

如果這邊您已經瞭解了,可以跳過。

相信很多人跟我一樣,剛開始切版其實不管 blockinline-block,反正能用就用,不過有時候強迫症一來,還是會想要釐清差別到底是什麼。

blockinline-block 簡單的兩個記法為前者是 block(區塊元素) 後者則是 **inline-block(區塊及行內元素)**。

block(區塊元素) inline(行內元素) inline-block(區塊及行內元素)
特性 會將整個容器空間擠滿,不在這裡面的就會換行 會與文字等等段落擠在同一行,不會強行將空間佔滿 同時具有 inline 同行的特性,又能維持 block 的特性

這邊你可能會好奇,那 inlineinline-block 又有什麼差別呢?

其實你只需要記得一個大方向,block 前後會換行,會站滿父元素的整個寬度,inlineinline-block 前後不會換行,可以一個擠一個,前者可以設定左右的 margin、padding,後者上下左右都能設定 margin、padding

詳細介紹可以看這邊:學習CSS版面配置

block(區塊元素) 及 inline(行內元素) 的分類可以看這邊:[CSS教學] - CSS基礎您不能不知道的block(塊元素)、inline(內聯元素)差別


屬性介紹

Flex container (容器)

想學好 Flexbox 就必須要先知道兩條線,分別為 主軸(main axis) 及 **交叉軸(cross axis)**,但就我個人而言比較喜好用 主軸副軸 來記,依個人好記為主。

Flexbox 的關鍵

上方我們有提到 inlineinline-block 一般我們見到的情境大概就是長這樣:

而我們通常會在外層的 Flex container (容器) 加入 **display: flex;**,這時候你會發現似乎容器自動幫我們變成 inline-block 的感覺。

你已經踏出第一步了,接下來這邊會介紹幾個 Flex container (容器) 的屬性介紹。

flex-direction

這一屬性決定 主軸(main axis) 的方向,進而會影響到 Flex item (子項目) 的排列, flex-direction 預設為 row,就是由左到右,如果想要上下就改為 flex-direction: column,另外如果需要反轉在後面加上 -reverse 即可。

1
2
3
.container {
flex-direction: row | row-reverse | column | column-reverse;
}

如果是 flex-direction: row,主軸就是左到右:

主軸為左到右

如果是 flex-direction: column,主軸就是上到下:

主軸為上到下

flex-wrap

這個屬性可以決定要不要讓所有元素擠在同一行, flex-wrap 預設是所有擠在同一行,但是 flexbox 會自己分配空間。

1
2
3
.container{
flex-wrap: nowrap | wrap | wrap-reverse;
}

flex-flow

這個屬性可以說是 flex-directionflex-wrap 的融合,簡單說就是可以一行搞定兩個屬性。

1
2
3
.container{
flex-flow: flex-direction(預設為row) || flex-wrap(預設為nowrap)
}

justify-content

這邊開始可以說是 flexbox 的地基了,你決定地基怎麼蓋,最終的成果就會蓋出怎麼樣的房子。

1
2
3
.container {
justify-content: flex-start | flex-end | center | space-between | space-around;
}

注意主軸方向

另外還有 space-betweenspace-around 兩屬性,前者會將空白平均分配到所有 Flex item 之間,第一個 item 靠在最左邊*,最後一個 item 靠在最右邊,後者將平均分配空間到所有的 Flex item 周圍,但你會發現似乎中間的間距比較大,原因在於中間的間隔方式不同,中間的間隔是左邊 item 的右間隔加上右邊 item 的左間隔。

align-items

主軸講過了接著就換交錯軸了,這個屬性基本上和 justify-content 只是他是跑在交錯軸上,如果今天 flex-directionrow 代表主軸由左到右,交錯軸由上到下,但是如果 flex-directioncolumn 代表主軸由上到下,交錯軸由左到右,除非交錯軸也被更換了方向。

1
2
3
.container {
align-items: flex-start | flex-end | center | baseline | stretch;
}

align-content

此一屬性相當於 justify-contentalign-items 的合體,但是 主軸(main axis) 沒有換行時,此屬性不會作用,其實這個屬性我是很少用到。

1
2
3
.container {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}

Flex item (子項目)

上面講了一串終於要說子項目了,這邊要記得一個觀念,以下面程式碼的例子來看,float、clearvertical-alignFlex item(子項目) 不會有影響,有影響的是 box 下面那層開始。

1
2
3
4
5
6
7
8
9
10
11
<div class="container"> 
<div class="box box_1">
<span>1</span>
</div>
<div class="box box_2">
<span>2</span>
</div>
<div class="box box_3">
<span>3</span>
</div>
</div>

order

這個屬性可以控制元素的排列順序,數字越小,得以放越前面,這是個很方便很簡單的不需要透過修改 HTML 就能改變順序的 CSS

1
2
3
.flex-item {
order: 'number';
}

以下面的例子來說,原本順序應該為 紅黃綠,但是賦予了黃色 order:1 的屬性,在三個之中是最小的,所以會被放到主軸開頭去。

flex-grow 及 flex-shrink

這個元素設定了每一個 flex-item 在需要時自動佔滿父元素的程度,如果 flex-item 都是設定1 ,那便會等值分配,如果其中一個設定為 2,那他將會是其他元素分配比例的 兩倍大

1
2
3
4
.flex-item {
/* 預設為 0 */
flex-grow: 'number';
}

而 flex-shrink 則是相反

1
2
3
4
.flex-item {
/* 預設為 1 */
flex-shrink: 'number';
}

flex-basis

這個可以想像為 min-width,但是他的權重大於 min-width,如果需要伸縮時,將會比照 flex-growflex-shrink 的設定來伸縮。

1
2
3
4
.flex-item {
/* 預設為 auto */
flex-basis: 'length' | auto;
}

flex

此屬性為 flex-growflex-shrinkflex-basis 的縮寫,第二及第三個參數可以不寫,預設為 0 1 auto

1
2
3
4
.flex-item {
/* 預設為 auto */
flex-basis: 'length' | auto;
}

通常建議使用此屬性來設定,盡量避免單獨使用 flex-growflex-shrinkflex-basis 三個屬性來設定 flex-item 的寬高。

align-self

此值可以將 flex-item 的 align-items 屬性覆蓋過去,使用更為彈性的設定。

1
2
3
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

實作練習

這邊會提供一份六角學院的 Flex 練習到 Github 有興趣的同學也可以下載下來練習看看,裡面有10個練習題,也會有我的實作成果,十個練習題如下:

  1. 並排卡片

  2. 雙欄排版

  3. 雙欄選單設計

  4. 表頭表尾設計

  5. 常見三種排版

  6. 圖文並排

  7. 首頁橫幅排版

  8. 圖文並排設計

  9. 訂單明細

  10. 產品列表

不得不說這十個題目真的是非常非常非常常遇到,推薦一定要練習看看,也不得不讚嘆 Flex 的方便呀,想如今置中多麽容易(雖然我剛接觸前端就有 Flex 了),真是多幸福的年代(笑


Conclusion & 結論

這次報名了六角的切版直播課程,課程前有幾個任務,其中之一就是 Flex,當初其實還很猶豫要不要報名,但是基於最近案子真的是超級趕,權衡之下還是覺得雖然沒什麼時間,但還是想練習好自己的切版功力,以應付今天PM要你先照感覺切,明天就跟你說要改,後天就要驗收的情況…希望這次八週的課程可以撐過去Q


參考網站