[譯] 簡單的響應式現代 CSS 網格佈局

在本文中,咱們將展現如何建立響應式現代 CSS 網格佈局,演示如何在舊瀏覽器上使用降級代碼,如何逐步添加 CSS 網格,如何使用對齊屬性從新構建小型設備的佈局以及居中元素。css

在以前的文章中,咱們探索了四種不一樣的技術,能夠輕鬆構建響應式網格佈局。那篇文章是在 2014 年寫的 —— 在 CSS 網格可用以前 —— 所以在本教程中,咱們將使用相似的 HTML 結構,但使用現代 CSS 網格佈局。前端

在本教程中,咱們將使用浮動來建立一個帶有基本佈局的演示項目,而後使用 CSS 網格對其進行加強。咱們將演示許多有用的實用工具,例如居中元素,跨越元素,以及經過從新定義網格區域和使用媒體查詢輕鬆更改小型設備上的佈局。你能夠在此 pen 中找到代碼:codepen.io/SitePoint/p…android

響應式現代 CSS 網格佈局

在咱們開始建立響應式網格演示項目以前,首先介紹一下 CSS 網格。ios

CSS 網格是一個功能強大的二維繫統,在 2017 年被添加到大多數現代瀏覽器中。它極大地改變了咱們建立 HTML 佈局的方式。網格佈局容許咱們在 CSS 而不是 HTML 中建立網格結構。git

除了 IE11 以外,大多數現代瀏覽器都支持 CSS 網格,IE11 支持可能產生一些問題的舊版標準。你可使用 caniuse.com 來檢查支持狀況。github

網格佈局有一個 display 屬性爲 gridinline-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> 標籤。瀏覽器

這是此階段頁面的屏幕截圖:bash

The basic HTML layout so far

接下來,讓咱們添加基本的 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() 函數來計算並設置主體部分可用的剩餘寬度。主體部分包含一些垂直排列的子項。

A gallery of items organized as vertical blocks

佈局並不完美。例如,側邊欄與主體內容部分的高度並不相同。有各類 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);,它在減去側邊欄的寬度加上外邊距/內邊距後計算主體部分的剩餘寬度。

這是結果的屏幕截圖。注意主體區域並無佔滿剩餘的所有寬度:

Progressive layout with current grid settings

要解決此問題,咱們能夠在支持網格時添加 width: auto;

@supports (display: grid) {
  main {
    width: auto;
  }
}
複製代碼

這是結果的屏幕截圖:

The effect of adding 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-fillauto-fit 的差別

這是結果的屏幕截圖:

A nested grid

使用網格 grid-columngrid-rowspan 關鍵詞

CSS 網格提供了 grid-columngrid-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;
}
複製代碼

這是結果的屏幕截圖:

Second child spanning four columns and two rows

使用網格對齊工具

咱們想讓頭部,側邊欄和頁腳中的文本以及 <article> 元素內的數字居中。

CSS 網格提供了六個屬性 justify-itemsalign-itemsjustify-contentalign-contentjustify-selfalign-self,可用於對齊和分散網格項。它們其實是 CSS 盒對齊模型的一部分。

在頭部內,側邊欄,文章和頁腳選擇器內添加如下內容:

display: grid;
align-items: center;
justify-items: center;
複製代碼
  • justify-items 用於沿行軸或在水平方向上對齊網格項。
  • align-items 沿着列軸或在垂直方向上對齊網格項。它們均可以使用 startendcenterstretch

這是居中元素後的屏幕截圖:

Numbers are now centered horizontally and vertically in each cell

重構小型設備中的網格佈局

咱們的演示佈局適用於中型和大型屏幕,但可能不是在小屏幕設備中構建頁面的最佳方式。使用 CSS 網格,咱們能夠輕鬆地更改此佈局結構,使其在小型設備中平滑過渡 —— 經過從新定義網格區域及使用媒體查詢。

這是在添加代碼重構小型設備上的佈局以前的屏幕截圖:

The initial mobile layout

如今,添加如下 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 的設備上咱們使用寬度分別爲 6rem1fr5.5rem5.5rem 的四行,以及佔滿全部可用空間的一列。咱們還從新定義了網格區域,讓側邊欄在小型設備上處於主體內容區域下面的第三行:

The developing mobile layout

請注意,側邊欄的寬度並未佔滿可用寬度。這是由降級代碼引發的,因此咱們須要作的是在支持網格的瀏覽器上用 width: auto; 覆蓋掉 width: 6.3rem;

@supports (display: grid) {
  main, aside {
    width: auto;
  }
}
複製代碼

這是最終結果的屏幕截圖:

The final mobile layout

你能夠在本文開頭附近的 pen 中找到最終代碼,也能夠直接訪問此 pen

結論

在本教程中,咱們使用 CSS 網格建立了一個響應式演示佈局。咱們已經演示瞭如何針對舊版瀏覽器使用降級代碼,逐步添加 CSS 網格,在小型設備中重構佈局以及使用對齊屬性居中元素。

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索