# CSS - Flexbox 學習 Flex 已經過一陣子了,所以做一下筆記複習與整理 Flexbox 是一種一維布局方式,可以方便地控制子元素在主軸和交叉軸上的排列。 取代使用繁瑣的浮動或定位,更輕鬆地設計複雜的佈局。 ## Flex 基本結構:Container & Item ![ExportedContentImage_00](https://hackmd.io/_uploads/HJkuYT4ylx.png) 透過 display: flex 將某個元件宣告成 flex container,然後這個容器內所有的子元素就會變成 flex item。 並運用 flex 相關屬性來操作它們的對齊、方向、順序和尺寸。 ## Flex 屬性分類 #### 🟢 外層屬性(父層 Flex Container) | 說明 | 屬性 | |------|------| | `display: flex` | 開啟 flex 模式,啟用彈性容器功能 | | `flex-direction` | 決定了子元素的主軸排列方向(row 橫向 / column 直向) | | `flex-wrap` | 是否換行(nowrap 不換行、wrap 換行) | | `justify-content` | 控制子元素在主軸上的對齊位置 | | `align-items` | 控制子元素在交錯軸上的對齊位置 | | `align-content` | 當有多行 Flex 項目時(啟用 flex-wrap: wrap),控制各行在交錯軸上的對齊方式 | #### 🟡 內層屬性(子層 Flex Item) | 屬性 | 說明 | |------|------| | `order` | 調整項目的順序(數字越小排越前面) | | `flex-grow` | 空間放大比例 (多大程度填滿剩餘空間) | | `flex-shrink` | 空間不足時的縮小比例 | | `flex-basis` | 預設大小 | | `flex` | grow + shrink + basis 的簡寫(例如:flex: 1 0 auto)| | `align-self` | 單一項目對齊方式 (覆蓋父層的 `align-items` 設定) | ### display #### `display: flex` 這使得 Flex 容器的行為類似區塊級元素。 Flex 容器佔據其父元素的整個可用寬度。它會在新的一行開始,其後的元素也會在新的一行開始。 #### `inline-flex` 這使得 Flex 容器的行為類似區塊級元素。 Flex 容器佔據其父元素的整個可用寬度。它會在新的一行開始,其後的元素也會在新的一行開始。 ## 主軸 ( main axis ) 與交叉軸 ( Cross Axis ) ![ExportedContentImage_03](https://hackmd.io/_uploads/Sya_YpVkgl.png) 每個 Flex 容器( display 屬性設定為 `flex` 或 `inline-flex` 的元素)都有一個主軸和一個交叉軸。 主軸是水平的還是垂直的,取決於 `flex-direction` 的值。 ### flex-direction ![ExportedContentImage_04](https://hackmd.io/_uploads/r1fyNfrJxx.png) `flex-direction` 屬性定義了 Flex 的排列方向。它設定了 Flex 容器的主軸。此屬性可以採用以下四個值中的任一個 `row`:預設值,由左到右,從上到下 `row-reverse`:與 row 相反 `column`:從上到下,再由左到右 `column-reverse`:與 column 相反 #### 關於反向和無障礙 當使用 `row-reverse` 和 `column-reverse` 時,這兩個值會影響螢幕上元素的視覺順序。 但是這些元素在 HTML 中的順序保持不變,而這些元素在 HTML 中的順序就是螢幕閱讀器和鍵盤導航控制項所使用的順序。 對於使用螢幕閱讀器的人來說,聽到的順序將會按照 *HTML 中的出現順序*而不是*螢幕上的順序*。 ### justify-content ![ExportedContentImage_08](https://hackmd.io/_uploads/ry-bVzHJxl.png) `justify-content` 決定了子元素與整個 Flexbox 主軸上的對齊方式,在 Flexbox 盒模型,運用 main start 與 main end 左右兩個端點,來處理主軸上空間的分配方式。 `flex-start`:預設值,對齊最左邊的 main start `flex-end`:對齊最左邊的 main end `center`:主軸置中 `space-between`:平均分配子元素,左右元素將會與 main start 和 main end 貼齊 `space-evenly` :平均分配子元素,間距與容器邊界也是平均分配 `space-around`:平均分配子元素,間距也是平均分配 ### align-items ![ExportedContentImage_09](https://hackmd.io/_uploads/HyLGVMrygl.png) `align-items` 決定了子元素與整個 Flexbox 交叉軸上的對齊方式,在 Flexbox 盒模型,具有 cross start 與 cross end 左右兩個端點,`align-items` 與 `align-self` 就是按照這個方式做設定,設定值總共有下列五個。 `stretch`:預設值,將子元素全部撐開至 Flexbox 的高度 `flex-start`:對齊最上面的 cross start `flex-end`:對齊最下面的 cross end `center`:交叉軸置中 `baseline`:以所有子元素的基線作為對齊標準 ### flex-wrap ![ExportedContentImage_05](https://hackmd.io/_uploads/rJTQ4fS1el.png) 當我們把父元素的 `display` 設定為 `flex` 或 `inline-flex` 的時候,子元素就是以單行的方式,彈性撐滿父元素,所以在容器內的空間不足以容納 `flex-wrap` 屬性來選擇讓子元素溢出還是換行。 `nowrap`(預設):不換行,可能會擠壓子元素 `wrap`:子元素會根據空間自動換行。 `wrap-reverse`:換行但順序反轉。 ### align-content ![20150130_1_08](https://hackmd.io/_uploads/rJ-1LGSkel.jpg) 當 `flex-wrap: wrap` 形成多行內容時,`align-content` 就會控制整體行與行之間的對齊方式,依照需求分配空間。 `stretch`(預設): 自動填滿整個交叉軸空間 `flex-start`: 所有行群組擠在交叉軸起點(上方) `flex-end`: 所有行群組擠在交叉軸終點(下方) `center`: 行群組集中在中間 `space-between`: 每行之間平均分配間距,首尾貼齊容器邊緣 `space-around`: 每行之間有相同間距,包含首尾 ### place-content 如果你需要同時使用 `justify-content` 和 `align-content` 屬性,你可以使用 `place-content` 縮寫屬性。 它可以接受一個或兩個值。當你給它一個單一值時,瀏覽器會為 justify-content 和 align-content 應用相同的值。 當你為 `place-content` 提供兩個值時,第一個值將用於 `align-content` ,第二個值將用於 `justify-content`。 --- ### order `order` 屬性決定子元素的排列順序。 你給這個屬性的賦值必須是一個數字。一個數字較小的子元素將出現在數字較大的子元素之前。 ### flex-grow 當你將容器的 `display` 設定為 `flex` 時,`flex-grow` 可以決定子元素如何分配剩餘空間: 0(預設):元素不會擴展。 1 以上:數值越大,元素佔據的比例越多。 ### flex-shrink 當容器空間不足時,`flex-shrink` 會決定元素的縮小程度:   1(預設):子元素根據容器大小縮小。 0:子元素不會縮小。 2 以上:子元素縮小的程度更大。 ### flex-basis `flex-basis` 用來設定子元素在主軸上的初始大小,可以是寬度或高度,這取決於 `flex-direction` 的使用。 可接受 px、% 或 auto 等單位 ### flex 由三個屬性組合而成,依照先後順序分別是 `flex-grow`、`flex-shrink` 和 `flex-basis` ,如果 `flex` 只填了一個數值 ( 無單位 ),那麼預設就是以 `flex-grow` 的方式呈現。 `flex-grow`:數字,無單位,當子元素的 flex-basis 長度「小」於它自己在父元素分配到的長度,按照數字做相對應的「伸展」比例分配,預設值為 0,不會進行彈性變化,不可為負值,設為 1 則會進行彈性變化。 `flex-shrink`:數字,無單位,當子元素的 flex-basis 長度「大」於它自己在父元素分配到的長度,按照數字做相對應的「壓縮」比例分配,預設值為 1,設為 0 的話不會進行彈性變化,不可為負值。 `flex-basis`:子元素的基本大小,作為父元素的大小比較基準,預設值為 0,也因為預設值為 0,所以沒有設定此屬性的時候,會以直接採用 flex-grow 屬性,flex-basis 也可以設為 auto,如果設為 auto,就表示子元素以自己的基本大小為單位。。 ### align-self 可以使用 align-self 為單一元素設置不同的對齊方式: `auto`(預設):繼承 align-items 設定。   `flex-start`:靠交錯軸起點對齊。   `flex-end`:靠交錯軸終點對齊。   `center`:置中對齊。   `stretch`:讓元素填滿交錯軸空間。 --- ## 總結 Flexbox 是非常實用的排版工具,讓我們能更直覺、靈活地控制元素的排列方式。無論是初學者還是有經驗的開發者,都應該熟練掌握 Flexbox 的用法,因為它已經成為響應式設計與跨裝置佈局的標準工具之一。 透過整理,學習了 Flexbox 的基本概念、外層與內層屬性,雖然無法記下所有的 flexbox 相關屬性,先理解這些屬性的觀念是什麼,等到實作專案要用到時,再回來查找和複習,同時搭配 CSS Grid 等工具,能讓整體設計更加靈活且強大。