徹底理解Flexbox

注:本文翻譯自CHRIS COYIER的A Complete Guide to Flexbox這篇文章,點擊鏈接可前往原版博文:https://css-tricks.com/snippets/css/a-guide-to-flexbox/
Tips: This tutorial is translated from the most popular article in CSS-Tricks - A Complete Guide to Flexbox, posted by CHRIS COYIER. Follow this link to see the original: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
Flexbox佈局旨在提供一種更有效的途徑,來爲容器內子元素進行佈局、對齊和分配空間,即便它們的大小是未指定或動態變化的,也能夠很好的適應。
Flexbox佈局背後的原理是,賦予父容器更改子元素寬高(或順序)的能力,來更好的填充可用的空間(主要使其適應各種顯示設備和屏幕尺寸)。一個使用Flexbox佈局的父容器會伸展每個子元素來填充可用的空間,或者壓縮它們來阻止超出父容器。
最重要的是,Flexbox佈局在方向上是不可預知的,這一點和常歸佈局不同(常規佈局中塊是基於豎直方向排列的,而內聯是基於水平方向)。這些常規佈局在頁面中顯示都沒問題,但它們缺乏靈活性,難以支撐大型複雜應用的需求,特別是響應方向、大小、伸展、收縮等這些變化。
注意:Flexbox最適合用在組件和小規模的佈局中,如果是更復雜的佈局,Grid佈局會比較好一些。
由於Flexbox是一個完整的模塊,它不單單是一個屬性,而是包含了一整套新的屬性集,所以這裏面涉及到了很多新東西。這些屬性中一些是用來設置父容器的,而另外一些是設置子元素的。
設置父容器的屬性有:

display: flex | inline-flex;
flex-direction: row | row-reverse | column | column-reverse;
flex-wrap: nowrap | wrap | wrap-reverse;
flex-flow: @flex-direction @flex-wrap;
justify-content: flex-start | flex-end | center | space-between | space-around;
align-items: flex-start | flex-end | center | baseline | strtch;
align-content: flex-start | flex-end | center | space-between | space-around | stretch;

設置子元素的屬性有:

order: number;
flex-grow: number; /* default 0 */
flex-shrink: number; /* default 1 */
flex-basis: number | auto; /* default auto */
flex: none | @flex-grow @flex-shrink @flex-basis;
align-self: auto | flex-start | flex-end | center | baseline | stretch;

上面是屬性的概括,接下來我們就一一介紹它們:

display

display屬性用來定義一個flex佈局的容器,容器本身是inline還是block,這取決於display的值是flex還是inline-flex。一旦聲明瞭flex,容器下面的直接子元素就得接受flex佈局的管理。
需要注意的是,CSS中的多列布局不會影響flex佈局的容器。
下面我們定義一個父容器和幾個子元素,分別爲父容器聲明flex和inline-flex的樣式:

.parent {
    background: #88499C;
}

.child {
    margin: 10px;
    padding: 10px;
    background: #E77F24;
    text-align: center;
    color: white;
    overflow: hidden;
}

.parent.flex {
    display: flex;
}

.parent.inline-flex {
    display: inline-flex;
}

下面是HTML內容:

<h3>父容器設置了display:flex</h3>
<div class="parent flex">
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
</div>
<span style="background:wheat">我是個span元素</span>

<h3>父容器設置了display:inline-flex</h3>
<div class="parent inline-flex">
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
</div>
<span style="background:wheat">我是個span元素</span>

上面的代碼中,第一個父容器使用了flex樣式,第二個使用了inline-flex樣式,現在我們來看看flex和inline-flex有什麼不同吧:

使用flex時父元素是block元素,而聲明瞭inline-flex的父元素變成了inline元素。

flex-direction

flex-direction屬性用於創建一個主軸,這個主軸規定了排列子元素的方向。Flexbox是單向排列的佈局概念,除非我們額外使用了flex-wrap屬性。Flexbox內部的子元素主要在水平方向排成一行或是在垂直方向排成一列。
一般常用的是flex-direction: row和flex-direction: column,而row-reverse和column-reverse從字面可以看出,是和前兩個方向上是相反的。
默認情況下,是從左到右排成一行,也就是flex-direction: row。
現在我們再爲父容器聲明一個flex-direction的樣式:

.parent.flex-direction-column {
    flex-direction: column; /* row | row-reverse | column | column-reverse */
}
<h3>父容器添加了flex-direction: column</h3>
<div class="parent flex flex-direction-column">
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
</div>

排列效果如下:

flex-wrap

