談到響應式的佈局排版,除了 Flexbox 之外,還有一個不容忽視的重要屬性,就是 Grid。
以下圖為例,我們透過 Grid 也能夠很輕易的將主要內容以及導覽列做平面佈局的排版:
<div class="background">
<div class="wrapper">
<main>
<!-- some content -->
<section class="carousel">
<!-- some images -->
</section>
</main>
<aside>
<!-- some content -->
</aside>
</div>
</div>
其中,<main />
是左方的主要內容,<aside />
是右方的導覽列。我們只要在 wrapper
上面宣告為 display: grid;
將其宣告為 grid 的外容器,就能夠對子元件做網格佈局:
.wrapper {
display: grid;
grid-template-columns: 1fr 248px;
grid-gap: 40px;
}
藉由 grid-template-columns
,我們定義左方主要內容的寬度為 1fr
,而右方側邊導覽列寬度則為固定的 248px
。
假設今天我們沒有這個 carousel
元件,那我們視窗在做縮放的時候,1fr
的主要內容區塊,也會隨著視窗的大小作縮放,到目前為止都符合我們的預期:
可是當我們把 carousel
放入主要內容區塊的時候,會發現,在窄螢幕狀態時會有非常嚴重的跑版,因為 1fr
的主要內容區塊,居然隨著視窗縮小到一個程度之後就不再縮小了:
在這之前,我們先來看一下 carousel
的結構以及作法,由於 carousel
是橫向排列,我們很直覺的會想使用 Flexbox 來處理佈局:
<section class="carousel">
<img src={bird} alt="" />
<img src={duck} alt="" />
<img src={eagle} alt="" />
<img src={frog} alt="" />
<img src={snake} alt="" />
</section>
.carousel {
display: flex;
overflow-x: auto;
gap: 20px;
}
在 .carousel
的 css 當中,我們將他宣告為 Flexbox 容器,然後讓裡面的照片水平排列。
其實魔鬼就藏在這個細節裡面,CSS Grid 網格為其子元件設置了默認的最小內容大小,亦即 auto
。 這表示,如果有一個元素大於網格的子元件,他的內容將會溢出。
換句話說,對於 1fr
實際上的預設定義是 minmax(auto, 1fr)
,所以這就很顯而易見,當那個 auto
生效的時候,就會取 max-content
來當作一個尺寸。
另一方面,因為 carousel 這個 Flexbox 預設是一個不換行的排列,因此如果主要內容區塊 1fr
縮小到無法容納 carousel 的時候,就會出現滾動調,以及上面破版的狀況。
為了防禦這樣的狀況發生,我們可以考慮使用 minmax(0, 1fr)
,藉此來解決預設 auto
所產生的問題:
.wrapper {
display: grid;
grid-template-columns: minmax(0, 1fr) 248px;
grid-gap: 40px;
}
從下圖我們可以看到,主要區塊縮小之後,裡面的 carousel 能夠保持在區塊內,並且藉由滾動條來瀏覽:
今天我們介紹了 CSS Grid 中,最小內容大小讓 grid-item 在縮放時產生的問題,因為 grid-item 當中的 Flexbox 預設為不換行,因此造成 grid-item 縮放時空間不足而造成破版。所以,在使用 Grid 的時候記得要留意,是否其內容有無法伸縮的元件在其中。