两步构建 CSS Grid

3月7号,谷歌、火狐统一更新了浏览器,加入 CSS Grid 网格布局。为什么新的 CSS Grid 网格布局值得让前端工程师激动?我觉得有三个原因:

  1. CSS Grid 比使用 float 或 flex 拿来做复杂的布局更简单。
  2. 基于网格的网页设计,使用 CSS Grid 可以无缝地、简单地转换为网页布局,并且像素精确。
  3. 给网页响应式布局带来更多的可能性:CSS Grid 中的新属性,比如 grid-auto-flow, auto-fill, auto-fit, minmax 能够很简单地设置响应点及自动填充,给 Web 响应设计带来更多的可能性,在设备尺寸注定会越来越多的将来,CSS Grid 提前一步给出了解决方案。

本文主要写了如何两步构建 CSS Grid:

  1. 设置 CSS Grid frame;
  2. 放置 Grid items 到 frame 中。

以下是全文。

Set Grid Frame

To create a grid frame, two basic things need to be considered:

  1. How many rows and columns does the grid frame have?
  2. How tall and wide are the rows and columns?

These two basic properties can be defined with two CSS grid property: grid-template-rows and grid-template-columns. Here is an example:

Set CSS Grid Frame</a> by wanghongyang (<a href="http://codepen.io/wanghongyang">@wanghongyang</a>) on <a href="http://codepen.io">CodePen</a>.

In this example, a grid frame containing 16 grid items has been build by adding these codes to .container:

.container {
  display: grid;
  height: 100vh;
  grid-gap: 5px;
  grid-template-columns:  1fr 2fr 1fr 2fr;
  grid-template-rows: 1fr 2fr 2fr 1fr;
  /*   grid-template-columns: repeat(2, 1fr 2fr); */
  /*   grid-template-columns: 100px 200px 100px auto; */
  /*   grid-template-columns: repeat(auto-fill, 200px); */
  /*   grid-template-columns: repeat(auto-fill, minmax(200px, auto)); */
}
  • grid-template-columns is set to define columns number and width;
  • grid-template-rows is set to define rows number and height;

CSS grid provides us with several ways to define grid columns and rows:

  • grid-template-columns: 1fr 2fr 1fr 2fr; equals to 4 columns, and the proportion of fractions (fr is a new unit means fraction) is 1:2:1:2. All grids will resize with the window size, but always keep the proportion.
  • grid-template-columns: repeat(2, 1fr 2fr); There are only 4 columns in this example, what if we need 1000 columns? To simplify codes, repeat notation can be utilized. repeat(2, 1fr 2fr) means repeat 1fr 2fr proportion twice, which is the same results with 1fr 2fr 1fr 2fr.
  • grid-template-columns: 100px 200px 100px auto; Apart from fr unit, pixel px unit can also be used. In addition, auto notation can be used to auto-fill the remaining space, so the frist three columns in this case occupy 100px, 200px, 100px respectively and the last column auto-fills the remaining space.
  • grid-template-columns: repeat(auto-fill, 200px); When the first argument is auto-fill instead of specific number in repeat notation, the browser will take the second argument as the break point of reflowing layout. In this case, the first grid item of the second row will auto-fill the white space in the first row once it's wider than 200px.
  • grid-template-columns: repeat(auto-fill, minmax(200px, auto)); In the prior case, when the view width is not an integer multiple of 200px, there will be white spaces in the first row. So how to auto-fill the white space while keeping the break point? Notation minmax can be used to define a range. minmax(200px, 400px) means the length of item can range from 200~400px. When the second argument is set to auto, space less than 200px will be auto-filled.

Open Codepen above and comment/uncomment to see effects.

Put Grid Items into Grid Frame

There are two ways to put items into grid.

Method One

The first way is straight forward: Assign name for each grid item by grid-area and assign each grid mesh with grid item name by grid-template-areas.

See the Pen <a href="https://codepen.io/wanghongyang/pen/WpWppE/">Put items into grid 2</a> by wanghongyang (<a href="http://codepen.io/wanghongyang">@wanghongyang</a>) on <a href="http://codepen.io">CodePen</a>.

In this example, mainly two sections of codes are needed: grid-template-areas in .container and grid-area in .grid-item:

.container {
  display: grid;
  grid-gap: 5px;
  height: 100vh;
  grid-template-columns: 1fr 2fr 1.5fr 1fr;
  grid-template-areas: 
    "sec1 sec2 sec3 sec4"
    "sec5 sec2 sec6 sec6";
}
.grid-item:nth-of-type(1) {
  grid-area: sec1;
}
.grid-item:nth-of-type(2) {
  grid-area: sec2;
}
...