上面我們也提到了,默認情況下,Flexbox會在一個方向上自適應地排列子元素,但是我們也可以聲明flex-wrap改變這個規定,允許一些子元素排列到下一行。
默認情況下,flex-wrap屬性的值是nowrap,我們可以聲明wrap和wrap-reverse來改變它。需要注意的是wrap和wrap-reverse的方向是跟flex-direction關聯的,使用時需靈活運用。
現在我們再添加CSS樣式然後在HTML中使用:

.parent.flex-wrap {
    flex-wrap: wrap; /* nowrap | wrap | wrap-reverse */
}
<h3>父容器未指定flex-wrap,使用默認值nowrap</h3>
<div class="parent flex">
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
</div>

<h3>父容器指定了flex-wrap: wrap</h3>
<div class="parent flex flex-wrap">
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
</div>

<h3>父容器添加了flex-direction: row-reverse</h3>
<div class="parent flex flex-wrap" style="flex-direction: row-reverse">
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
</div>

顯示效果如下圖所示:

可以看出,默認情況下,容器會壓縮子元素使其保持在一行,如果添加了flex-wrap: wrap,並不會強制子元素在同一行內,而是從下一行開始排列。

flex-flow

flex-flow屬性是flex-direction和flex-wrap的簡寫方式,例如上面的flex-direction: row和flex-wrap同時聲明時我們可以用只用一個屬性表示:flex-flow: row wrap;

講了這麼多父容器的屬性,也該結合父容器介紹一下子元素的屬性了。

order

默認情況下,Flexbox內的子元素會按照文檔聲明順序排列,不過我們可以使用order屬性控制子元素出現在父容器的順序。默認情況下,order值爲0。
下面我們定義了子元素的兩個order值,然後在HTML中應用:

.child.order-negative-1 {
    order: -1;
}

.child.order-positive-1 {
    order: 1; 
}
<h3>子元素設置了order,order值越小越靠前,默認值爲0</h3>
<div class="parent flex">
    <div class="child order-positive-1">order: 1</div>
    <div class="child">default</div>
    <div class="child order-negative-1">order: -1</div>
</div>

第一個子元素的order爲1,最後一個子元素order爲-1,所以理論上來講,最後一個子元素和最後一個子元素應該會調換一下位置,而第二個子元素使用了默認值0,所以會排在中間位置。
下面這張圖證實了我們的推斷:

flex-grow

flex-grow屬性賦予子元素在必要時伸展的能力,可指定一個不帶單位的數值,作爲父容器剩餘空間的比例,它表示子元素在flex容器中可以分配多少可用的空間。
如果所有聲明瞭flex-grow的子元素都指定flex-grow爲1,那麼父容器剩餘的空間將會平均的分配到這些子元素上。如果其中一個flex-grow指定爲2,那麼容器將會試圖爲其分配一個空間,這個空間2倍於那些flex-grow爲1的子元素。
需要注意的是,我們說的剩餘空間,是指除子元素內容以外的父容器可用空間,另外,父容器並不保證所有情況下都能均勻分配,但至少它會這樣嘗試。flex-grow的值不能爲負。
現在我們來爲子元素聲明flex-grow屬性並應用到HTML文檔中:

.child.flex-grow-1 {
    flex-grow: 1;
}

.child.flex-grow-2 {
    flex-grow: 2;
}
<h3>設置了flex-grow: 1的子元素,會平均分配剩餘空間</h3>
<div class="parent flex">
    <div class="child">default</div>
    <div class="child flex-grow-1">flex-grow: 1</div>
    <div class="child flex-grow-1">flex-grow: 1</div>
</div>

<h3>多個指定flex-grow的子元素會按比例劃分剩餘空間</h3>
<div class="parent flex">
    <div class="child">default</div>
    <div class="child flex-grow-1">flex-grow: 1</div>
    <div class="child flex-grow-2">flex-grow: 2</div>
</div>

<h3>理解剩餘空間 & 父容器如何分配剩餘空間</h3>
<div class="parent flex">
    <div class="child flex-grow-1">flex-grow: 1</div>
    <div class="child flex-grow-1">flex-grow: 1, but very loooooooong</div>
    <div class="child flex-grow-1">flex-grow: 1</div>
</div>

現在看一下flex-grow是如何分配空間的:

從圖中第三個例子可以看出,容器只是對文本以外的可用空間進行平均分配,所以每個子元素的”padding”都是1比1的,但是對於子元素整體來講,並非都是1比1的。
那麼如何確保如何使子元素整體大小按照比例劃分父容器空間呢,這裏我們就需要使用flex-basis: 0這個屬性了,稍後會介紹到。

flex-shrink

