# flex

[CSS](https://lochiwei.gitbook.io/web/css) ⟩ [layout](https://lochiwei.gitbook.io/web/css/layout) ⟩ [display](https://lochiwei.gitbook.io/web/css/layout/display) ⟩ flex&#x20;

{% hint style="success" %}
任何元素設定 <mark style="color:blue;">`display: flex`</mark> 就會變成 *<mark style="color:purple;">flexbox</mark>* (*<mark style="color:purple;">flex container</mark>*)，而其內部的<mark style="color:orange;">子元素</mark>會變成 <mark style="color:orange;">flex items</mark>。*<mark style="color:purple;">Flexbox</mark>* 是一種<mark style="color:yellow;">佈局模式</mark>，可以設定容器內元素的<mark style="color:yellow;">排版</mark>、<mark style="color:yellow;">對齊</mark>、<mark style="color:yellow;">空間分配</mark>等方式。
{% endhint %}

{% tabs %}
{% tab title="🗺️ 圖表" %}
{% embed url="<https://codepen.io/lochiwei/pen/bNbgKgd>" %}
{% endtab %}

{% tab title="排版對齊" %}
{% hint style="info" %}
設定 *<mark style="color:purple;">flexbox</mark>* 容器內元素排版的<mark style="color:yellow;">主軸</mark>、<mark style="color:yellow;">副軸</mark>與<mark style="color:yellow;">對齊方式</mark>。
{% endhint %}

{% tabs %}
{% tab title="設定主軸" %} <mark style="color:blue;">`flex-direction`</mark>：設定<mark style="color:orange;">主軸</mark><mark style="color:yellow;">方向</mark>，

* <mark style="color:blue;">`row`</mark>：設定<mark style="color:yellow;">水平</mark>為主軸方向 。
* <mark style="color:blue;">`column`</mark>：設定<mark style="color:yellow;">垂直</mark>為主軸方向 。

```css
/* flex container */
.flexbox {
    display: flex;			/*    設定為 Flex 容器   */
    flex-direction: row; 		/* ⭐ 設定主軸：水平(預設) */
    justify-content: space-around; 	/*    主軸對齊方式：分散   */
    align-items: center; 		/*    副軸對齊方式：居中   */
}
```

{% endtab %}

{% tab title="主軸對齊方式" %} <mark style="color:blue;">`justify-content`</mark>：設定<mark style="color:orange;">主軸</mark>的<mark style="color:yellow;">對齊方式</mark>。

* <mark style="color:blue;">`flex-start`</mark>, <mark style="color:blue;">`center`</mark>, <mark style="color:blue;">`flex-end`</mark>, <mark style="color:blue;">`space-between`</mark>, <mark style="color:blue;">`space-around`</mark>, <mark style="color:blue;">`space-evenly`</mark>.&#x20;

```css
/* flex container */
.flexbox {
    display: flex;			/*    設定為 Flex 容器   */
    flex-direction: row; 		/*    設定主軸：水平(預設) */
    justify-content: space-around; 	/* ⭐ 主軸對齊方式：分散   */
    align-items: center; 		/*    副軸對齊方式：居中   */
}
```

{% endtab %}

{% tab title="副軸對齊方式" %} <mark style="color:blue;">`align-items`</mark>：設定<mark style="color:orange;">副軸</mark>的<mark style="color:yellow;">對齊方式</mark>。

* <mark style="color:blue;">`stretch`</mark>：讓<mark style="color:orange;">子元素</mark><mark style="color:yellow;">撐滿</mark><mark style="color:orange;">副軸</mark><mark style="color:yellow;">方向的空間</mark> (<mark style="color:yellow;">預設值</mark>)。
* <mark style="color:blue;">`flex-start`</mark>：對齊<mark style="color:orange;">副軸</mark>的<mark style="color:yellow;">起始</mark>位置。
* <mark style="color:blue;">`flex-end`</mark>：對齊<mark style="color:orange;">副軸</mark>的<mark style="color:yellow;">結束</mark>位置。
* <mark style="color:blue;">`center`</mark>：在<mark style="color:orange;">副軸</mark>上<mark style="color:yellow;">居中對齊</mark>。
* <mark style="color:blue;">`baseline`</mark>：對齊<mark style="color:yellow;">文字基線</mark>。

```css
/* flex container */
.flexbox {
    display: flex;			/*    設定為 Flex 容器   */
    flex-direction: row; 		/*    設定主軸：水平(預設) */
    justify-content: space-around; 	/*    主軸對齊方式：分散   */
    align-items: center; 		/* ⭐ 副軸對齊方式：居中   */
}
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="空間分配" %}
{% hint style="info" %}
設定 *<mark style="color:purple;">flexbox</mark>* 容器內的<mark style="color:yellow;">空間分配</mark>問題：

* 有<mark style="color:yellow;">多餘空間</mark>時，子元素該<mark style="color:yellow;">如何擴張</mark>(或不擴張)。
* <mark style="color:yellow;">空間不足</mark>時，子元素該<mark style="color:yellow;">如何壓縮</mark>(或不壓縮)。
  {% endhint %}

{% tabs %}
{% tab title="擴展" %}

* <mark style="color:blue;">`flex-grow`</mark>：🚧

```css
/* CSS */
```

{% endtab %}

{% tab title="壓縮" %}

* <mark style="color:blue;">`flex-shrink`</mark>：🚧

```css
/* CSS */
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="子元素行為" %} <mark style="color:orange;">Flex items</mark> 有以下的屬性可以設定：

