CSS Grid佈局:合併單元格佈局

CSS Grid佈局:網格單元格佈局》一文中經過一些簡單的實例介紹瞭如何給容器定義網格,而且怎麼使用網格線或者網格區域來實現單元格這樣的簡單的佈局。在文章結尾之處也提到過,這樣的單元格如同表格同樣,僅僅一個個獨立的單元格是沒法知足一些複雜的Web佈局,咱們須要將多個單元格合併在一塊兒,拼裝成一個稍爲複雜一點的佈局。簡單點說,就是由單元格慢慢過渡到具備合併單元格的佈局(在腦海中想一想曾經愛過的table)。css

那麼接下來咱們要介紹的是如何使用CSS Grid Layout實現一些更有意思的佈局。html

期待中的佈局...

在腦海中有不少種佈局效果,那咱們先來看一種常見的,簡單的佈局模板,以下圖所示:css3

佈局模板.png

上圖也是這一章須要實現的一種佈局方式,就將其稱爲網格的合併單元格佈局,由於他和表格中的合併單元格是很是的類似。segmentfault

你們是否還記得,在《CSS Grid佈局:網格單元格佈局》一文中經過網格線的grid-column-startgrid-column-endgrid-row-startgrid-row-end(或者grid-column: start / endgrid-row: start / end)能夠很是方便的實現單元格的佈局,那麼這種方式一樣能夠運用於合併的單元格佈局中。如此一來,若是咱們須要實現上圖展現的佈局,就能夠給每一個子元素設置網格線,而後劃分出各自的佔位區。來看看其對應的網格線:瀏覽器

網格線.png

有了這樣的示意圖,我想要實現這個佈局對於你們來講並非一件複雜的事情。接下來咱們經過實例來演示。app

基於網格線實現單元格合併

從示圖中不難發現:佈局

  • A區(.a)跨越了三列和兩個列間距,對應網格佈局中,他佔了五個網格,從網格線上來劃分,他是列網格線line1line6和行網格線line1line2圈起的空間
  • C、D、E、G和H幾個區與之前介紹的單元格並沒有不一樣之處,對於的網格線能夠看上面的網格線展現示意圖
  • F區(.f)跨越了兩列和一個列間距,對應網格佈局中,他佔了三個網格,從網格線上來劃分,他是列網格線line1line4和行網格線line5line6圈起的空間
  • I區(.i)和F區相似,只不過他是列網格線line3line6和行網格線line7line8圈起的空間
  • J區(.j)和A區相似,只不過他是列網格線line1line6和行網格線line9line10圈起的空間
  • B區(.b)和前面幾個區都有點不同,他是將行合併在一塊兒,跨越了網格中全部的行,從網格線上來劃分,他是列網格線line7line8和行網格線line1line10圈起的空間

從外觀上看,這跟平時看到的兩列布局很是的類似。不一樣之處是這裏經過網格來實現。來看看具體代碼:spa

HTML
<div class="wrapper">
  <div class="box a">A</div>
  <div class="box b">B</div>
  <div class="box c">C</div>
  <div class="box d">D</div>
  <div class="box e">E</div>
  <div class="box f">F</div>
  <div class="box g">G</div>
  <div class="box h">H</div>
  <div class="box i">I</div>
  <div class="box j">J</div>
</div>
CSS
body {
  padding: 50px;
}
.wrapper {
  display: grid;
  grid-template-columns: 100px 10px 100px 10px 100px 10px 100px;
  grid-template-rows: auto 10px auto 10px auto 10px auto 10px auto;
}
.box {
  background-color: #444;
  color: #fff;
  font-size: 150%;
  padding: 20px;
  text-align: center;
}
.a{
  grid-column: 1 / 6; 
  grid-row: 1 / 2;
}
.b {
  grid-column: 7 / 8; 
  grid-row: 1 / 10; 
  background: orange;
}
.c { 
  grid-column: 1 / 2; 
  grid-row: 3 / 4;
}
.d { 
  grid-column: 3 / 4; 
  grid-row: 3 / 4;
}
.e { 
  grid-column: 5 / 6; 
  grid-row: 3 / 4;
}
.f { 
  grid-column: 1 / 4; 
  grid-row: 5 / 6;
}
.g {
  grid-column: 5 / 6; 
  grid-row: 5 / 6;
}
.h {
  grid-column: 1 / 2; 
  grid-row: 7 / 8;
}
.i {
  grid-column: 3 / 6; 
  grid-row: 7 / 8;
}
.j {
  grid-column: 1 / 6; 
  grid-row: 9 / 10;
}

效果以下:code

基於網格線合併單元格.png

在線案例htm

從效果圖中,不難發現,雖然在B區經過網格線定義了跨行:

.b {
  grid-column: 7 / 8; 
  grid-row: 1 / 10; 
  background: orange;
}