flex-shrink屬性表示一個子元素在必要時是否收縮自己來適應當前的Flexbox,默認值是1。注意:flex-shrink不能爲負值。
flex-shrink適合使用在固定尺寸的子元素上,默認情況下,固定大小的子元素並非始終保持設定的值,比如在父容器太小時,就會壓縮子元素來適應,如果我們不想這些子元素被壓縮,就可以使用flex-shrink,並設置其值爲0。
我們先設置最後一個子元素的寬度爲300px,然後爲其添加flex-shrink: 0的樣式,看看flex-shrink是怎麼控制子元素的:

.child.flex-shrink-0 {
    flex-shrink: 0;
}
<h3>未設置flex-shrink的子元素,即使是固定寬度也會被強制壓縮</h3>
<div class="parent flex">
    <div class="child">default</div>
    <div class="child flex-grow-1">flex-grow: 1</div>
    <div class="child" style="width: 300px;">width: 300px</div>
</div>

<h3>設置了flex-shrink: 0的子元素,會保持其設定寬度不會收縮</h3>
<div class="parent flex">
    <div class="child">default</div>
    <div class="child flex-grow-1">flex-grow: 1</div>
    <div class="child flex-shrink-0" style="width: 300px;">flex-shrink: 0</div>
</div>

現在來看看添加flex-shrink前後的區別:

需要注意的是,上面的第一個視圖中,最後的子元素當前的寬度已不是300px了,因爲父容器寬度太小,強制壓縮每個子元素的寬度,所以雖然最後一個子元素設定了寬度,但也受到了影響。而第二個視圖中,最後一個子元素依舊保持它的寬度,未被壓縮,因爲它聲明瞭flex-shrink: 0。

flex-basis

