下是来自Oliver Williams的帖子. Oliver已经学习了相当长时间的原生CSS网格,可以说是在CSS网格方面有一定的发言权。在这篇文章中,他将以非同寻常的思路分析自己的CSS网格布局学习之路。我比较赞同他的想法,就是学习一门新技术的时候,把它们拆分成比较小的单元块并配上实例,一步一步的学习。这比直接学习网格布局的所有东西要好太多了。

浏览器原生CSS网格预计会在2017年年初得到支持. 在这之前你需要在浏览器中开启这个实验性的功能 (Firefox实验版默认是开启的). Chrome Canary是当前最好的实现. 同时,火狐有一个非常好的插件叫CSS Grid Inspector, 它能显示出网格的线,它是目前唯一可以在浏览器中运行的此类工具。

在 chrome的地址栏中输入chrome://flags, 找到 ‘实验性网络平台功能’ 并开启它. IE 和 Edge 实现的是一个比较老的网格标准,现在并不受支持。

网格布局不是将零散的块拼到一起

相信我,很快你就能掌握它的.

网格布局只能像左边那样,以矩形的单元块组合起来。并不能像右图那样,由一堆零散的多边形(跟俄罗斯方块那样的块)拼凑。

设计网格布局并不是为了取代弹性盒,相反,它是弹性盒的一种补充

虽然网格布局和弹性盒在某些方面起到相似的作用,而且你可以发现,很多人用弹性盒来实现网格布局,但这并不是设计弹性盒的初衷。Jake Archibald的这篇博文值得一读Don’t use flexbox for overall page layout。

这篇博文大概的意思是:

Flexbox(弹性盒)是为一维布局设计的(行或列)。
CSS网格是为二维设计的.
Rachel Andrews也 说过类似的话:

Flexbox(弹性盒)用于一维布局 – 也就是行或者列. 网格用于二维布局 – 也就是多行多列.
它们可以很好的结合,你可以往弹性容器中放入网格,也可以在网格块中加入flex元素

来看个例子吧。 我们想在一个网格元素(grid item)里垂直居中一段文字, 但我们想要让背景(图片,颜色或渐变)覆盖整个的网格区域。 我们可以使用align-items属性,并把它的值设为center,但是如果这样背景并不会填满整个网格元素的区域。align-items 默认的值是 stretch-你不改变它,始终会填满整个空间的。我们把网格元素设为align-items:center并把网格元素(grid item)设置为一个弹性容器(flex container)。

.grid {
align-items: stretch;
}

.griditem {
display: flex;
align-items: center;
}
给grid-column-end设置负值,意想不到的有用

在小屏幕下,写一个12列的网格,所有格子的跨度都12列。

你可以用网格这样做:

/* For small screens */
.span4, .span6, .spanAll {
grid-column-end: span 12;
}

/* For large screens */
@media (min-width: 650px) {
.span4 {
grid-column-end: span 4;
}
.span6 {
grid-column-end: span 6;
}
}
这样的显示效果是没什么错误的,当使用CSS网格,重新定义列数非常简单。并且你可以通过设置grid-column-end: -1;来让你的页面始终是从左到右贯穿的。

/* For small screens */
.span4, .span6, .spanAll {
grid-column-end: -1;
}
在大屏幕上,你想要尽可能的接近12列,但是在移动端,一行大概是1~4列。用media来改变grid-template-columns是非常容易的。

.grid {
grid-template-columns: 1fr 1fr;
}

@media (min-width: 700px) {
.grid {
grid-template-columns: repeat(12, 1fr);
}
}
有一些元素,我们想让它贯穿整个视口,比如像 header, footer,和一些大图啥的。

对于小屏幕,我们可以这样写:

.wide {
grid-column: 1 / 3; /* start at 1, end at 3 */
}
不幸的是,当我们换到大屏的时候,一行12列,这些元素将仅仅占满前两列,并不会占满12列,我们需要定义新的grid-column-end,并且把他的值设为 13. 这种方式比较麻烦,还有一种简单的方式,grid-column: 1 / -1;,这样不论在什么屏幕尺寸下,它们都是占满整行的了。就像下面这样:

.wide, .hero, .header, .footer {
grid-column: 1 / -1;
}
网格区域可以命名,并使用一些隐含的名字

使用grid-template-areas和grid-line-numbers是两种控制行数的属性,你也可以两个同时用。你可以使用那些隐含的行名去设置你的网格。

.grid {
grid-template-areas: "main main sidebar sidebar";
}
这段代码,我们能得到四个隐含名字,main-start, main-end, sidebar-start, 和 sidebar-end.

这可能很有用,如果你想重叠内容,无论是在几个网格区域或在一个特定分段的网格区域。

定义网格区域的另一种方式

就像给网格的行命名,特殊的行名能用于设置网格区域,语法是这样的:

.grid {
grid-template-areas:
"header header header"
"main main sidebar"
"footer footer footer";
}
如果你的布局设计(太多列的布局!没列都要起名字,可能还需要空元素)中有很多空的区域,这种写法稍微有点麻烦。所以对于网格是有另一种写法的,在这种写法中,名字是什么无所谓,只要你合理利用到[name-start] 和 [name-end],也能达到自己的布局目的。下面是一个例子:

.grid {
display: grid;
grid-template-columns: 20px 100px [main-start] 1fr [main-end] 100px 20px;
grid-template-rows: 100px [main-start] 100px [main-end] 100px;
}

.griditem1 {
background-color: red;
grid-area: main;
}
你可能并不想整个页面都用这种方式布局,但是如果你想要结合 grid-area来确定行数的话,它会非常适合。

相等尺寸网格(equal sized box layout)使用vmin单位

虽然你可以在CSS网格中使用任意尺寸的行或列,但是如果想要相等大小的格子并是响应式的,你就需要使用vmin单位了。

.grid {
grid-template-columns: repeat(5, 20vw);
grid-template-rows: repeat(5, 20vh);
}
这种布局在台式电脑和笔记本上基本都可以完美显示,但是在手机上,高度大于宽,内容将会溢出,产生出一个横向的滚动条。Dudley Storey写了篇blog说这件事the usefulness of a lesser-known css unit: vmin。这种方法,通过调整容器视口的百分比和内容位置,做到适配各种尺寸的屏幕。

.gridcontainer {
display: grid;
width: 100vw;
height: 100vh;
justify-content: center;
align-content: center;
grid-template-columns: repeat(5, 20vmin);
grid-template-rows: repeat(5, 20vmin);
}
绝对定位

当我们绝对定位一个网格元素的时候,这个元素会跑到它的容器中,我们可以用grid-column 和 grid-row来定位它。正常情况下,绝对定位使元素脱离文档流,它最适合的使用场景就是想要让元素重叠,并不打乱其他布局元素。除非你为每个元素声明grid-column-start 和 grid-row-start,要不然即使使用了绝对定位,元素也是不会重叠的。

尝试删除这个例子中div的position: absolute;,思考grid-column 和 grid-row的值,也可以试试修改它们,你就明白是什么意思了。

改变网格元素(grid item)的顺序

如果你使用过弹性盒(flexbox)的order 属性,那你已经知道一些相关的知识了。所有的网格元素都有一个默认的order值0。所以如果给一个网格元素设置 order: 1;,这个元素将在所有元素的后面。 你可以给order属性设置负值,让它跑到所有item的前面。

grid中 minmax()的坑

想不想要整行随着内容的宽度而变宽,直到他们达到最大宽度,这种情况你可能想尝试使用 minmax() :

.grid {
display: grid;
grid-template-columns: repeat(3, minmax(1fr, 300px));
}
不幸的是,像上面这样看似简单,实际上是不行的。如果max小于min的话,css会被忽略。在minmax()中fr不能使用。实际上实现这个需求很容易,在grid-template-columns 或 grid-template-rows中使用auto,这样item就可以随着内容增大而变大了。

我们可以设置一个 max-width:

.grid {
display: grid;
grid-template-columns: repeat(3, auto);
}

