CSS Flex 布局和 Grid 布局怎么選?
大家好,我是 CUGGZ。
CSS 中的 Flex 布局?和 Grid 布局都是非常強大的布局方案,那什么情況下應該使用 Grid 布局,什么情況下應該使用 Flex 布局呢?本文就來通過一些示例看看兩者之間的區別以及使用場景!
Grid 和 Flexbox 的區別
Grid 是二維布局模型,它有列和行。而 Flexbox 是一維布局模型,可以將其子項目布局為列或行,但不能同時布局行和列。
可以看到,Flexbox 正在布局元素的內聯列表(對一行元素進行布局),而 CSS 網格使它們組成列和行的網格。當然,也可以使用 Flexbox 布局對一列元素進行布局:
如何決定使用哪個?
在選擇其中一種布局時,可以考慮以下問題:
- 組件的子項如何顯示?內聯還是作為列和行?
- 組件如何在各種尺寸的屏幕上顯示?
大多數情況下,如果組件的子項都以內聯的方式顯示,那么 Flexbox 布局可能是最好的解決方案。考慮以下組件:
這個組件中包含兩個子元素,需要在一行中顯示,就非常適合使用 Flex 布局。
如果布局需要多個列和行,那么 Grid 布局就是最合適的解決方案。考慮以下組件:
看完這些示例,下面來通過一些具體的示例學習如何決定使用哪個布局方案。
使用場景
CSS Flexbox
(1)網站導航
大多數情況下,網站導航可以使用 CSS Flexbox 來構建。最常見的模式就是左側為網站 Logo,右側為網站導航,中間為空白區域。Flex 就可以輕松實現這個布局:
布局代碼如下:
(2)操作列表
操作列表通常由一組可以執行的操作按鈕組成,它們排列在一行中:
可以看到,這些操作按鈕都是相鄰的,并且是水平分布的。這種情況就非常適合使用 Flex 來布局:
下面這種包含標題欄或操作欄的場景也同樣適用 Flex 布局:
這個組件的頁眉和頁腳都有內聯顯示的子元素。對于頁眉,布局代碼如下:
對于頁腳,Cancel 按鈕比較特殊,可以使用自動左邊距將其推到右側。
(3)表單元素
下圖第一個組件中,左側的輸入框和右側的按鈕組合是 Flexbox 布局的完美用例:
在第二個組件中,使用 Flex 也可以快速完成布局。這里輸入框占據了所有剩余空間,其具有動態寬度。布局代碼如下:
(4)評論組件
Flexbox 的另一個常見用例就是評論組件。考慮以下示例:
這里左側是用戶的頭像,右側是評論內容,其占據了父元素的剩余空間。
(5)卡片組件
卡片組件有很多類型,最常見的卡片設計如下:
左側的卡片組件為上下布局,此時 Flex 容器的方向是列。右側的卡片組件為左右布局,此時 Flex 容器的方向是行,這是 Flex 布局方向的默認值。
另一種卡片,圖標的下方帶有文本,它可以是一個按鈕、鏈接。這種模式下 Flex 布局同樣適用:
第一種模式的布局代碼如下:
第二種模式的布局代碼如下:
(6)Tab 菜單
當涉及到占據整個屏幕寬度的元素并且具有應該填滿所有可用空間的項目時,Flexbox 也是完美的解決方案。
這里,每個項目都應該填充可用空間,并且它們的寬度是相等的。通過將容器元素的 display? 屬性設置為 flex,即可輕松完成。
(7)功能列表
Flexbox 的一個很實用功能就是可以反轉元素的方向。默認情況下,Flexbox 的方向是從從左到右的行,我們可以可以這樣來反轉它:
在下面的例子中,這個功能就非常實用:
在布局時,可以對偶數行的元素使用上述的方向反轉的屬性值。
(8)內容居中
假設有一個組件,它的內容需要在水平和垂直方向居中。可以通過 text-align 實現文本的水平居中。
可以使用 Flexbox 布局讓內容在水平和垂直方向居中:
CSS Grid
(1)側邊欄+內容區
當有側邊欄和內容區時,網格布局就是一個完美的解決方案。考慮以下組件:
可以在 CSS 中這樣定義:
如果 <aside>? 元素不使用 align-self?,它的高度將與 main 元素相同,無論內容長度如何。
(2)卡片網格
網格布局從名字就可以很好地理解,它很適合布局卡片網格:
布局代碼如下:
這里的列寬至少為 200px,如果空間不夠,它會將卡片換行。如果視口寬度小于 200px,上面的布局會出現水平滾動。
我們可以僅在視口寬度足夠時才添加網格布局的定義:
(3)部分布局
在下面的設計中,可以使用兩次網格布局。第一次將整個區域劃分為左右兩個區域(左側的側邊欄,右側的表單),第二次在表單中使用網格布局。
布局代碼如下:
Grid 和 Flexbox 結合使用
上面介紹了這兩種布局單獨使用的場景,當然也可以結合使用這兩種布局。考慮下面的例子,對于卡片列表,可以使用 Grid 布局來實現,對于每個卡片組件,就可以使用 Flexbox 布局來實現:
以下是對布局的要求:
- 每行卡片的高度應該相等;
- Read more 鏈接應位于卡片的末尾,高度不固定;
- Grid 應該使用 minmax() 函數
對于上面的代碼:
- card 元素作為 Flexbox 的容器;
- 布局方向為 column,表示卡片元素垂直分布;
- 讓卡片內容擴展并填充剩余空間;
- 卡片內容作為 Flexbox 的容器;
- 使用 margin-top: auto 將鏈接下推,無論卡片高度如何,這都會使其保持在末端。
可以看到,Grid 和 Flexbox 結合使用也不難,使用它們可以輕松實現日常開發的大多數布局。