CSS Grid 系列(下)-使用Grid佈局構建網站首頁

飢人谷前端發表於2018-01-23

by Chris House 譯者:若愚老師

想要更好的閱讀體驗可在飢人谷技術部落格 檢視原文

要看懂這篇文章,推薦先簡單過一遍姊妹篇 CSS Grid 系列(上)-Grid佈局完整指南

當我開始一個專案,並開始計劃如何佈局主頁時,我的大腦復現出浮動和定位。有些人可能會使用 Bootstrap 或其他框架。 那是因為這是2016年,我們一直在用這些方法來做佈局。 但假設我們乘坐時光機來到2018年,所有主流瀏覽器都支援CSS Grid 佈局模組。此時我們的頁面佈局模式已經完全改變,CSS的功能最終強大到能輕鬆實現我們的設計目標,這是一個web開發人員最美好的時代。現在,讓我們使用超讚的工具——Grid佈局來建立一個主頁。

設計

下面是我們將要實現的頁面

CSS Grid 系列(下)-使用Grid佈局構建網站首頁

在我們開始編碼之前,我們需要進入網格的思維模式。 第一步是觀察我們的設計稿,並將其劃分為主要的網格元件。 以下是我為此設計做的劃分:

CSS Grid 系列(下)-使用Grid佈局構建網站首頁

你會發現整個頁面分為7個頂級網格區域。 我之所以說“頂級”是因為我們可以在其內部繼續巢狀網格,這正是我們將要對hero部分所做的事:

CSS Grid 系列(下)-使用Grid佈局構建網站首頁

HTML

這是HTML的基本結構。 稍後我會顯示整個完成的檔案,但現在我已經省去了大部分的細節。 這裡要注意的重要部分是作為 body 的直接後代的7個元素:top-barmain-headerheroblog-postsnewsside-bar 以及 main-footerbody將成為我們的網格容器(grid container),它的孩子將成為網格項(grid items)。

正如剛剛提到的,我們也將設定 hero 作為網格容器。 它有兩個孩子,將作為網格項:messageaward

<body>

  <header class="top-bar">
    <!-- social links and contact info -->
  </header>

  <header class="main-header">
    <!-- logo and main navigation -->
  </header>

  <section class="hero">
    <div class="message">
      <!-- circular element -->
    </div>
    <div class="award">    
      <!-- award image and quote -->      
    </div>
  </section>

  <section class="blog-posts">
    <!-- blog posts and excerpts -->
  </section>

  <section class="news">
    <!-- news headlines and excerpts -->
  </section>

  <aside class="side-bar">
    <!-- critter of the month info -->
  </aside>

  <footer class="main-footer">
    <!-- footer menu and copyright -->
  </footer>

</body>
複製程式碼

CSS

Okey,我們按照這種方式講解,教程中我們不會展示所有使用到的CSS,在文章的最後我會展示最終完整的檔案。現在我們只關注吸引我們的網格部分以及任何與它直接相關的樣式即可。

我們首先在body上定義主網格容器:

body{
  display: grid;
  grid-template-columns: 12% auto 400px 12%;
  grid-template-rows: auto auto 950px auto auto auto;
}
複製程式碼

我們剛剛建立了一個4列6行的網格,第一列和最後一列將作為主內容兩側的填充。 我把第三列設定為400px,因為這是我們將要放置side-bar元素的地方,我們希望這是一個固定的寬度。 hero 元素(第三行)的固定高度為950px。

現在我們使用grid-template-areas來定義某個網格區域會跑到哪裡。 這是非常有趣的部分:

body{
  display: grid;
  grid-template-columns: 12% auto 400px 12%;
  grid-template-rows: auto auto 950px auto auto auto;
  grid-template-areas: "top-bar     top-bar     top-bar     top-bar"
                       "main-header main-header main-header main-header"
                       "hero        hero        hero        hero"
                       ".           blog-posts  side-bar    ."
                       ".           news        side-bar    ."
                       "main-footer main-footer main-footer main-footer";  
}
複製程式碼

