入門篇
排版目標
Flexbox與Grid的基本概念與使用時機
基本概念
我們都知道,Flexbox用於一維排版,Grid用於二維排版。
一維:Row or Column
二維:Row and Column
什麼是Row 跟Column?(已知可跳過)
使用時機
Grid可以讓我們非常客製化的排出我們想要的版面。
應用時機:二維排版時使用(如下圖),當你已經有明確的設計稿,需要將畫面分成一塊一塊,把所需的內容對照放進去。
flexbox的使用時機:針對一維的內容來排版(如下圖,只有一個row)
Flexbox for content and Grid for layout
實務案例-Youtube
在實務上,Flexbox常常會跟Grid一起搭配使用,在一維的地方用Flex、內容排版上也用Flex。
而在二維有行有欄時會用Grid。
你可以看到,左篇那一行的標題,YT是用flex來排版的(如圖右邊,都是flex),因為他就只有一行,是一維排版。
讓我們把玩一下,如果把inline-flex取消,他還是flex( — layout-display:flex;),不過變成block了,所以每個標籤都會占一行。
如果我連同 — layout-display:flex;一起取消,你會發現它爆炸了XD
接下來我們來看YT在Grid的應用吧:
影片的地方,Youtube是用grid來排版,因為他就是一格一格的內容,有行跟欄。
每一個影片都是一個grid-item:
而每個grid-item裡面的內容,都是用flex排版:
這也驗證了我們前面所說的,Flexbox for content and Grid for layout。
如何使用Grid排版?
你可以看到他一共有2row,3col,這是一個二維排版,所以要用Grid。
總共會有2*3=6個item。
在設定Grid排版時,你需要一個容器把item包住,代表這是一個Grid。
我們只需要在容器上設定display:grid;,下圖是尚未設定時的狀況:
接下來把wrapper宣告成gird排版:
恩?好像什麼都沒變化?那是因為我們還沒有設定grid-template-columns
grid-template-columns 網格中要有幾欄&每欄寬度
語法補充:repeat(共有幾欄,每欄多寬)
等同於grid-template-columns: 1fr 1fr 1fr;
試想,如果今天有20欄,你要打到何時,用repeat最快。
我們的目標排版中,column最多有三欄,而且每欄都是相同的比例,在學Grid之前,我們都會習慣用百分比表示,但這會延伸出一些問題,例如你在設定item之間的間距時可能會造成欄位溢出,所以我們在設定欄位寬度時,會使用fr相對單位。
Grid獨有的單位 — Fr
Fr是一個相對寬度。
如果是grid-template-columns:1fr 2fr 1fr
,意味著第一欄分配1/4寬度,第二欄2/4、第三欄1/4。
grid-template-row 共有幾行&每行高度
在這個案例中,我們希望他有2行,而且每行一樣大,故設定grid-template-rows:1fr 1fr;
這邊要特別注意的是,我們只有設定兩行的高度,所以如果有更多行出現,他並不會被設定到大小(如下圖)。
設定grid item之間的距離 — grid-gap
在Grid排版中,我們不用margin,而是用grid-gap,跟margin的概念一樣。
grid-gap是用來設定網格行與列之間的間隙,也能分別做設定:
grid-gap:大小
row-gap:行間隙大小
column-gap:欄間隙大小
這樣目標1就達成了。
Recap
首先我們宣告了display:grid
,再來我們用grid-template-columns
設定了網格中要有幾欄,以及每欄多寬。
緊接著我們用grid-template-rows
設定網格中要有幾行,以及每行多高。
最後我們用grid-gap
將行與列之間分隔開來。
我們也介紹了Grid(網格)中獨有的相對單位-Fr。
保持gird item大小一致
其實剛剛的設定已經完成了,因為我們已經設定了每欄跟每行的設定每行的高度跟寬度時,是用fr這個相對大小,所以他會自動變長會變寬。
不過今天如果我們是將每行的高度用絕對單位設定,會發生什麼事?
OMG,別急,會這樣很正常,而且也能補救。
為什麼正常?因為你已經設定了兩行的高度都要是各60px,px是一個絕對單位,他就是只有60px這麼高,如果內容超過,他必然會溢出。
如何補救 — minmax
語法:minmax(最小大小,最大大小)
因為我們希望他最少有60px高,但是我們又希望當內容增加時,他可以自動長長,而不是溢出,所以我們只要將最大高度max設定為auto,他就會根據item裡面內容,自動長長囉。
語法:minmax(60px,auto)
grid item中的圖片處理
#wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, minmax(60px, auto));
grid-gap: 1em;
}
修但幾勒,我們的每欄寬度不是已經是相對單位1fr了嗎?
為什麼還是壞了?
那是因為在fr開始分配寬度之前,圖片就會先把item撐大了。
解決方法 — max-width:100%;
因為我們希望圖片最寬就跟他的父元素一樣寬就好,不要把它撐開。
延伸閱讀
如何讓grid col width大小一致
結語
排版一直都是CSS難搞的原因,因為你很容易破版,在還沒有學框架之前,就是要試著去了解這些基本原則,我也還在學習當中,這篇就是我的學習筆記XD
大神路過歡迎指點小菜雞,互相交流,謝謝!
其他參考資料
When to use flexbox and when to use grid
Understanding the difference between grid-template and grid-auto