# Flex Box
###### tags: `CSS`
Flexbox 設定分為 :
1. 彈性容器(flex container)
2. 彈性項目(flex items)

## 彈性盒設定
### display:flex
設定父元素 display:flex 為*彈性容器*,子元素會變成*彈性項目*(無論什麼類型的盒子都會被==區塊化==)。
1. 彈性項目預設是由左至右順序排列
2. 但不一定填滿彈性容器的寬度
3. 且高度會相等。
以下為 `displey:flex` 預設屬性/值
```css=
flex-direction: row ;
flex-wrap: nowrap;
justify-content: flex-start ;
align-items: stretch;
```

### flex-direction 彈性盒軸向
水平row/垂直column
彈性盒布局是以主軸與次軸為基礎,flex-direction 可以決定主軸水平或垂直,決定主軸方向後,次軸就是另一個方向。就可以知道主/次軸的起/終點,作為對齊依據。
主軸方向可變,用起/終點(start/end),不是左右。
1. <font color="red">**row**</font> 主軸為橫向 ==(預設值)==
`flex-direction : row` 主軸為水平,彈性項目水平排列。

2. <font color="red">**column**</font> 主軸為直向
`flex-direction : column` 主軸為垂直,彈性項目垂直排列。

:::danger
預設 row 可反轉顯示 row-reverse
colume 反轉column-reverse

:::
## 設定對齊
決定主軸 flex-direction 後,可以設定對齊。
主軸對齊 justify-content
次軸對齊 align-items
### **justify-content**
- flex-start (預設) 對主軸main-start
- flex-end 對其主軸 main-end
- center 對其主軸中央
- space-between 首位項目放置於 main-start ,末尾項目放置於main-end,剩餘空間/(n-1) =>平均分配空間
- space-around 彈性項目周圍分配相同空間
- space-evenly 彈性項目之間的間隔相等
1. justify-content : flex-start ==(預設值)==
對齊主軸起點(左邊)

2. justify-content : center
對齊主軸置中。

3. justify-content : space-between
對齊起終點,剩下平均分配。

4. justify-content : around
剩餘空間平均分配給彈性項目的左右。


5. justify-content : space-evenly
彈性項目之間的間隔相等

### align-items
- stretch (預設) <font color="red">延伸拉長</font>彈性項目的最大尺寸(會依據flex-direction 決定拉長高度或寬度)
- flex-star 對齊次軸 cross-start
- flex-end 對齊次軸 cross-end
- center 對齊次軸中央
- baeline 對其彈性項目文字底部的 baeline
1. align-items : stretch ==(預設)==

2. align-items : flex-star

3. align-items : flex-end

4. align-items : center

5. align-items : baeline

### flex-wrap
可以設定單行(不換行)/多行(換行)
1. flex-wrap : nowrap ==(預設值)==

2. flex-wrap : wrap

### flex-flow
`flex-direction` + `flex-wrap` = `flex-flow`
表示主軸方向與換行屬性
flex-flow : row nowrap
### 彈性項目水平垂直居中
```css=
display:flex;
justify-content: center;
align-items:center;
```

## 彈性項目設定
彈性項目可設定的屬性
彈性項目設定自己的對齊
### align-self 彈性項目次軸的對齊
個別設定彈性項目次軸的對齊。
```html=
<div class="row d-flex">
<div class="col align-self-start">彈性項目 01</div>
<div class="col align-self-center">彈性項目 02</div>
<div class="col align-self-end">彈性項目 03</div>
<div class="col align-self-stretch">彈性項目 04</div>
</div>
```

:::info
元素display:flex ,成為彈性容器,子元素成為彈性項目,也產生預設屬性。
[彈性項目的設定屬性]
flex-grow 0; 彈性伸展係數
flex-basis:auto 彈性尺寸
縮寫=> flex: 0 1 auto
:::
### flex-grow 彈性伸展係數
預設值為 `flex-grow : 0 `
彈性項目的伸展係數,決定彈性項目是否伸展,預設0為不伸展。
設成1或其他數字,會將剩餘的空間進行比例分配給彈性項目。
1. flex-grow:1
1 : 1 : 1

