- 原文地址:Easy and Responsive Modern CSS Grid Layout
- 原文作者:Ahmed Bouchefra
- 譯文出自:掘金翻譯計劃
- 本文永久連結:github.com/xitu/gold-m…
- 譯者:MeFelixWang
- 校對者:CoolRice
在本文中,我們將展示如何建立響應式現代 CSS 網格佈局,演示如何在舊瀏覽器上使用降級程式碼,如何逐步新增 CSS 網格,如何使用對齊屬性重新構建小型裝置的佈局以及居中元素。
在之前的文章中,我們探索了四種不同的技術,可以輕鬆構建響應式網格佈局。那篇文章是在 2014 年寫的 —— 在 CSS 網格可用之前 —— 因此在本教程中,我們將使用類似的 HTML 結構,但使用現代 CSS 網格佈局。
在本教程中,我們將使用浮動來建立一個帶有基本佈局的演示專案,然後使用 CSS 網格對其進行增強。我們將演示許多有用的實用工具,例如居中元素,跨越元素,以及通過重新定義網格區域和使用媒體查詢輕鬆更改小型裝置上的佈局。你可以在此 pen 中找到程式碼:codepen.io/SitePoint/p…
響應式現代 CSS 網格佈局
在我們開始建立響應式網格演示專案之前,首先介紹一下 CSS 網格。
CSS 網格是一個功能強大的二維繫統,在 2017 年被新增到大多數現代瀏覽器中。它極大地改變了我們建立 HTML 佈局的方式。網格佈局允許我們在 CSS 而不是 HTML 中建立網格結構。
除了 IE11 之外,大多數現代瀏覽器都支援 CSS 網格,IE11 支援可能產生一些問題的舊版標準。你可以使用 caniuse.com 來檢查支援情況。
網格佈局有一個 display
屬性為 grid
或 inline-grid
的父容器。容器的子元素是網格項,由強大的網格演算法隱式定位。你還可以應用不同的類來控制網格項的放置,尺寸,位置和其他方面的東西。
讓我們從一個基本的 HTML 頁面開始。建立 HTML 檔案並新增以下內容:
<header>
<h2>CSS Grid Layout Example</h2>
</header>
<aside>
.sidebar
</aside>
<main>
<article>
<span>1</span>
</article>
<article>
<span>2</span>
</article>
<!--... -->
<article>
<span>11</span>
</article>
</main>
<footer>
Copyright 2018
</footer>
複製程式碼
我們使用 HTML 語義標籤來定義頁面的頭部,側邊欄,主體和頁尾部分。在主體部分中,我們使用 <article>
標籤新增一組子項。<article>
是一個 HTML5 語義標籤,可用於包裝獨立和自包含的內容。單個頁面可以包含任意數量的 <article>
標籤。
這是此階段頁面的螢幕截圖:
接下來,讓我們新增基本的 CSS 樣式。在文件的頭部新增 <style>
標籤並新增以下樣式:
body {
background: #12458c;
margin: 0rem;
padding: 0px;
font-family: -apple-system, BlinkMacSystemFont,
"Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell",
"Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
}
header {
text-transform: uppercase;
padding-top: 1px;
padding-bottom: 1px;
color: #fff;
border-style: solid;
border-width: 2px;
}
aside {
color: #fff;
border-width:2px;
border-style: solid;
float: left;
width: 6.3rem;
}
footer {
color: #fff;
border-width:2px;
border-style: solid;
clear: both;
}
main {
float: right;
width: calc(100% - 7.2rem);
padding: 5px;
background: hsl(240, 100%, 50%);
}
main > article {
background: hsl(240, 100%, 50%);
background-image: url('https://source.unsplash.com/daily');
color: hsl(240, 0%, 100%);
border-width: 5px;
}
複製程式碼
這是一個小型演示頁面,因此我們將直接設定標籤樣式以提高可讀性,而不是應用類命名系統。
我們使用浮動將側邊欄定位到左側,將主體部分定位到右側,將側邊欄的寬度設定為固定的 6.3rem。然後我們使用 CSS calc()
函式來計算並設定主體部分可用的剩餘寬度。主體部分包含一些垂直排列的子項。
佈局並不完美。例如,側邊欄與主體內容部分的高度並不相同。有各種 CSS 技術可以解決這些問題,但大多數都是 hack 或變通方法。由於此佈局是網格的降級,因此快速減少的使用者也可以看到效果。降級是可用的,足夠了。
最新版本的 Chrome、Firefox、Edge、Opera 和 Safari 都支援 CSS 網格,這意味著如果你的訪問者使用這些瀏覽器,則無需提供降級。你還需要考慮常青瀏覽器。最新版本的 Chrome、Firefox、Edge 和 Safari 是常青瀏覽器。也就是說,它們會在不提示使用者的情況下自動靜默更新。為確保你的佈局適用於每個瀏覽器,你可以從預設的基於浮動的降級開始,然後使用漸進增強技術應用現代網格佈局。那些使用舊瀏覽器的使用者將無法獲得相同的體驗,但這樣足夠了。
漸進增強:你不必全部覆蓋
在降級佈局的頂部新增 CSS 網格佈局時,實際上不需要覆蓋所有標籤或使用完全獨立的 CSS 樣式:
- 在不支援 CSS 網格的瀏覽器中,你新增的網格屬性將被忽略。
- 如果你使用浮動來佈置元素,請記住網格項優先於浮動項。也就是說,如果將
float: left|right
樣式新增到也是網格元素的元素(具有display: grid
樣式的父元素的子元素)中,則將忽略浮動以支援網格。 - 可以使用
@supports
規則在 CSS 中檢查特定功能的支援情況。這允許我們在必要時覆蓋降級樣式,而舊瀏覽器會忽略@supports
程式碼塊。
現在,讓我們在頁面中新增 CSS 網格。首先,我們讓 <body>
成為一個網格容器並設定網格列,行和區域:
body {
/*...*/
display: grid;
grid-gap: 0.1vw;
grid-template-columns: 6.5rem 1fr;
grid-template-rows: 6rem 1fr 3rem;
grid-template-areas: "header header"
"sidebar content"
"footer footer";
}
複製程式碼
我們使用 display:grid
屬性將 <body>
標記為網格容器。將網格 gap 設為 0.1vw
。gap 允許你在網格單元格之間建立間距,而不是使用外邊距。
我們用 grid-template-columns
來新增兩列。第一列寬度固定為 6.5rem
,第二列為剩餘寬度。fr
是一個小數單位,1fr
等於可用空間的一部分。
接下來,我們用 grid-template-rows
新增三行。第一行高度固定為 6rem
,第三行高度固定為 3rem
,剩餘可用空間(1fr
)指定給第二行。
然後我們用 grid-template-areas
將由列和行的交集產生的虛擬單元格分配給區域。現在我們需要使用 grid-area
實際定義區域模板中指定的區域:
header {
grid-area: header;
/*...*/
}
aside {
grid-area: sidebar;
/*...*/
}
footer {
grid-area: footer;
/*...*/
}
main {
grid-area: content;
/*...*/
}
複製程式碼
我們的大多數降級程式碼對 CSS 網格沒有任何副作用,除了主體部分的寬度 width: calc(100% - 7.2rem);
,它在減去側邊欄的寬度加上外邊距/內邊距後計算主體部分的剩餘寬度。
這是結果的螢幕截圖。注意主體區域並沒有佔滿剩餘的全部寬度:
要解決此問題,我們可以在支援網格時新增 width: auto;
:
@supports (display: grid) {
main {
width: auto;
}
}
複製程式碼
這是結果的螢幕截圖:
新增巢狀網格
網格子項可以是網格容器本身。讓我們將主體部分作為一個網格容器:
main {
/*...*/
display: grid;
grid-gap: 0.1vw;
grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
grid-template-rows: repeat(auto-fill, minmax(12rem, 1fr));
}
複製程式碼
我們將網格 gap 設為 0.1vw
並使用 repeat(auto-fill, minmax(12rem, 1fr));
函式定義列和行。auto-fill
選項會嘗試使用盡可能多的列或行填充可用空間,必要時會建立隱式列或行。如果要將可用列或行放入可用空間,則需要使用 auto-fit
。詳情請閱讀 auto-fill
和 auto-fit
的差異。
這是結果的螢幕截圖:
使用網格 grid-column
,grid-row
和 span
關鍵詞
CSS 網格提供了 grid-column
和 grid-row
,它們允許你使用網格線在父網格中對網格項進行定位。它們是以下屬性的簡寫:
grid-row-start
: 指定網格行中網格項的起始位置grid-row-end
: 指定網格行中網格項的結束位置grid-column-start
: 指定網格列中網格項的起始位置grid-column-end
: 指定網格列中網格項的結束位置。
你還可以使用關鍵字 span
指定要跨越的列數或行數。
我們讓主體區域的第二個子項跨越四列、兩行,並讓其從第二列和第一行(也是它的預設位置)開始放置:
main article:nth-child(2) {
grid-column: 2/span 4;
grid-row: 1/span 2;
}
複製程式碼
這是結果的螢幕截圖:
使用網格對齊工具
我們想讓頭部,側邊欄和頁尾中的文字以及 <article>
元素內的數字居中。
CSS 網格提供了六個屬性 justify-items
、align-items
、justify-content
、align-content
、justify-self
和 align-self
,可用於對齊和分散網格項。它們實際上是 CSS 盒對齊模型的一部分。
在頭部內,側邊欄,文章和頁尾選擇器內新增以下內容:
display: grid;
align-items: center;
justify-items: center;
複製程式碼
justify-items
用於沿行軸或在水平方向上對齊網格項。align-items
沿著列軸或在垂直方向上對齊網格項。它們都可以使用start
、end
、center
和stretch
。
這是居中元素後的螢幕截圖:
重構小型裝置中的網格佈局
我們的演示佈局適用於中型和大型螢幕,但可能不是在小螢幕裝置中構建頁面的最佳方式。使用 CSS 網格,我們可以輕鬆地更改此佈局結構,使其在小型裝置中平滑過渡 —— 通過重新定義網格區域及使用媒體查詢。
這是在新增程式碼重構小型裝置上的佈局之前的螢幕截圖:
現在,新增以下 CSS 程式碼:
@media all and (max-width: 575px) {
body {
grid-template-rows: 6rem 1fr 5.5rem 5.5rem;
grid-template-columns: 1fr;
grid-template-areas:
"header"
"content"
"sidebar"
"footer";
}
}
複製程式碼
在寬度 <= 575px
的裝置上我們使用寬度分別為 6rem
、1fr
、5.5rem
和 5.5rem
的四行,以及佔滿所有可用空間的一列。我們還重新定義了網格區域,讓側邊欄在小型裝置上處於主體內容區域下面的第三行:
請注意,側邊欄的寬度並未佔滿可用寬度。這是由降級程式碼引起的,所以我們需要做的是在支援網格的瀏覽器上用 width: auto;
覆蓋掉 width: 6.3rem;
:
@supports (display: grid) {
main, aside {
width: auto;
}
}
複製程式碼
這是最終結果的螢幕截圖:
你可以在本文開頭附近的 pen 中找到最終程式碼,也可以直接訪問此 pen。
結論
在本教程中,我們使用 CSS 網格建立了一個響應式演示佈局。我們已經演示瞭如何針對舊版瀏覽器使用降級程式碼,逐步新增 CSS 網格,在小型裝置中重構佈局以及使用對齊屬性居中元素。
如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。