但瀏覽器實際解析並非跟咱們想象的同樣。爲何跨行沒有效果呢?具體是什麼緣由,說實在的,我也不知道,或許有一天會更正這個問題。那麼有沒有方法能解決呢?咱們先繼續往下看吧。或許你能找到你須要的答案。

基於網格線使用關鍵詞span實現單元格合併

在CSS Grid Layout佈局中除了使用網格線合併單元格以外,還可使用關鍵詞span來實現單元格合併。接下來的實例,將使用span關建詞完成上例同樣的效果。

.wrapper {
  display: grid;
  grid-template-columns: 100px 10px 100px 10px 100px 10px 100px;
  grid-template-rows: auto 10px auto 10px auto 10px auto 10px auto;
}
.a{
  grid-column: 1 / span 5; 
  grid-row: 1;
}
.b {
  grid-column: 7; 
  grid-row: 1 / span 9; 
  background: orange;
}
.c { 
  grid-column: 1; 
  grid-row: 3;
}
.d { 
  grid-column: 3; 
  grid-row: 3;
}
.e { 
  grid-column: 5; 
  grid-row: 3;
}
.f { 
  grid-column: 1 / span 3; 
  grid-row: 5;
}
.g {
  grid-column: 5; 
  grid-row: 5;
}
.h {
  grid-column: 1; 
  grid-row: 7;
}
.i {
  grid-column: 3 / span 3; 
  grid-row: 7;
}
.j {
  grid-column: 1 / span 5; 
  grid-row: 9;
}

實現的效果同樣:

基於網格線合併單元格.png

在線案例

自定義網格線名稱

前面的示例,都是使用默認的網格線名稱來製做網格佈局,其實在CSS Grid Layout模塊中還提供了自定義網格線名稱,而後使用定義好的名稱來製做網格佈局。在CSS Grid Layout自定義網格線名稱都放置在()內。好比在下面的示例中,定義了列第一網格線名稱爲col1-start(對應的列網格線line1),而後後面緊跟第一列的軌道寬度100px,而後就是第一列後面的網格線col1-end(對應的列網格線line2)。行網格線也是相似。以下圖所示:

自定義網格線名稱.png

在網格定義網格線的方式以下:

.wrapper {
  display: grid;
  grid-template-columns: (col1-start) 100px (col1-end) 10px (col2-start) 100px (col2-end) 10px (col3-start) 100px (col3-end) 10px (col4-start) 100px (col4-end);
  grid-template-rows: (row1-start) auto (row1-end) 10px (row2-start) auto (row2-end) 10px (row3-start) auto (row3-end) 10px (row4-start) auto (row4-end) 10px (row5-start) auto (row5-end);
}

寫個實例,經過自定義的網格線實現上例同樣的網格佈局效果:

.wrapper {
  display: grid;
  grid-template-columns: (col1-start) 100px (col1-end) 10px (col2-start) 100px (col2-end) 10px (col3-start) 100px (col3-end) 10px (col4-start) 100px (col4-end);
  grid-template-rows: (row1-start) auto (row1-end) 10px (row2-start) auto (row2-end) 10px (row3-start) auto (row3-end) 10px (row4-start) auto (row4-end) 10px (row5-start) auto (row5-end);
}
.a{
  grid-column: col1-start / col3-end; 
  grid-row: row1-start;
}
.b {
  grid-column: col4-start / col4-end; 
  grid-row: row1-start / row5-end; 
  background: orange;
}
.c { 
  grid-column: col1-start; 
  grid-row: row2-start;
}
.d { 
  grid-column: col2-start; 
  grid-row: row2-start;
}
.e { 
  grid-column: col3-start; 
  grid-row: row2-start;
}
.f { 
  grid-column: col1-start / col2-end; 
  grid-row: row3-start;
}
.g {
  grid-column: col3-start; 
  grid-row: row3-start;
}
.h {
  grid-column: col1-start; 
  grid-row: row4-start;
}
.i {
  grid-column: col2-start / col3-end; 
  grid-row: row4-start;
}
.j {
  grid-column: col1-start / col3-end; 
  grid-row: row5-start;
}

效果和預期的同樣,能夠打示演示案例查看效果。

在線案例

自定義網格線配合關鍵詞span合併單元格

上面那種自定義網各線的方法好是好,但也有一個問題,若是網格線少,仍是蠻方便的,不過網格一多,網格線也多起來,每條網格線都定義名稱是否是太費時費力了。其實在CSS Grid Layout中不須要這麼作,你徹底能夠給網格線定義相同的名稱,而後使用關鍵詞span添加到特定的目標網格線。這種方法對於建立一些複雜的網格(包括多個網格與列間距)是很是方便的。