2. flex-grow:1 /flex-grow:2 /flex-grow:1
1 : 2 : 1

已知條件
彈性項目 margin total => 10 * 6 = 60px
彈性項目 width total => 100 + 100 + 100 = 300px
彈性容器 width = 1200px
剩餘空間 1200 - 300 - 60 = 840px
剩餘空間進行分配,各彈性項目伸展係數設成 1 ,每個彈性項目分配1/3剩餘空間。
每個項目可獲得 280px(840 * 1/3 = 280px)
最終每個彈性項目寬度+剩餘空間比例分配=> 100+280=380px
當flex-grow 1,2,3 計算彈性項目的寬度?
得知每個比例分配
840*1/6=140
840*2/6=280
840*3/6=420
100+140=240
100+280=380
100+420=520
### flex-shrink 彈性收縮係數
預設值為 `flex-shrink : 1 `
彈性項目的收縮係數,==預設 1== ,發生彈性項目總寬度超過彈性容器寬度,
==會限縮超出空間,防止爆版。==
flex-shrink:0 ,若彈性項目總寬度大於彈性容器寬度時,會爆版。
```css=
.w3 {
width: 500px;
}
.flex-shrink {
flex-shrink: 1;
}
```
```html=
<div class="row d-flex">
<div class="col flex-shrink w3">彈性項目 01</div>
<div class="col flex-shrink w3">彈性項目 02</div>
<div class="col flex-shrink w3">彈性項目 03</div>
</div>
```

若 flex-shrink: 0 (沒有彈性收縮係數,會爆版)

計算 flex-shrink
預設 1 發生彈性項目總寬度超過彈性容器寬度,會限縮超出空間。防止爆版。
已知條件
彈性項目 margin total => 10 * 6 = 60px
彈性項目 width total => 500 + 500 + 500 = 1500px
彈性項目總寬度 1500+60=1560px
彈性容器1200px
1560px < 1200px => 爆版
但因為 flex-shrink 預設為 1 ,不會爆版,限縮超出空間360px
計算收縮後的實際寬度
520 - (360*1/3) = 400
520 - (360*1/3) = 400
520 - (360*1/3) = 400
400+400+400=1200
### flex-basis 彈性尺寸
flex-basis 是指 row 或 column 排列時,彈性項目的基準尺寸
```css=
.flex-basis {
width: 300px;
flex-basis: auto;
}
```
```html=
<div class="row d-flex flex-direction">
<div class="col flex-basis">彈性項目 01</div>
<div class="col flex-basis">彈性項目 02</div>
<div class="col flex-basis">彈性項目 03</div>
</div>
```

:::danger
當 flex-direction : row,
flex-basis優先權 > width
但 高度(heigh) 不會被影響
當 flex-direction : column,
flex-basis優先權 > heigh
但 寬度(width) 不會被影響
:::
```css=
.flex-basis {
width: 100px;
flex-basis: 300px;
}
```

```css=
.flex-basis {
width: 10000000px;
flex-basis: 0%;
}
```

flex-basis 掌控了彈性尺寸設定,以尺寸來稱呼它,而不能用寬度、高度來看它。
這是因為它會根據 flex-direction 的row 或 column 的設定,調整的寬、高也會不同
情況一:
當彈性項目flex-basis:auto(預設)。無論水平或垂直排列,wdith height 都可以被作為flex-basis 的依據
情況二:
當彈性項目flex-basis: 設定為非auto 例如0、100px、25%...,flex-basis擁有絕對優先權,會以它的設定值為主
此時在flex-direction:row => width 無效化,會以flex-basis 優先, height 仍是有效
此時在flex-direction:column => height 無效化,會以flex-basis 優先, width 仍是有效
### flex 三合一屬性,一次設定grow、shrink、basis
1. flex 屬性值為數字時
==雖然是縮寫,要知道它省略的是什麼==
flex:0 =>flex: 0 1 0% 無伸展
flex:1 =>flex: 1 1 0% 以伸展係數 flex-grow 1 為基準.
該數值是指定彈性項目的 flex-grow 伸展係數
flex:1