flex-basis屬性告訴父容器,在剩餘空間被分配之前先定義子元素的默認尺寸,可以指定爲百分比或rem等長度單位或者auto關鍵字。如果設置爲0,那麼父容器分配分配之前,對每個子元素的默認尺寸都視之爲0,剩餘空間也就是父容器的全部空間,其結果是,直接按照flex-grow值的比例分配子元素整體的大小;如果設置爲auto,那麼父容器會將每個子元素中的內容作爲子元素默認尺寸,然後再計算剩餘空間,最後把剩餘空間按照flex-grow值的比例平均分配到子元素除內容以外的空間,也就是”padding”。我們來看下面這張圖(圖片來源:https://www.w3.org/TR/css-flexbox-1/images/rel-vs-abs-flex.svg):

圖中第一個視圖子元素聲明瞭flex-basis: 0,所以父容器會按照flex-grow值的比例,爲每個子元素的整體分配空間。而第二個視圖就不同了,子元素聲明瞭flex-basis: auto,所以父容器會先把每個子元素的內容空間分配出去,然後對於除內容以外的剩餘空間,再按照每個子元素flex-grow的比例進行分配。
上面介紹flex-grow時提到,如何利用flex-basis: 0將父容器的全部空間按比例分配到每個子元素上,下面我們就來爲每個子元素添加flex-basis: 0屬性:

.child.flex-grow-1 {
    flex-grow: 1;
}

.child.flex-basis-0 {
    flex-basis: 0;
}
<h3>理解剩餘空間 & 父容器如何分配剩餘空間</h3>
<div class="parent flex">
    <div class="child flex-grow-1">flex-grow: 1</div>
    <div class="child flex-grow-1">flex-grow: 1, but very loooooooong</div>
    <div class="child flex-grow-1">flex-grow: 1</div>
</div>

<h3>理解剩餘空間 & 父容器如何分配剩餘空間,添加完flex-basis: 0之後</h3>
<div class="parent flex">
    <div class="child flex-grow-1 flex-basis-0">flex-grow: 1</div>
    <div class="child flex-grow-1 flex-basis-0">flex-grow: 1, but very loooooooong</div>
    <div class="child flex-grow-1 flex-basis-0">flex-grow: 1</div>
</div>

看看前後的對比如何:

flex-basis默認值爲auto,當子元素只聲明flex-grow時,它會使用flex-basis: auto。
當然上面我們也提到,可以使用百分比或rem等長度單位明確告訴父容器,在剩餘空間分配之前,我默認就應該佔用多少比例,下面我們爲其中一個子元素添加指定的flex-basis:

.child.flex-basis-50-percent {
    flex-basis: 50%;
}
<h3>爲子元素設置flex-basis指定最基本的空間</h3>
<div class="parent flex">
    <div class="child flex-basis-50-percent">flex-basis: 50%</div>
    <div class="child flex-grow-1">flex-grow: 1</div>
    <div class="child flex-grow-1">flex-grow: 1</div>
</div>

顯示效果如下:

flex

flex屬性是flex-grow, flex-shrink, flex-basis的簡寫方式,其中flex-shrink和flex-basis是可選的。默認情況下,flex的值是0 1 auto

在Flexbox中,對齊也是一個非常重要的概念,它也涉及到很多屬性,下面我們來介紹一下父容器的幾個關於對齊的屬性:

justify-content

justify-content屬性定義了父容器沿主軸方向的對其方式。需要注意這裏的主軸方向,如果flex-direction爲row,則主軸方向就是水平方向從左到右,如果爲column,則主軸方向就是豎直方向從上到下,如果爲row-reverse或column-reverse,大家也可以推斷。
當Flexbox中的子元素都是大小固定的,或者其中可伸縮的子元素已經達到最大尺寸時,justify-content可以對剩餘的可用空間進行分配,在超出行內的子元素對齊方式上,它也會加以控制。
justify-content主要有以下幾個值:
flex-start: 從主軸起始位置開始,緊湊型排列
flex-end: 從主軸末端位置開始,緊湊型排列
center: 居中排列在主軸線上
space-between: 子元素均勻分佈在主軸線上,第一個子元素從起始位置開始,最後一個子元素從末端開始
space-around: 子元素均勻分佈在主軸線上,並且每個子元素都會均勻的被周圍的空間包裹着
我們現在爲父容器添加不同的屬性值,看看它們是怎麼影響Flexbox內的子元素的:

.parent.justify-content-flex-start {
    justify-content: flex-start;
}

.parent.justify-content-flex-end {
    justify-content: flex-end;
}

.parent.justify-content-center {
    justify-content: center;
}

.parent.justify-content-space-between {
    justify-content: space-between;
}

.parent.justify-content-space-around {
    justify-content: space-around;
}

.child.width-100 {
    width: 100px;
}

.child.width-150 {
    width: 150px;
}

.child.width-200 {
    width: 200px;
}
<h3>父容器設置了justify-content: flex-start</h3>
<div class="parent flex justify-content-flex-start">
    <div class="child width-150">width: 150px</div>
    <div class="child width-100">width: 100px</div>
    <div class="child width-200">width: 200px</div>
</div>

<h3>父容器設置了justify-content: flex-end</h3>
<div class="parent flex justify-content-flex-end">
    <div class="child width-150">width: 150px</div>
    <div class="child width-100">width: 100px</div>
    <div class="child width-200">width: 200px</div>
</div>

<h3>父容器設置了justify-content: center</h3>
<div class="parent flex justify-content-center">
    <div class="child width-150">width: 150px</div>
    <div class="child width-100">width: 100px</div>
    <div class="child width-200">width: 200px</div>
</div>

<h3>父容器設置了justify-content: space-between</h3>
<div class="parent flex justify-content-space-between">
    <div class="child width-150">width: 150px</div>
    <div class="child width-100">width: 100px</div>
    <div class="child width-200">width: 200px</div>
</div>

<h3>父容器設置了justify-content: space-around</h3>
<div class="parent flex justify-content-space-around">
    <div class="child width-150">width: 150px</div>
    <div class="child width-100">width: 100px</div>
    <div class="child width-200">width: 200px</div>
</div>

效果如圖所示:

align-items

與justify-content不同,align-items是在主軸的垂直方向進行對齊。所以如果我們使用flex-direction: row時,align-items會在豎直方向對元素加以控制,讓其以某種方式對齊。
align-items和justify-content相似,都有flex-startflex-endcenter這幾種對齊方式,不同的是,align-items有自己的stretchbaseline
stretch表示父容器會儘可能在主軸的垂直方向上拉伸子元素,來填滿容器垂直空間,但也要注意,它也會考慮子元素本身設定的寬度或高度等因素。
baseline表示子元素會以它們的基線爲準對齊。
下面我們也照例添加一些CSS樣式,看看幾種不同對齊方式之間的差異:

.parent.height-150 {
    height: 150px;
}

.parent.align-items-flex-start {
    align-items: flex-start;
}

.parent.align-items-flex-end {
    align-items: flex-end;
}

.parent.align-items-center {
    align-items: center;
}

.parent.align-items-stretch {
    align-items: stretch;
}

.parent.align-items-baseline {
    align-items: baseline;
}

.child.height-30 {
    height: 30px;
}

.child.height-50 {
    height: 50px;
}

.child.font-size-big {
    font-size: 20px;
}
<h3>父容器設置了align-items: flex-start</h3>
<div class="parent flex align-items-flex-start height-150">
    <div class="child height-30">height: 30px</div>
    <div class="child">child</div>
    <div class="child height-50">height: 50px</div>
</div>

<h3>父容器設置了align-items: flex-end</h3>
<div class="parent flex align-items-flex-end height-150">
    <div class="child height-30">height: 30px</div>
    <div class="child">child</div>
    <div class="child height-50">height: 50px</div>
</div>

<h3>父容器設置了align-items: center</h3>
<div class="parent flex align-items-center height-150">
    <div class="child height-30">height: 30px</div>
    <div class="child">child</div>
    <div class="child height-50">height: 50px</div>
</div>

<h3>父容器設置了align-items: stretch,但對於設定了固定值的子元素無效</h3>
<div class="parent flex align-items-stretch height-150">
    <div class="child height-30">height: 30px</div>
    <div class="child">child</div>
    <div class="child height-50">height: 50px</div>
</div>

<h3>父容器設置了align-items: baseline</h3>
<div class="parent flex align-items-baseline height-150">
    <div class="child height-30">height: 30px</div>
    <div class="child">child</div>
    <div class="child height-50">height: 50px</div>
</div>

效果如下圖所示:

align-content

align-content主要用來對父容器內多個行在垂直方向上進行排列。該屬性只針對父容器內多行的情況,如果父容器內只有一行子元素,則此屬性無效。
align-content也有幾個不同的值:flex-startflex-endcenterstretchspace-betweenspace-around。現在我們也來應用不同的值,看看他們的樣式:

.parent.height-200 {
    height: 200px;
}

.parent.align-content-flex-start {
    align-content: flex-start;
}

.parent.align-content-flex-end {
    align-content: flex-end;
}

.parent.align-content-center {
    align-content: center;
}

.parent.align-content-stretch {
    align-content: stretch;
}

.parent.align-content-space-between {
    align-content: space-between;
}

.parent.align-content-space-around {
    align-content: space-around;
}
<h3>父容器設置了align-content: flex-start</h3>
<div class="parent flex flex-wrap align-content-flex-start height-200">
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
</div>

<h3>父容器設置了align-content: flex-end</h3>
<div class="parent flex flex-wrap align-content-flex-end height-200">
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
</div>

<h3>父容器設置了align-content: center</h3>
<div class="parent flex flex-wrap align-content-center height-200">
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
</div>

<h3>父容器設置了align-content: stretch</h3>
<div class="parent flex flex-wrap align-content-stretch height-200">
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
</div>

<h3>父容器設置了align-content: space-between</h3>
<div class="parent flex flex-wrap align-content-space-between height-200">
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
</div>

<h3>父容器設置了align-content: space-around</h3>
<div class="parent flex flex-wrap align-content-space-around height-200">
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
</div>

<h3>align-content屬性對單行無效</h3>
<div class="parent flex flex-wrap align-content-flex-start height-200">
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
    <div class="child">child</div>
</div>

再來看看幾種不同的排列效果:


以上幾個就是父容器控制子元素對齊方式的屬性,在flex佈局中,子元素也有一個控制對齊的屬性,那就是align-self。

align-self

align-self用來爲子元素自身聲明對齊方式,如果子元素聲明瞭此屬性,它會覆蓋父容器施加在子元素上的對齊規則。我們可以爲align-self屬性指定下面這幾個值:flex-startflex-endcenterstretchbaseline,這與父容器的align-items一致。align-self默認值爲auto。
我們在前面align-items的例子上,爲第一個子元素添加一個與父容器不同的樣式:

.align-self-flex-end {
    align-self: flex-end;
}
<h3>父容器設置了align-items: flex-start,但第一個子元素設置了align-self: flex-end</h3>
<div class="parent flex align-items-flex-start height-150">
    <div class="child height-30 align-self-flex-end">height: 30px</div>
    <div class="child">child</div>
    <div class="child height-50">height: 50px</div>
</div>

然後我們來看看它會有什麼變化:

從圖中可以看到,子元素並不再按照父元素的對齊方式放置自己了,它覆蓋了原有的規則。

需要注意的是,在使用flex佈局時,float,clear,和vertical-align屬性都會對容器內的子元素失去作用。

寫在最後:掌握Flexbox的每個細節並不是件輕鬆的事,博主也是從懵懵懂懂走過來的,CHRIS COYIER的這篇指導教程對初學者幫助很大,所以搜索排行榜第一也是理所當然的,翻譯這篇文章更是進一步加深了博主對Flexbox細節的理解和把握,而對於原文沒有闡述清楚的地方,我在這裏都儘可能的把它們呈現出來,幫助大家理解,最後,希望大家都能夠掌握並靈活運用Flexbox,謝謝。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章