* <mark style="color:blue;">`flex`</mark>：設定子元素可否擴展、壓縮，自己的尺寸該如何決定等。
* <mark style="color:blue;">`flex-basis`</mark>：用來定義<mark style="color:orange;">子元素</mark>的<mark style="color:yellow;">初始尺寸</mark>。

{% tabs %}
{% tab title="擴展性" %}

* <mark style="color:blue;">`flex-grow`</mark>：🚧

```css
/* CSS */
```

{% endtab %}

{% tab title="壓縮性" %}

* <mark style="color:blue;">`flex-shrink`</mark>：🚧

```css
/* CSS */
```

{% endtab %}

{% tab title="初始尺寸" %}

{% endtab %}
{% endtabs %}
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="💾 程式" %}
📁 index.html

```html
<!-- flexbox -->
<div class="flexbox">
    <!--     flex items     -->
    <div class="item red">A</div>
    <div class="item green">B<br>B</div>
    <div class="item blue">C<br>C<br>C</div>
</div>
```

📁 styles.css

```css
/* flexbox */
.flexbox {
    display: flex;			/* ⭐️ 設定為 Flex 容器   */
    flex-direction: row; 		/*    設定主軸：水平(預設) */
    justify-content: space-around; 	/*    設定主軸對齊：分散   */
    align-items: center; 		/*    設定副軸對齊：居中   */
}

/* flex items */
.item {
    /* ⭐️ flex: grow shrink basis (shortcut)  */
    /*    0 = 不, 1 = 可            */
    flex: 0 0 auto;         /* 不擴展、不壓縮、尺寸依內容或設定 */
    flex: 0 1 auto;         /* 不擴展、可壓縮、尺寸依內容或設定 */
    flex: 1 0 auto;         /* 可擴展、不壓縮、尺寸依內容或設定 */
    flex: 1 1 auto;         /* 可擴展、可壓縮、尺寸依內容或設定 */
    
    /* ⭐️ flex-basis */
    flex-basis: auto;    /* 由內容或 CSS 決定尺寸 */
}

/* 以下為 flex items 的不同設定方式 */

.item {
    flex-basis: auto; 
    width: 100px;        /* ⭐️ 結果：初始尺寸為 100px，即使內容大小不同❗️ */
}

.item {
    flex-basis: 150px;   /* 初始尺寸固定為 150px */
}

.item {
    flex-basis: content; /* ⭐️ 根據內容決定，不參考 width/height❗️ */
}

.item {
    /* ⭐️ 初始尺寸設為 0，子元素完全依賴 flex-grow 來分配剩餘空間 */
    flex-basis: 0;     /* 初始尺寸設為 0  */
    flex-grow: 1;      /* 平均分配剩餘空間 */
}
```

{% endtab %}

{% tab title="📗 參考" %}

* Every Layout (2021)
* ChatGPT ⟩ [學習 CSS 排版](https://chatgpt.com/share/67615fd5-26cc-800e-b740-63aa8d06b4c4)
  {% endtab %}

{% tab title="👥 相關" %}

* 可用 [less-than-select-greater-than](https://lochiwei.gitbook.io/web/html/element/less-than-select-greater-than "mention") 來動態選擇 *<mark style="color:purple;">flexbox</mark>* 的排版方式。
  {% endtab %}

{% tab title="💈範例" %}

<table><thead><tr><th width="280">範例</th><th>說明</th></tr></thead><tbody><tr><td><a href="https://codepen.io/pegasusroe/pen/qEWrNwd">flexbox (0.0.2)</a></td><td>主軸：<mark style="color:blue;"><code>space-around</code></mark>, 副軸：<mark style="color:blue;"><code>center</code></mark></td></tr><tr><td><a href="https://codepen.io/pegasusroe/pen/JoPWbbp">flexbox (0.0.3)</a> <span data-gb-custom-inline data-tag="emoji" data-code="2b50">⭐</span></td><td>用<a href="../../../html/element/less-than-select-greater-than">下拉式選單</a>選擇 <em><mark style="color:purple;">flexbox</mark></em> 的排版方式</td></tr></tbody></table>
{% endtab %}
{% endtabs %}