.item {
max-width: 300px;
}
minmax()的运行方式和使用我还没有完全想出来,虽然如此,我还是写了一篇文章(译者注:Medium entitled是什么我没有理解清楚,原文:I wrote an entire post on Medium entitled) The One Thing I Hate About Grid.

如果你给每一个网格线命名了的话,写布局将容易的多

有多种办法供你选择,如果你就想多写点,你可以给多行设置多个名字。

.grid {
grid-template-columns: [col1-start] 1fr [col1-end col2-start] 1fr [col2-end];
}
最简单的命名约定使用网格自动编号。不是去写 [col2],而是写为col 2

.griditem1 {
grid-column-start: col 2;
}
和span关键字组合使用,我们就不用去写column-start和column-end中的各种网格线数字了,这样能直观许多。

.grid {
grid-template-columns: repeat(4, [col] 100px);
}

.griditem1 {
grid-column: col 2 / span 2;
}
fr单位为什么那个的重要,让你摆脱麻烦的计算

想象一下一行上四等列这种布局,使用百分比是多么的容易grid-template-columns: 25% 25% 25% 25%。

但是当想用grid-gap属性的时候那?如果设置grid-gap: 10px,金丝阁那么这一行上将有三个空隙,每个10px,整体的宽度就是100% + 30px,大于100%滚动条就出来了。虽然可以通过计算来解决,但是如果使用fr,这太容易了grid-template-columns: 1fr 1fr 1fr 1fr

网格布局中第二个我较恶心的点

没有办法强制自动布局算法留下一些行和列是空的。

grid-gap可以让我们设置内容间的距离。grid-row-gap和grid-column-gap能设置行或列之间的间隙,可是如果我想让第一行和第二行相距10px,第二行和第三行相距50px,用现有的网格是没法实现的,除非建个空行占位。

你可能见到过像下面这样写grid-template-area的:

grid-template-rows:
"header header header"
"main main main"
" . . ."
"secondary secondary secondary"
"footer footer footer";
应该提供一个比较聪明的办法,金丝阁www.jsgren.com让布局算法去做这件事。不幸的是,这样写也没用。此语法简单地表示,我们不想将第三行变成一个命名的网格区域。可是grid-template-rows将仍然在那结束。

一些设计上的建议: 你不一定需要12列网格 (每一列不一定大小一致)

12列网格算是web design的默认配置了。Bootstrap引导大家用12列网格,导致很多框架都是12列网格。12既能被3整除也能被4整除,能让我们有更多种布局摆放方式。1行12列,1行6列,1行4列,1行3列,1行2列

虽然有些人喜欢每一个项目总是使用相同的网格,但是你应该去思考你真正需要的,有时候没有必要有更多的列,你应该建立一个网格,对针对你的内容去布局,而不是一个12列网格到处用。

看看这个例子 Gridset. Gridset是一个制作网格非常有用的工具, 但是原生CSS的网格不需要你使用任何工具,但是可以看看它展示的一些良好的网格设计。

