CSS Flexbox


課堂練習參考範例

簡介

考慮到網頁排版以文字流為主軸的概念,有時並不是這麼適合用來製作人機介面。這時我們可以使用 display 樣式的一個特別的屬性 "flex" 來使用 Flexbox Layout 做排版。

<div style="display:flex"></div>

display: flex 設定了一種新的排版方式,讓我們可以更自由彈性的設定標籤的位置,其中包括了:

  • 標籤的流向
  • 標籤的對齊
  • 標籤的尺寸

設定 display: flex 的標籤通常是做為容器,而上述的位置設定則是針對容器內的標籤所做。例如,下例中我們加了三個 div 標籤在容器中:

<div style="display:flex"> <div>A</div> <div>B</div> <div>C</div> </div>

原本應該是 block 顯示樣式的 div 標籤,因為容器的 display: flex 樣式,而變成了並排的形式:

A
B
C

flex-direction

文字流預設為從左到右、從上到下,但 flexbox 提供了不同的文字流向供我們設定。使用 flex-direction 樣式,你可以設定四種不同的流向:

  • column ( 從上到下 )
  • row ( 從左到右 )
  • column-reverse ( 從下到上 )
  • row-reverse ( 從右到左 )
A
B
C

你可能會注意到在 column 模式下,三個方塊都佔滿了整個橫向的空間。事實上我們在使用 flexbox 時需要考慮兩個方向:

  • main axis ( 主軸 ): 即 flex-direction 指定的文字流向
  • cross axis ( 副軸 ): 與主軸垂直的方向

其中副軸方向亦有不同的樣式可以設定其排版、尺寸等表現。flexbox 中的元素在副軸方向的排版方式預設是「stretch 」 ( 佔滿 ),而在主軸方向則是「start」( 向起點靠齊 ),這兩種排版方式分別由「align-items」以及「justify-content」來控制。

align-items

align-items 可以用來控制元素在 副軸 上的排版方式。例如,使用 align-items: center 可讓子標籤置中對齊:

A
B
C

justify-content

justify-content 可以用來控制元素在主軸 上的排版方式。例如,使用 justify-content: around 可讓子標籤平均散布在容器中:

<div style="display:flex;justify-content:aounrd"> <div style="background:#ccc">A</div> <div style="background:#ccc">B</div> <div style="background:#ccc">C</div> </div>

結果如下:

A
B
C

我們亦可使用 gap 樣式來控制容器內元素彼此間的距離,做出類似 margin 的效果。以下例來說,我們使用 justify-content-center 讓元素置中靠齊後,再用 gap: .25em 讓元素間保留 0.25em 的空隙,並與 gap: 0em 的樣式做對比:

gap: .25em
A
B
C
gap: 0em
A
B
C
試試看吧!

試試看 justify-content 的不同效果吧:

justify-content: start
A
B
C
justify-content: end
A
B
C
justify-content: space-around
A
B
C
justify-content: space-between
A
B
C
justify-content: center
A
B
C

flex-basis, flex-grow, flex-shrink

除了以容器的角度來操縱內部元素的排版,你亦可單獨設置個別元素的大小。不同於 widthheight 樣式,flexbox 的一個重要特色即是可以讓我們在容器尺寸不同時,按照我們的設定針對個別子元素做尺寸的縮放。

一個最常見的使用情境即是讓元素自動填滿容器用剩的空間。以下例來說,容器中有三個元素,其中左右元素的尺寸固定為 3em ,若我們想讓中間元素自動填滿剩餘空間,可以使用 flex-grow: 1 這個樣式設定:

3em
( 未設定 flex-grow )
3em
3em
自動填滿 ( flex-grow: 1)
3em

相反的,若容器空間較小,我們希望讓子元素可以自動縮小,則可以使用 flex-shrink 樣式。

flex-growflex-shrink 中的數值可以是任意數字,他們代表了放大與縮小的相對比例;以上例來說,若我們想讓三個元素都能夠填滿,但放大比例是 1 : 3 : 1 的話,我們可以使用下例的設定:

flex-grow: 1
flex-grow: 3
flex-grow: 1

要注意這個縮放的比例是指「剩餘空間的分配」,也就是容器的尺寸扣掉元素預設尺寸 ( basis ) 後的空間。以下例來說,就是容器扣掉 20px + 40px + 60px = 120px 之後的空間,再按照 1 : 3 : 1 的方式來分配:

flex-grow: 1
width: 20px
flex-grow: 3
width: 40px
flex-grow: 1
width: 60px
對照組 ( 寬度均設定為 0px )
flex-grow: 1
width: 0px
flex-grow: 3
width: 0px
flex-grow: 1
width: 0px

元素預設尺寸可以透過 flex-basis 樣式設定,其預設值為 auto 會由 width ( 或 height, 視 flex-direction 而定 ) 樣式取值,所以預設即為元素本身的寬度值,但若你設定 flex-basis 為特定的值,flexbox 則會優先使用你設定的值做計算。

flex-grow, flex-shrinkflex-basis 可以合併寫成一個單一樣式 flex:

<div style="flex:1 0 auto">...</div>
試試看吧!

1. 試著重現自動填滿的範例:

A
B
C

2. 搭配不同的 flex-grow 做出寬度遞增的元素列表:

A
B
C
D
E
F
G

3. 接著,使用 flexbox 製作出如下圖的排版,佔滿整個畫面,外圍高度(上下) / 寬度(左右) 固定為 3em,中央紅色區域則隨視窗大小自動調整:

你可以參考以下連結來學習、測試 flexbox 的效果:

樣式列表

當一個標籤將 display 樣式設定為 flex 時,我們可以再用以下的樣式設定內容的排版方式:

樣式名可能的值用途
flex-directionrow / column / row-reverse / column-reverse內容的流向 ( 左到右 / 上到下 / 右到左 / 下到上 )
flex-wrapwrap / nowrap是否允許換行
justify-contentstart / end / center / space-around / space-between主要方向的內容對齊方式
align-itemsstart / end / center / baseline / stretch行內元素的對齊
align-contentstart / end / center / space-between / space-around / stretch行元素的對齊方式

flex 標籤內的子元素則可以設定以下樣式:

flex-grow數值當 flexbox 尚有空間時,此元素自動放大的比例
flex-shrink數值當 flexbox 空間不足時,此元素自動縮小的比例
flex-basis數值 或 auto此元素尚未更新大小前的基準尺寸
flex見右

flexflex-grow, flex-shrink, flex-basis 三者合併的簡寫。例如:

<div style="flex:1 1 auto"></div>
align-self同 align-items類似 align-items, 但作用在單一元素上
order數值此元素在 flexbox 中的順序
進階排版

1. 利用 flexbox 排版資訊:

xinmeti.co
新媒體內容與設計課程
輔仁大學新聞傳播學系
立即註冊

2. 利用 flex-grow + remixicon 圖示 製作出臉書的功能列 ( 注意滑鼠移入時的背景效果 ):

( 使用的圖示為 ri-thumb-up-lineri-discuss-lineri-share-forward-lineri-user-lineri-arrow-down-s-fill )
留言
留言

3. 試利用 flexbox 排出如下圖的作品小卡:

範本1
範本2
範本3
範本4
範本5
範本
頭貼
作者姓名
關於作品的簡單描述 ...
追蹤

4. 全部合體

範本1
範本2
範本3
範本4
範本5
範本
頭貼
作者姓名
關於作品的簡單描述 ...
追蹤
xinmeti.co
新媒體內容與設計課程
輔仁大學新聞傳播學系
立即註冊
留言
留言
新媒體內容技術與設計

New Media Techniques and Design