grid-template-areas讓我們能把元素放在任何想要放置的地方,並且對於元素的佈局該屬性給我們提供一個不錯的視覺化。 值得注意的是,這裡使用的值(top-barmain-headerhero等)不是指那些元素的類名,而是指我們用grid-area屬性給它們起的名字,下一步我們將對它們命名。

當網格區域名稱重複時,該元素將跨越這些列/行。 例如,top-bar 橫跨四列,side-bar橫跨四行和五行。 .號代表空單元格。如果你回頭看看上面的完整設計,您會看到這個定義如何與我們的網格模式相匹配。

假設我們已經應用了我們所有的樣式,但還沒有為網格項分配網格區域名稱,到目前為止我們的頁面看起來還不太好:

CSS Grid 系列(下)-使用Grid佈局構建網站首頁

在將網格區域名稱分配給網格項之前,網格將根據它們的源順序自動將我們的元素放置在網格中。 顯然這不是我們想要的。 為了使我們的佈局按預期工作,我們需要定義我們的網格區域。所以我們繼續往下走:

.top-bar{
  grid-area: top-bar;
} 
.main-header{
  grid-area: main-header;
} 
.hero{
  grid-area: hero;
}
.blog-posts{
  grid-area: blog-posts;
}
.news{
  grid-area: news;
}
.side-bar{
  grid-area: side-bar;
}
.main-footer{
  grid-area: main-footer;
}
複製程式碼

需要注意的是這些名稱可以隨意設定。 為了方便,我選擇了讓它們與類名相匹配。

現在,我們已經為網格項分配了網格區域名稱,它們將在被放置在網格中合適的位置。 這一步帶來的變化很大:

CSS Grid 系列(下)-使用Grid佈局構建網站首頁

除了 hero 部分中的網格項外,所有內容都完全按照需要正確放置,我們差不多要完成了。

但是在我們修復 hero 部分之前,我想解釋一下一些難以理解的地方:主要內容兩邊的填充區域的設定。 作為提醒,我們再次把剛剛的設定搬過來,用如下方式調整列:

body{
  grid-template-columns: 12% auto 400px 12%;
}
複製程式碼

設定為12%的兩列用於填充主要內容兩邊的空白,但是它們僅用於第四行和第五行。 回想一下,我們告訴我們的top-barmain-headerheromain-footer元素跨越所有列,包括這兩個“填充”列。 我們為什麼這樣做? 因為我們希望這些元素的背景色橫跨越整個視窗寬度,且任何一側都沒有空白。 我們只想在 blog-post/newssidebar元素周圍留出空白(第四行和第五行)。

為了讓元素水平覆蓋整個寬度,同時讓元素裡面的內容儲存一定的padding,我們需要顯示地在這些元素上設定padding:

.top-bar{
  padding: 4px 12%; 
}
.main-header{
  padding: 12px 12%;
}
.hero{  
  padding: 55px 12% 0 12%;
}
.main-footer{
  padding: 25px 12%;
}
複製程式碼

我們給元素設定左右 padding 為12%,這和grid-template-areas定義中的第一列和最後一列的寬度是一樣的。 現在,需要填充整個寬度的元素最終呈現的結果是,背景橫跨水平寬度,但其內容在兩側都預留出12%的空白。 很贊!

好了,讓我們來修復 hero 部分。 這也將是一個網格容器,因此我們把它定義為一個網格,就像剛剛做過的那樣:

.hero{
  display: grid;
  grid-template-columns: auto 1fr auto;
  grid-template-rows: auto auto auto;
  grid-template-areas: ".       .  award"
                       "message .  .    "
                       ".       .  .    "; 
 }
複製程式碼

這是一個3×3的網格,除了中間的列,其它都設定為 auto。 我們給中間一列大小設為1fr,因為我們希望在第一列和最後一列用東西填充後,剩下的空間完全需要完全填滿。

hero中只有兩個元素:messageaward。 我們要message佔據第二行的第一列,我們要award佔據第一行的第三列。所以我們的完整網格定義應該如下所示:

.hero{
  display: grid;
  grid-template-columns: auto 1fr auto;
  grid-template-rows: auto auto auto;
  grid-template-areas: ".       .  award"
                       "message .  .    "
                       ".       .  .    ";  
 }
複製程式碼

下面我們所要做的就是命名我們的元素:

.message{
  grid-area: message;
}
.award{
  grid-area: award;
}
複製程式碼

就這樣,messageaward卡入到位,我們的頁面完成:

CSS Grid 系列(下)-使用Grid佈局構建網站首頁

引入響應式

CSS Grid 使用媒體查詢讓重新排列整個佈局變得非常簡單。你所做的就是重新放置你的網格項。現在回到我們的設計,簡單起見,我們只對兩個寬度臨界值做響應式處理,1600px 和 1050px。我們需要對一些元素(padding、margin等)進行一些小的樣式調整,但是我不會把所有的樣式調整都全部展示在這裡。後面我會放出完整的程式碼,現在我們只需要關注關注網格相關的東西即可。

1600px 這個臨界點的處理比較簡單,當瀏覽器寬度到底1600px時我們將減少網站外部填充的地方。 之所以選擇1600px,是到了這個寬度後12%填充看起來不太合適。為了解決這個問題,我們需要做的是在body上改變grid-template-columns的值,將第一列和最後一列減少到2%。 我們還需要調整其他元素的填充以匹配:

@media (max-width: 1600px) {
  body{
    grid-template-columns: 2% auto 400px 2%;
  }
  .top-bar{
    padding: 4px 2%;
  }
  .main-header{
    padding: 12px 2%;
  }
  .hero{
    padding: 55px 2% 0 2%;
  }
  .main-footer{
    padding: 25px 2%;
  }
}
複製程式碼

對於下一個臨界值,我們對網格項重新排列,使它們排列在一個列中。 再次回頭看看我們原來的程式碼是如何對body進行設定的:

body{
  display: grid;
  grid-template-columns: 12% auto 400px 12%;
  grid-template-rows: auto auto 950px auto auto auto;
  grid-template-areas: "top-bar     top-bar     top-bar     top-bar"
                       "main-header main-header main-header main-header"
                       "hero        hero        hero        hero"
                       ".           blog-posts  side-bar    ."
                       ".           news        side-bar    ."
                       "main-footer main-footer main-footer main-footer";  
}
複製程式碼

下面是重新設定的媒體查詢:

@media (max-width: 1050px) {
  body{
    grid-template-columns: 3% auto 3%;
    grid-template-rows: auto auto auto auto auto auto auto;
    grid-template-areas: "top-bar     top-bar     top-bar"
                         "main-header main-header main-header"
                         "hero        hero        hero"
                         ".           blog-posts  ."
                         ".           news        ."
                         ".           side-bar    ."
                         "main-footer main-footer main-footer";
  }
}
複製程式碼

我們在這裡做了一些重要的改變:將列數從四個減少到三個,將第一列和最後一列的值改為3%(3%在較窄的寬度上優於2%),新增了 附加行,將所有行的長度改為auto,並將side-bar移動到自己的行。 現在我們的頁面元素很適合在較窄的寬度下展示:

CSS Grid 系列(下)-使用Grid佈局構建網站首頁

The Live Code

下面是我們的主頁,以及完整的HTML和CSS檔案。 你需要一個支援grid的瀏覽器來檢視預覽。 我建議啟用Experimental Web Platform Features標誌的Chrome 49+(位址列輸入 chrome:// flags ,並向下滾動到“Experimental Web Platform Features”)。

下面的嵌入式頁面預設會以移動檢視展示,可以點選“Edit on Codepen”在頁面全寬下展示不同的效果:

在 CodePen 檢視效果 Building a Home Page with Grid by Chris House (@chrishouse) .

補充:基本佈局程式碼

加微訊號: astak10或者長按識別下方二維碼進入前端技術交流群 ,暗號:寫程式碼啦

每日一題,每週資源推薦,精彩部落格推薦,工作、筆試、面試經驗交流解答,免費直播課,群友輕分享... ,數不盡的福利免費送

CSS Grid 系列(下)-使用Grid佈局構建網站首頁

相關文章