在實際使用中,能夠在網格內容軌道前的網格線都定義爲col,而在列間距軌道前的網格線都定義爲gutter。在調用時,可使用col <line number>來指定開始的網格線,配合關鍵詞span <number of lines of that name>來指寫網格的跨度。這樣說或許有些搞不明白,咱們來看一個簡單的示例,好比說咱們要實現下圖網格效果:

自定義網格線名稱.png

看看代碼要怎麼寫,才能完成上圖的網格效果:

.wrapper {
  display: grid;
  grid-template-columns: (col) 100px (gutter) 10px (col) 100px (gutter) 10px (col) 100px (gutter) 10px (col) 100px (gutter) 10px (col) 100px (gutter) 10px (col) 100px (gutter); 
  grid-template-rows: (row) auto (gutter) 10px (row) auto (gutter) 10px (row) auto (gutter) 10px (row) auto;
}

.a{
  grid-column: col / span gutter 2; 
  grid-row: row;
}
.b {
  grid-column: col 3 / span gutter 2; 
  grid-row: row;
}
.c { 
  grid-column: col 5 / span gutter 2; 
  grid-row: row;
}
.d { 
  grid-column: col / span gutter 3; 
  grid-row: row 2;
}
.e { 
  grid-column: col 4 / span gutter 3; 
  grid-row: row 2;
}
.f { 
  grid-column: col / span gutter 2; 
  grid-row: row 3;
}
.g {
  grid-column: col 3 / span gutter 1; 
  grid-row: row 3;
}
.h {
  grid-column: col 4 / span gutter 2; 
  grid-row: row 3;
}
.i {
  grid-column: col 6 / span gutter 1; 
  grid-row: row 3;
}
.j {
  grid-column: col  / span gutter 6; 
  grid-row: row 4;
}

效果以下:

自定義網格線名稱.png

在線案例

repeat關鍵詞

在上例中,不難發現列和行都有不少重複的,好比:列網格線有六個(col) 100px (gutter) 10px,而行網格線有四個(row) auto (gutter) 10px。其實在CSS Grid Layout沒有必要這麼痛苦,他提供了一個關鍵repeat,徹底可使用repeat來讓你的代碼變得更簡潔。

使用repeat的代碼以下:

.wrapper {
  display: grid;
  grid-template-columns:repeat(6, (col) 100px (gutter) 10px); 
  grid-template-rows: repeat(4, (row) auto (gutter) 10px );
}

你將看到效果:

在線案例

是否是如出一轍呀。是否是變得輕鬆多了。

網格區域製做合併單元格

在上一節中,介紹了網格區域製做單元格,其實根據網格區域的定義,也可使用網格區域實現單元格的效果。回到文章第一個示例,使用網格區域,只須要這樣寫,就能夠輕鬆實現所須要的效果:

.wrapper {
  display: grid;
  display: grid;
    grid-template-columns: 100px 10px 100px 10px 100px 10px 100px;
    grid-template-rows: auto 10px auto 10px auto 10px auto 10px auto;
}
.a{
  grid-area: 1 / 1 / 2 / 6;
}
.b {
  grid-area: 1 / 7 / 10 / 8;
  background: orange;
}
.c { 
  grid-area: 3 / 1 / 4 / 2; 
}
.d { 
  grid-area: 3 / 3 / 4 / 4;
}
.e { 
  grid-area: 3 / 5 / 4 / 6;
}
.f { 
  grid-area: 5 / 1 / 6 / 4;
}
.g {
  grid-area: 5 / 5 / 6 / 6;
}
.h {
  grid-area: 7 / 1 / 8 / 2;
}
.i {
  grid-area: 7 / 3 / 8 / 6;
}
.j {
  grid-area: 9 / 1 / 8 / 6;
}

效果以下:

在線案例

模擬合併行

從上面演示的衆多示例能夠得知,在CSS Grid Layout中合併行並無像合併列來得那麼簡單。換句話說,要實現下圖的效果,到目前爲止僅使用CSS Grid Layout的網格線或者網格區域是沒法實現的。

佈局模板.png

或許你們會說,拋開瀏覽器的兼容性問題,若是我真要實現上圖的佈局風格,怎麼破呢?我嘗試了一下,若是須要強制實現上圖效果,能夠在.b容器中添加一段代碼:

.b {
  grid-area: 1 / 7 / 10 / 8;
  background: orange;
  height: 100%;
  box-sizing:border-box;
}

若是就模擬出上圖須要的效果。

在線案例

總結

單元格的合併對於實現一個複雜的網格佈局是不可或缺的,那麼這篇文章主要向你們介紹瞭如何使用網格線製做網格的合併效果。實現方法有不少種,能夠用網格線來劃分,也可使用關鍵詞span來跨列,固然還可使用repeat來減小網格線定義的重複工做。除了網格線以外,還可使用網格區域來實現合併單元格的效果。不知道你掌握了幾種方法呢?

via w3cplus

相關文章
相關標籤/搜索