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