搜尋

認識彈性盒子 Flexbox

Flex 彈性排版是近幾年網頁設計常用的排版方式,構成彈性排版的網頁元素就稱為「彈性盒子 Flexbox」,Flexbox 不需要額外設定,就具有自動對齊和調整寬高的能力,是相當好用的網頁元素!這篇教學會介紹什麼是 Flexbox,以及最基本的 flex-direction、flex-wrap 和 flex-flow 樣式屬性。

延伸閱讀:Flexbox 的對齊方式Flexbox 的彈性伸縮

快速導覽:

CSS 教學 - 認識彈性盒子 Flexbox

認識彈性盒子 Flexbox

當元素的 display 顯示類型設定為 flexinline-flex 時,該元素就變成了「彈性容器 Flex container」,這個元素裡的所有子元素都會變成「彈性項目 Flex item」,而 Flexbox 就是這一整組彈性容器與彈性項目,就會統稱為「彈性盒子 Flexbox」,透過 Flexbox 進行排版,也就可稱之為「Flexbox 彈性排版」。彈性容器與項目有各自的顯示類型,相關說明如下:

彈性盒子 元素 說明
彈性容器 設定 flex 的元素 表現和 block 相同,強制換行。
彈性容器 設定 inline-flex 的元素 表現和 inline-block 相同,不換行。
彈性項目 子元素 按照彈性容器的設定,決定對齊和換行的方式。

下方範例將 span 元素變成 flexinline-flex 兩種彈性盒子,因為顯示類型類似 blockinline-block,所以可以調整寬高,flex 的元素也會強制換行。

線上展示:https://codepen.io/oxxo/pen/ExBzpbq

<!-- HTML 程式碼-->
<span>apple</span>
<span>oxxo</span>
<span>banana</span>
<span>coconut</span>
<span class="f">apple</span>
<span class="f">oxxo</span>
<span class="f">banana</span>
<span class="f">coconut</span>
<span class="fb">apple</span>
<span class="fb">oxxo</span>
<span class="fb">banana</span>
<span class="fb">coconut</span>

<!-- CSS 程式碼 -->
<style>
  body {padding: 10px; }
  span {
    background: #f509;
    margin: 10px;
    height: 50px;
  }
  .f {
    display: inline-flex;   /* class 為 f 的元素是 inline-flex */
    background: #0c09;
  }
  .fb {
    display: flex;          /* class 為 fb 的元素是 flex */
    background: #0c09;
  }
</style>

CSS 教學 - 認識彈性盒子 Flexbox - flex 與 inline-flex 元素

下方範例將 span 元素變成彈性盒子,可以發現內容的 strongem 元素都變成彈性項目,不僅不會換行,也不會因為換行導致背景或邊框重疊的狀況 ( 參考「文字行高、文字縮排」 )。

線上展示:https://codepen.io/oxxo/pen/dyBEjJM

<!-- HTML 程式碼-->
<span><strong>apple</strong> <em>banana</em> <em>orange</em></span>
<span class="f"><strong>apple</strong> <em>banana</em> <em>orange</em></span> 
<span><strong>An apple a day keeps the doctor away!!</strong> <em>Hello World! I am oxxo.studio!!</em></span>
<span class="f"><strong>An apple a day keeps the doctor away!!</strong> <em>Hello World! I am oxxo.studio!!</em></span>

