by Chris House
譯者:若愚老師
想要更好的閱讀體驗可在飢人谷技術博客 查看原文
要看懂這篇文章,推薦先簡單過一遍姊妹篇 CSS Grid 系列(上)-Grid佈局完整指南css
當我開始一個項目,並開始計劃如何佈局主頁時,個人大腦復現出浮動和定位。有些人可能會使用 Bootstrap 或其餘框架。 那是由於這是2016年,咱們一直在用這些方法來作佈局。 但假設咱們乘坐時光機來到2018年,全部主流瀏覽器都支持CSS Grid 佈局模塊。此時咱們的頁面佈局模式已經徹底改變,CSS的功能最終強大到能輕鬆實現咱們的設計目標,這是一個web開發人員最美好的時代。如今,讓咱們使用超讚的工具——Grid佈局來建立一個主頁。html
下面是咱們將要實現的頁面前端
在咱們開始編碼以前,咱們須要進入網格的思惟模式。 第一步是觀察咱們的設計稿,並將其劃分爲主要的網格組件。 如下是我爲此設計作的劃分:web
你會發現整個頁面分爲7個頂級網格區域。 我之因此說「頂級」是由於咱們能夠在其內部繼續嵌套網格,這正是咱們將要對hero部分所作的事:面試
這是HTML的基本結構。 稍後我會顯示整個完成的文件,但如今我已經省去了大部分的細節。 這裏要注意的重要部分是做爲 body
的直接後代的7個元素:top-bar
、main-header
、hero
、 blog-posts
、 news
、 side-bar
以及 main-footer
。 body
將成爲咱們的網格容器(grid container),它的孩子將成爲網格項(grid items)。chrome
正如剛剛提到的,咱們也將設置 hero
做爲網格容器。 它有兩個孩子,將做爲網格項:message
和 award
。segmentfault
<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>
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-bar
,main-header
,hero
等)不是指那些元素的類名,而是指咱們用grid-area
屬性給它們起的名字,下一步咱們將對它們命名。
當網格區域名稱重複時,該元素將跨越這些列/行。 例如,top-bar
橫跨四列,side-bar
橫跨四行和五行。 .
號表明空單元格。若是你回頭看看上面的完整設計,您會看到這個定義如何與咱們的網格模式相匹配。
假設咱們已經應用了咱們全部的樣式,但尚未爲網格項分配網格區域名稱,到目前爲止咱們的頁面看起來還不太好:
在將網格區域名稱分配給網格項以前,網格將根據它們的源順序自動將咱們的元素放置在網格中。 顯然這不是咱們想要的。 爲了使咱們的佈局按預期工做,咱們須要定義咱們的網格區域。因此咱們繼續往下走:
.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; }
須要注意的是這些名稱能夠隨意設置。 爲了方便,我選擇了讓它們與類名相匹配。
如今,咱們已經爲網格項分配了網格區域名稱,它們將在被放置在網格中合適的位置。 這一步帶來的變化很大:
除了 hero
部分中的網格項外,全部內容都徹底按照須要正確放置,咱們差很少要完成了。
可是在咱們修復 hero
部分以前,我想解釋一下一些難以理解的地方:主要內容兩邊的填充區域的設置。 做爲提醒,咱們再次把剛剛的設置搬過來,用以下方式調整列:
body{ grid-template-columns: 12% auto 400px 12%; }
設置爲12%的兩列用於填充主要內容兩邊的空白,可是它們僅用於第四行和第五行。 回想一下,咱們告訴咱們的top-bar
、main-header
、hero
和main-footer
元素跨越全部列,包括這兩個「填充」列。 咱們爲何這樣作? 由於咱們但願這些元素的背景色橫跨越整個視窗寬度,且任何一側都沒有空白。 咱們只想在 blog-post
/news
和sidebar
元素周圍留出空白(第四行和第五行)。
爲了讓元素水平覆蓋整個寬度,同時讓元素裏面的內容保存必定的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
中只有兩個元素:message
和award
。 咱們要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; }
就這樣,message
和award
卡入到位,咱們的頁面完成:
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
移動到本身的行。 如今咱們的頁面元素很適合在較窄的寬度下展現:
下面是咱們的主頁,以及完整的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或者長按識別下方二維碼進入前端技術交流羣 ,暗號:寫代碼啦
每日一題,每週資源推薦,精彩博客推薦,工做、筆試、面試經驗交流解答,免費直播課,羣友輕分享... ,數不盡的福利免費送