原生 CSS 网格布局学习笔记的更多相关文章

  1. CSS Grid 布局学习笔记

    CSS Grid 布局学习笔记 好久没有写博客了, MDN 上关于 Grid 布局的知识比较零散, 正好根据我这几个月的实践对 CSS Grid 布局做一个总结, 以备查阅. 1. 基础用法 Grid ...

  2. CSS 网格布局学习

    转自:https://blog.jirengu.com/?p=990 CSS网格布局(又名“网格”)是一个二维的基于网格的布局系统,其目的只在于完全改变我们设计基于网格的用户界面的方式. CSS一直用 ...

  3. CSS flex 布局学习笔记

    写在前面 Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性. 任何一个容器都可以指定为 Flex 布局. 采用 Flex 布局的元素 ...

  4. CSS常用布局学习笔记

    水平居中-行内元素 如果是文字和图片这类的行内元素,则在其父级元素上加上样式:text-align:center; 水平居中-定宽块元素 div{ width:100px; margin:0 auto ...

  5. 【图片版】学习CSS网格布局

    简言 CSS网格布局(Grid)是一套二维的页面布局系统,它的出现将完全颠覆页面布局的传统方式.传统的CSS页面布局 一直不够理想.包括table布局.浮动.定位及内联块等方式,从本质上都是Hack的 ...

  6. CSS3与页面布局学习笔记(八)——浏览器兼容性问题与前端性能优化方案

    一.浏览器兼容 1.1.概要 世界上没有任何一个浏览器是一样的,同样的代码在不一样的浏览器上运行就存在兼容性问题.不同浏览器其内核亦不尽相同,相同内核的版本不同,相同版本的内核浏览器品牌不一样,各种运 ...

  7. 从今天开始 每天记录HTML,CSS 部分的学习笔记

    从今天开始 每天记录HTML,CSS 部分的学习笔记

  8. CSS3与页面布局学习笔记(四)——页面布局大全(负边距、双飞翼、多栏、弹性、流式、瀑布流、响应式布局)

    一.负边距与浮动布局 1.1.负边距 所谓的负边距就是margin取负值的情况,如margin:-100px,margin:-100%.当一个元素与另一个元素margin取负值时将拉近距离.常见的功能 ...

  9. css 网格布局

    一.概述 网格布局(Grid)是最强大的 CSS 布局方案. 它将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局.以前,只能通过复杂的 CSS 框架达到的效果,现在浏览器内置了. 上 ...

随机推荐

  1. 详解BOM头以及去掉BOM头的方法

    类似WINDOWS自带的记事本等软件,在保存一个以UTF-8编码的文件时,会在文件开始的地方插入三个不可见的字符(0xEF 0xBB 0xBF,即BOM).它是一串隐藏的字符,用于让记事本等编辑器识别 ...

  2. Kafka到Hdfs的数据Pipeline整理

    作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 找时间总结整理了下数据从Kafka到Hdfs的一些pipeline,如下 1> Kafka ...

  3. [Web API] Web API 2 深入系列(7) Model绑定(下)

    目录 ModelBinder ModelBinderProvider 不同类型的Model绑定 简单类型 复杂类型 其他类型 ModelBinder ModelBinder是Model绑定的核心. p ...

  4. 在Mac上开发使用yeoman构建Asp.net core项目并且实现分层引用

    1.Yeoman? yeoman是一个自动化脚手架工具.它提供很多generator,generator相当于VisualStudio的模板,用来初始化项目.更多的就不多说了,写一遍都写不完,自己看吧 ...

  5. 关于 window.parent, window.top, window.self 详解

    在应用有frameset或者iframe的页面时,parent是父窗口,top是最顶级父窗口(有的窗口中套了好几层frameset或者iframe),self是当前窗口,opener是用open方法打 ...

  6. C++面试题汇集

    1.在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”?答:首先,extern是C/C++语言中表明函数和全局变量作用范围的关键字,该关键字告诉编译器,其声明的函数和变量可以 ...

  7. EC笔记:第二部分:11:在operator=中处理“自我赋值”

    已经一年半没有写过博客了,最近发现学过的知识还是需要整理一下,为知笔记,要开始收费了以前写在为知笔记上笔记也会慢慢的转到博客里. 话不多说,进入正题. 考虑考虑以下场景: 当某个对象对自身赋值时,会出 ...

  8. 疯狂Android讲义 - 学习笔记(七)

    第8章 Android数据存储与IO  Java IO的数据存储可以移植到Android应用开发上来,Android系统还提供了一些专门的IO API. Android系统内置了SQLite数据库,S ...

  9. c# json序列化 意外字符i 意外字符ï 解决方案

    今天使用DataContractJsonSerializer遇到了这个问题 这是个蛋疼的问题,折腾了我好久,反复检查对象和json字符串,没发现什么问题,而且错误提示还看走眼了,是ï不是i 现公布解决 ...

  10. Nginx配置文件详解

    Nginx是一款面向性能设计的HTTP服务器,相较于Apache.lighttpd具有占有内存少,稳定性高等优势. ######Nginx配置文件nginx.conf中文详解##### #定义Ngin ...