<!-- CSS 程式碼 -->
<style>
  body {padding: 10px;}
  span {
    border: 1px solid #000;
    margin: 10px;
    padding: 5px;
  }
  strong, em {
    background: #f509;
    margin: 5px;
  }
  .f {display: flex;}        /* class 為 f 的元素是 flex 元素 */
  .f * {background: #0c09;}  /* flex 元素的子元素背景都是綠色 */
</style>

CSS 教學 - 認識彈性盒子 Flexbox - inline 元素轉換成 flex 元素

下方範例將 div 元素變成彈性盒子,可以發現內容的 divstrongem 元素都變成彈性項目,不僅不會換行,也不會因為換行導致背景或邊框重疊的狀況。

線上展示:https://codepen.io/oxxo/pen/PorvBEK

<!-- HTML 程式碼-->
<div><div>apple</div> <div>banana</div> <div>orange</div></div>
<div class="f"><div>apple</div> <div>banana</div> <div>orange</div></div> 
<div><strong>An apple a day keeps the doctor away!!</strong> <em>Hello World! I am oxxo.studio!!</em></div>
<div class="f"><strong>An apple a day keeps the doctor away!!</strong> <em>Hello World! I am oxxo.studio!!</em></div>

<!-- CSS 程式碼 -->
<style>
  body {padding: 10px;}
  div {
    border: 1px solid #000;
    margin: 10px;
    padding: 5px;
  }
  div * {
    border: none;
    background: #f509;
    margin: 5px;
  }
  .f {display: flex;}        /* class 為 f 的元素是 flex 元素 */
  .f * {background: #0c09;}  /* flex 元素的子元素背景都是綠色 */
</style>

CSS 教學 - 認識彈性盒子 Flexbox - block 元素轉換成 flex 元素

Flexbox 相關樣式屬性

CSS 有專門針對 Flexbox 的樣式屬性,這些樣式屬性只有在 Flexbox 容器或項目才會作用 ( 部分通用於顯示類型為 Gird 元素 ),下方列出 Flexbox 相關樣式屬性:

Flexbox 相關樣式屬性 說明 作用元素
flex-direction 彈性元素方向 彈性容器
flex-wrap 彈性元素換行 彈性容器
flex-flow 彈行元素方向縮寫樣式 彈性容器
justify-content 水平對齊 彈性容器
align-items 單行垂直對齊 彈性容器
align-content 多行垂直對齊 彈性容器
align-self 覆寫單一元素垂直對齊方式 彈性項目
flex-grow 彈性項目「擴展」比例 彈性項目
flex-shrink 彈性項目「縮小」比例 彈性項目
flex-basis 彈性項目「基礎」比例 彈性項目
flex 彈性伸縮樣式縮寫 彈性項目
order 彈性項目順序位置 彈性項目

flex-direction 彈性元素方向

當元素變彈性盒子之後,就會採用「軸向」作為排版佈局的方式,而不是使用傳統常見的 inlineblock 進行排版,flex 元素的軸向分成「主軸 Main axis」和「交叉軸 Cross axis」,兩條軸線呈垂直狀態,子元素會根據「主軸的方向」進行排列 ( 從起點 main start 出發往結束點 main end 的方向 )。

主軸通常表示「水平方向」,交叉軸通常表示「垂直方向」。

CSS 教學 - 認識彈性盒子 Flexbox - Flexbox 軸向

flex-direction 樣式屬性表示主軸 main axis 的方向,也就是子元素排列的方向,沒有繼承特性,共有下列幾種屬性值:

屬性值 說明
row 左到右 ( 預設值 )
row-reverse 右到左
column 上到下
column-reverse 下到上

下方範例使用四個變成 flex 彈性容器的 div,分別呈現四種不同的彈性項目排列方向。

線上展示:https://codepen.io/oxxo/pen/MWMdBrZ

<!-- HTML 程式碼-->
<div class="f a"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div></div>
<div class="f b"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div></div>
<div class="f c"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div></div>
<div class="f d"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div></div>

<!-- CSS 程式碼 -->
<style>
  .f {
    display: flex;           /* 設定為彈性容器 */
    border: 1px solid #000;
    font-family: monospace;
    font-size: 20px;
    margin: 5px;
    width: 200px;
    height: 200px;
  }
  .a {flex-direction: row;}              /* 左到右 */
  .b {flex-direction: row-reverse;}      /* 右到左 */
  .c {flex-direction: column;}           /* 上到下 */
  .d {flex-direction: column-reverse;}   /* 下到上 */
  div div {
    text-align: center;
    width: 30px;
    height: 30px;
    margin: 2px;
  }
  div div:nth-child(1) {background: #f90;}
  div div:nth-child(2) {background: #f66;}
  div div:nth-child(3) {background: #4d4;}
  div div:nth-child(4) {background: #4bf;}
  div div:nth-child(5) {background: #f9f;}
</style>

CSS 教學 - 認識彈性盒子 Flexbox - flex-direction 彈性元素方向

如果同時使用 writing-mode:rlwriting-mode:lr,會造成軸向反轉,呈現出不同方向的排列效果 ( 參考 writing-mode 書寫模式 )。

線上展示:https://codepen.io/oxxo/pen/rNEgrpg

<!-- HTML 程式碼-->
<div class="f a"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div></div>
<div class="f b"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div></div>
<div class="f c"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div></div>
<div class="f d"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div></div>
<div class="f r a"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div></div>
<div class="f r b"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div></div>
<div class="f r c"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div></div>
<div class="f r d"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div></div>

<!-- CSS 程式碼 -->
<style>
  .f {
    display: flex;
    border: 1px solid #000;
    font-family: monospace;
    font-size: 20px;
    margin: 5px;
    width: 200px;
    height: 200px;
    writing-mode:vertical-rl;   /* 設定書寫方向 */
    float: left;
  }
  .f.r {
    writing-mode:vertical-lr;   /* 設定書寫方向 */
  }
  .a {flex-direction:row;}
  .b {flex-direction:row-reverse;}
  .c {flex-direction:column;}
  .d {flex-direction:column-reverse;}
  div div {
    text-align: center;
    width: 30px;
    height: 30px;
    margin: 2px;
  }
  div div:nth-child(1) {background: #f90;}
  div div:nth-child(2) {background: #f66;}
  div div:nth-child(3) {background: #4d4;}
  div div:nth-child(4) {background: #4bf;}
  div div:nth-child(5) {background: #f9f;}
</style>

CSS 教學 - 認識彈性盒子 Flexbox - flex-direction 彈性元素方向搭配不同書寫方向

flex-wrap 彈性元素換行

當彈性容器的寬度無法容納彈性項目時,彈性項目在預設的狀態下仍然會保持「自動分配寬度」且「不換行」,如果最後寬度不足就會超過容器範圍,而 flex-wrap 樣式屬性可以控制彈性項目的換行行為,沒有繼承特性,相關屬性值如下:

屬性值 說明
norwap 彈性項目維持一行,不換行,可能會溢出父元素寬度 ( 預設值 )。
wrap 允許多行,換行後出現在原行之前。
wrap-reverse 許多行,換行後出現在原行之後,類似 cross axis 反轉。

下方使用兩組範例,第一組的三個 div 使用預設 flex-direction 樣式,搭配九個彈性項目呈現不同的換行效果,第二組的三個 div 使用 flex-direction:column-reverse;,呈現不同軸向換行的效果。

線上展示:https://codepen.io/oxxo/pen/LYKoBQG

<!-- HTML 程式碼-->
<div class="f a"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div></div>
<div class="f b"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div></div>
<div class="f c"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div></div>
  
<div class="f cr a"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div></div>
<div class="f cr b"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div></div>
<div class="f cr c"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div></div>

<!-- CSS 程式碼 -->
<style>
  .f {
    display: flex;
    border: 1px solid #000;
    font-family: monospace;
    font-size: 20px;
    margin: 40px 10px;
    width: 200px;
    height: 200px;
    float: left;
  }
  .a {flex-wrap: nowrap;}
  .b {flex-wrap: wrap;}
  .c {flex-wrap: wrap-reverse;}

  .cr {flex-direction: column-reverse;}  /* class 為 cr 的為 column-reverse */

  div div {
    text-align: center;
    width: 30px;
    height: 30px;
    margin: 2px;
  }
  div div:nth-child(1) {background: #f90;}
  div div:nth-child(2) {background: #f66;}
  div div:nth-child(3) {background: #4d4;}
  div div:nth-child(4) {background: #4bf;}
  div div:nth-child(5) {background: #f9f;}
  div div:nth-child(6) {background: #fc0;}
  div div:nth-child(7) {background: #0b5;}
  div div:nth-child(8) {background: #0df;}
  div div:nth-child(9) {background: #aaa;}
</style>

CSS 教學 - 認識彈性盒子 Flexbox - flex-wrap 彈性元素換行

flex-flow 彈行元素方向縮寫樣式

flex-flow 樣式屬性其實只是 flex-directionflex-wrap 的「縮寫樣式」,沒有繼承特性,具有兩個屬性值,分別是 flex-directionflex-wrap 的屬性值 ( 位置可顛倒 ),初始值為「row nowrap」,如果只輸入一個屬性值,另外一個屬性值就會帶入預設值

下方的範例分別展示「單一屬性值」、「兩個屬性值」、「兩個屬性值位置顛倒」的呈現方式。

線上展示:https://codepen.io/oxxo/pen/vYqwadg

<!-- HTML 程式碼-->
<div class="f a"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div></div>
<div class="f b"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div></div>
<div class="f c"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div></div>
<div class="f d"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div></div>

<!-- CSS 程式碼 -->
<style>
  .f {
    display: flex;
    border: 1px solid #000;
    font-family: monospace;
    font-size: 20px;
    margin: 20px 10px;
    width: 200px;
    height: 200px;
    float: left;
  }
  .a {flex-flow: wrap;}           /* 單一屬性值 */
  .b {flex-flow: row wrap;}       /* 兩個屬性值,等於上方效果 */
  .c {flex-flow: column-reverse wrap-reverse;}  /*  兩個屬性值 */
  .d {flex-flow: wrap-reverse column-reverse;}  /*  兩個屬性值位置顛倒,等於上方效果 */

  div div {
    text-align: center;
    width: 30px;
    height: 30px;
    margin: 2px;
  }
  div div:nth-child(1) {background: #f90;}
  div div:nth-child(2) {background: #f66;}
  div div:nth-child(3) {background: #4d4;}
  div div:nth-child(4) {background: #4bf;}
  div div:nth-child(5) {background: #f9f;}
  div div:nth-child(6) {background: #fc0;}
  div div:nth-child(7) {background: #0b5;}
  div div:nth-child(8) {background: #0df;}
  div div:nth-child(9) {background: #aaa;}
</style>

CSS 教學 - 認識彈性盒子 Flexbox - flex-flow 彈行元素方向縮寫樣式

小結

彈性盒子 Flexbox 的排版方式,是目前網頁設計師愛用的排版技巧,可以用更簡單的 HTML 和 CSS 程式碼,做出更多靈活彈性的版面,大家不妨開始在自己的網頁中使用 Flexbox 吧!

延伸閱讀:Flexbox 的對齊方式Flexbox 的彈性伸縮

意見回饋

如果有任何建議或問題,可傳送「意見表單」給我,謝謝~

CSS 教學

基本介紹

認識 CSS 開始使用 CSS CSS 語法規則 CSS 命名原則

CSS 選擇器

認識 CSS 選擇器 優先順序 ( 權重 ) 樣式繼承與聯集 元素選擇器 ID 和 Class 選擇器 屬性選擇器 文件結構選擇器 虛擬類別選擇器 ( 結構 ) 虛擬類別選擇器 ( 類型 ) 虛擬類別選擇器 ( 輸入 ) 虛擬類別選擇器 ( 行為 ) 虛擬類別選擇器 ( 超連結 ) 虛擬類別選擇器 ( 邏輯 ) 虛擬類別選擇器 ( 其他 ) 虛擬元素選擇器 群組與組合選擇器

數值與單位

關鍵字與文字數值 長度與角度單位 顏色單位 位置名稱與時間單位

變數與內容函式

變數 數學計算 文字與清單計數 生成內容與引號

顏色與濾鏡

色彩模型 漸層色 影像濾鏡

文字樣式

使用通用字型 使用外部字型 @font-face 定義字型 文字尺寸 常用文字樣式 文字換行 文字空白與 Tab 大小 文字行高與縮排 文字水平與垂直對齊 文字書寫方向 特殊文字樣式

元素容器

容器顯示類型 ( display ) 元素 display 對照表 盒子模型 ( Box Model ) 寬度與高度 內邊距 ( padding ) 外邊界 ( margin ) 邊框 ( border ) 邊框圓角 影像邊框 輪廓 ( outline ) 可見性與透明度 內容溢出與裁切

背景與陰影

背景顏色 背景圖 ( 定位、尺寸 ) 背景圖 ( 固定、重複 ) 背景圖 ( 多重背景、混合 ) 背景縮寫 ( background ) 容器陰影 ( box-shadow )

清單與表格

清單樣式 清單計數器 定義計數規則 表格基本樣式 表格邊框樣式 表格內容寬度與對齊

基本排版與定位

元素排版方式 浮動 ( float ) 浮動形狀 定位 ( position )

Flexbox 彈性排版

Flexbox 彈性盒子 Flexbox 對齊方式 Flexbox 彈性伸縮

Grid 網格排版

Grid 網格容器與格線 Grid 網格空間與命名 Grid 網格流向與間距 Grid 排列網格項目 Grid 項目對齊與順序

轉場與動畫

轉場 ( transition ) 轉場觸發事件 動畫 ( animation ) 動畫觸發事件 多重動畫的權重與順序

變形、裁切與遮罩

裁切路徑 ( clip-path ) 影像遮罩 ( mask )