flex:0

2. flex 設定文字時
值為文字時,flex-basis 為 auto ,可以設定尺寸。
flex:initial => flex: 0 1 auto
flex:auto => flex: 1 1 auto
flex:none => flex: 0 0 auto
/
flex:0 flex:auto =>不一樣
flex:0 => flex:0 1 0%
flex:none=> 0 0 auto
flex:auto

flex:initial

flex:none

### flex:1 與 flex:auto 的差異
#### flex:1 => flex: 1 1 0%
==真正的等寬或等高== ,flex-basis 0% 無法設定長度,flex-grow:1 會將剩餘空間平均分配給彈性項目。


#### flex:auto => flex: 1 1 aut
flex-basis :auto 可以設定內容長度,==會受長度設定或文字內容影響==。


### order 彈性項目順序
order 可以調整彈性項目之間的 order-排列順序,數值越大排在越後面。
```css=
.order-1 {
order: 6;
}
.order-2 {
order: 2;
}
.order-3 {
order: 3;
}
.order-4 {
order: 4;
}
.order-5 {
order: 5;
}
.order-6 {
order: 1;
}
.order-first {
order: -1;
}
.order-last {
order: 7;
}
```
```html=
<div class="row d-flex">
<div class="col order-1">彈性項目 01</div>
<div class="col order-2 order-last">彈性項目 02</div>
<div class="col order-3">彈性項目 03</div>
<div class="col order-4">彈性項目 04</div>
<div class="col order-5 order-first">彈性項目 05</div>
<div class="col order-6">彈性項目 06</div>
</div>
```

### 彈性項目與margin的關係
margin-xxxx auto,可以將剩餘的空間分配給彈性項目的magin ,做到推擠的效果
```html
<div class="row d-flex" style="justify-content: space-between;">
<div class="col">logo</div>
<div class="col">彈性項目 02</div>
<div class="col" style="margin-right:auto ; margin-left:auto;">彈性項目 03</div>
<div class="col">彈性項目 04</div>
<div class="col">彈性項目 05</div>
</div>
```

### 彈性項目與position的關係
```html
<div class="row d-flex" style="justify-content: space-around;position: relative;">
<div class="col">彈性項目 01</div>
<div class="col">彈性項目 02</div>
<div class="col" style="position:absolute ; left:50% ; top:50%; transform: translate(-50%,-50%);">彈性項目 03</div>
<div class="col">彈性項目 04</div>
<div class="col">彈性項目 05</div>
</div>
```

## align-content
1. 設定在彈性容器的屬性
2. flex-wrap 必須是 wrap(換行)
```css=
.row2 {
width: 1200px;
height: 600px;
background: #000;
display: flex;
flex-wrap: wrap;
justify-content: center;/*主軸對齊*/
align-content: center;/*次軸對齊*/
}
.col2 {
margin: 10px;
background: red;
color: white;
}
.col2 img {
width: 100%;
height: 100%;
}
```
```html=
<div class="row2">
<div class="col2">1<img src="https://picsum.photos/300/200/?random=1"> </div>
<div class="col2">2<img src="https://picsum.photos/300/200/?random=2"> </div>
<div class="col2">3<img src="https://picsum.photos/300/200/?random=3"> </div>
<div class="col2">4<img src="https://picsum.photos/300/200/?random=4"> </div>
<div class="col2">5<img src="https://picsum.photos/300/200/?random=5"> </div>
<div class="col2">6<img src="https://picsum.photos/300/200/?random=6"> </div>
</div>
```