The grid-area property is for the children (grid items) to assign names. Once the names are assigned, grid-template-areas property can be used for parent (grid container) to fill each grid mesh with one name.

Method Two

The second way of putting items into grid is to define grid lines and assign start and end (or span) for grid items.

See the Pen <a href="https://codepen.io/wanghongyang/pen/PpgpGz/">Put items into grid 2</a> by wanghongyang (<a href="http://codepen.io/wanghongyang">@wanghongyang</a>) on <a href="http://codepen.io">CodePen</a>.

In this example, mainly two sections of codes are needed: define grid lines when setting grid-template-columns (or rows) in .container and grid-column-start and grid-column-end (or rows) in .grid-item:

.container {
  display: grid;
  grid-gap: 5px;
  height: 100vh;
  grid-template-columns: 
    [first-column-start] 1fr 
    [first-column-end second-column-start] 2fr 
    [second-column-end third-column-start] 1.5fr 
    [fourth-column-start] 1fr [fourth-column-end];
}

.grid-item:nth-of-type(2) {
  grid-row-end: span 2;
}

.grid-item:nth-of-type(6) {
  grid-column-start: third-column-start; 
/*   grid-column-start: second-column-end; */
/*   grid-column-start: 3; */
  grid-column-end: fourth-column-end;
/*   grid-colum-end: 5; */
  
  /* or simply use shorthand: */
  /*   grid-column: 3 / span 2; */
}

Grid lines are lines between every two grid items, and they can be defined by adding name in []. Then the defined names can be used in children (grid items) grid-column-start and grid-column-end property to specify the start and end of grid items.

  • grid-column-start: third-column-start; and grid-column-start: fourth-column-end; are set for the sixth item to start with the third grid line and end with the fifth grid line, which spans two columns.
  • grid-column-start: 3; and grid-column-end: 5; are the same with the prior one. You can either specify grid-column with grid line name, which is defined by you, or the default value indicating the No. of grid lines.
  • grid-column: 3 / span 2; Short-hand grid-column is more convenient to write. The value before / is the start value and the format after / should be span x to specify how many columns current grid item occupies.
  • grid-column: third-column-start / span 2; It is the same with the prior one.

By harnessing these two methods, you can put certain grid item into any grid mesh of the grid. You can specify the flow direction by adding grid-auto-flow: column; property to grid container and specify the order property for any grid item. Note that no matter where the grid items are, the order of grid items in HTML remain unchanged.

Properties Sheet

Properties for the Grid Container Properties for the Grid Items
display grid-column-start
grid-template-columns grid-column-end
grid-template-rows grid-column
grid-template-areas grid-row-start
grid-template grid-row-end
grid-column-gap grid-row
grid-row-gap grid-area
grid-gap justify-self
justify-items align-self
align-items order
justify-content
align-content
grid-auto-columns
grid-auto-rows
grid-auto-flow
grid

Study Resources

[1] Egghead, Rory Smith, video, Build Complex Layouts with CSS Grid Layout

[2] Grid examples, Rachel Andrew, Grid by Example

[3] CSS Tricks, Chris House, A Complete Guide to Grid

[4] Codepen, Anthony Dugois, CSS Grid Template Builder

[5] Personal Blog, Una, 3 CSS Grid Features That Make My Heart Flutter

[6] Cloudfour, Tyler Sticka, Case Study: My First Practical CSS Grid Layout

[7] Mozilla Hacks, Ali Spivak, A new CSS Grid demo on mozilla.org

[8] Mozilla Developer Network (MDN), Examine grid layouts with the CSS Grid Inspector

[9] CSS Tricks, Chris Coyier, Container Query Discussion

[10] Thomas Park, Game for learning CSS Grid, CSS Grid Garden

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容

  • 往昔身旁常唠叨,甚烦意 如今开门都不应,空叹息 原来相思已入骨,心绪异 盼君早日归来兮,不离弃
    柳若素阅读 167评论 0 0
  • 虽然我国男比女多五千万,单身的主力却是姑娘们。这说明,情人节为什么单身,并不是因为对象难找,而是你不想找。别再说十...
    菜pan阅读 252评论 2 1
  • 事修跟心性的塑造是一体的,心性的铸就是通过生活中去经历事件来完成的,活在当下去觉察事件中没有做好的那部分,还可以去...
    湘羽瑶阅读 184评论 0 0
  • [题记]如果第一天写或者第二天,我可能写成一部血泪史,但是今天是第五天,通过回忆通过大家的分享。我慢慢找到我小时候...