澳门新萄京官方网站-www.8455.com-澳门新萄京赌场网址

澳门新萄京官方网站:布局入门,Grid中的陷阱和

2019-11-16 作者:澳门新萄京赌场网址   |   浏览(107)

CSS Grid中的陷阱和绊脚石

2018/04/02 · CSS · Grid

原文出处: Rachel Andrew   译文出处:大漠   

2017年3月,CSS Grid在几个星期内就被发送到Chrome、Firefox和Safari的生产版本中。很高兴,大家可以使用它来解决实际问题。

CSS Grid是一种不同的布局方式,在大家开始使用规范的时候,有很多常见的问题。这篇文章的目的是回答其中的一些问题,并且将会是Smashing Magazine中有关于CSS Grid一系列文章中的一篇。

简介

CSS Grid布局 (又名"网格"),是一个基于二维网格布局的系统,旨在改变我们基于网格设计的用户界面方式。正如我们所知,CSS 总是用于布局我们的网页,但它并没有做的很好。刚开始的时候我们使用表格(table),然后使用浮动(float)、 定位(position)和内联块(inline-block),但所有这些方法本质上来讲都是hacks,并留下了很多需要实现的重要功能问题(例如垂直居中),虽然Flexbox可以起到一定的补救作用,但是旨在用于更简单的一维布局,并不适用于复杂的二维布局(实际上 Flexbox 和 Grid 可以一起结合使用起到最佳效果)。网格(Grid)是第一个专门为解决布局问题而创建的CSS模块,用来解决我们之前在制作网站时使用hacks处理布局问题。
这里有两件事情启发我创建本指南。第一个是 Rachel Andrew 的令人敬畏的书--为 CSS Grid 布局做好准备。这本书很详尽明确的的介绍了Grid,是整篇文章的基础。我强烈鼓励你买它,读它。另外一个很大的灵感来自于 Chris Coyier 的-- Flexbox完整指南,这本书是我了解Flebox的一个很优秀的资源。它帮助了很多人,这是事实,这里,我还想补充一句,当你使用谷歌搜索"flexbox"时,会出现很多类似的资源,但是为什么不直接利用最好的资源呢?
我书写此指南的目的是基于目前最新规范的版本,规范其网格概念。所以我不会再次提及过时的 IE 语法,并且随着规范的成熟,我会尽我们所能定期更新此指南。

  • DEMO 地址:【传送门】
  • 示例下载地址: 【传送门】
  • 原文地址:Getting to know CSS Grid Layout
  • 原文作者:Chris Wright
  • 译者:华翔
  • 校对者:珂珂、干干

近几年,Flexbox的出现,带来了巨大的轰动效应,它使CSS变得更加强大,给我们带来了更大的施展空间,并在几乎所有的浏览器中都得到了很好地支持,你没有理由不使用它。我们发现Flexbox在很多情况下对我们非常有帮助,但是它绝对不是一个构建整个布局的理想候选方案。我们更倾向于使用浮动或者内联元素来构建整体布局,但是这并不是浮动、内联元素被创建出来的初衷。但很遗憾CSS从来没有一个这样的内置功能,为了建立布局,我们没有选择,只能用这些Hack。好消息是CSS Grid Layout Model 是一个转折点,我们可以用它的一些基础功能就可以重建一些标准布局。目前,浏览器对网格布局的支持情况还不是很理想。唯一支持它的浏览器是Edage和最新的Internet Explorer 。幸运的是,我们可以在Google Chrome,FireFox ,Safari 上手动启用该功能,在Chrome上我们在导航栏输入chrome://flags切换到“启用实验性Web平台”标识并重启浏览器,FireFox上我们在导航栏输入about:config, 搜索 layout.css.grid.enabled 设置为true,Safari上我们需要下载 Safari Technology Preview 版本的浏览器,就可以使得浏览器支持网格布局。

为什么使用CSS Grid而不是CSS Flexbox?

在CSS网格布局在浏览器中可用之前,很多人都认为Flexbox是我们所有设计相关问题的答案。然而,Flexbox并没有提供比浮动更好的网格系统,尽管它确实比浮动创建一个网格系统更简单。一个真正的网格是二维的。这两个维度就是行和列,并且使用网格布局,你可以同时控制它们。使用Flexbox,你可以选择是否将这些项列成一行或列,一个或另一个,而不是两个。

这里有一个简单的示例,突出其区别。第一个布局使用Flexbox,为了能尽可能多的使用盒子,以适合可用的宽度。这里我们控制了整个行中的布局。允许Flex项目进行包裹,因此会创建新的行,但是每一行都是一个新的Flex容器。空间分布在行中发生,所以取决于最后一行多少项,它们有时不会与上面的Flex项对齐。DEMO1

第二个示例使用CSS Grid实现相同的布局,但是,你可以看到,最后一行中的项目始终保持在它们的列中。这是因为在网格中,我们将项目排列成行和列 —— 二维布局。

 DEMO2

你还可以在第二个示例中看到,在CSS Grid布局中,我们不需要向网格添加任何内容来进行布局。所有东西都被放在容器上。在Flexbox布局中,你必须针对Flex项目来设置flex-growflex-shrinkflex-basis属性。这是理解网格布局关键所在,也可能是大家有很多困惑的地方。Grid主要是关于包含元素的,而我们之前的所有布局方法都依赖于我们在布局中设置的宽度,使某些东西看起来像一个网格。

如果你使用一个简化版本的浮动12列“网格”,我们必须计算每一列的百分比大小,加上每个列之间间距的百分比大小。要创建跨多个列的项,需要将所有项的宽度加上用于分隔它们的边界宽度。DEMO3

使用Flexbox创建的网格也是如此。当我们在父节点上通过display:flex创建Flex布局时,Flex所有的大小都需要在单个Flex项目上进行。为了制作一个Flexbox的“网格”,我们必须阻止Flexbox做灵活的操作,而是应该设置百分比宽度,就像我们前面的浮动网格示例一样。使用Flexbox要比浮动更有一些优势,比如控制对齐和列等高之类的要简易得多。然而,在Flexbox和浮动的方法中仍然没有网格,只是通过设置项目的大小,并将它们排列起来,让其看起来像网格的东西。DEMO4

在网格中,所有的大小都发生在容器上。一旦我们创建了我们的网格轨道,我们就可以告诉单个项目(Grid项目)有多少个轨道可以跨越,但我们却有一个实际的网格。我们可以完全抛弃行的容器,因为网格已经有行了。这也意味着,我们也可以使用相同的方式进行跨列。这对于以前而言是件很难做的事情。

 DEMO5

基础知识与浏览器支持

Grid 的入门是很容易的。你只需要定义一个容器元素并设置display:grid,使用grid-template-columnsgrid-template-rows属性设置网格的列与行的大小,然后使用grid-columngrid-row属性将其子元素放入网格之中。与flexbox类似,网格项的源顺序并不重要。你的CSS可以按任何顺序放置,这使得你很容易重新布局网格与媒体查询。想象一下你定义的整个页面布局,然后如果想要完全重新布局以适应不同的屏幕宽度,这时仅仅使用几行 CSS 代码就可以实现。Grid是有史以来最强大 CSS 模块之一。
关于 Grid 一件很重要的事情就是它现在还不适用于项目使用。目前还处于 W3C 的工作草案之中,并且默认情况下,还不被所有的浏览器正确支持。Internet Explorer 10 和 11 已经可以实现支持,但也是利用一种过时的语法实现的。现在出于示例演示,我建议你使用启用了特殊标志的 Chrome, Opera 或者 Firefox 。在 Chrome,导航到chrome://flags并启用" web 实验平台功能"。该方法同样适用于 Opera (opera://flags)。在Firefox中,启用 layout.css.grid.enabled标志。
这里有一张浏览器支持情况的表格(之后我会继续更新):

澳门新萄京官方网站 1

CSS Grid Layout

除了Microsoft,浏览器厂商似乎想要等到Grid规范完全成熟后再加以推广。这是一件好事,因为这意味着我们就不需要担心学习多个语法。
这只是时间问题,你可以在生产环境中使用Grid。但是现在你需要开始学习它了。


翻译 | CSS网格(CSS Grid)布局入门

澳门新萄京官方网站 2

banner

CSS网格布局是浏览器Flexbox布局之后最重要的布局方式。我们可以忘记过去15年经常使用的的各种“神奇数字”,hacks和一系列变通布局方案。网格布局提供了非常简单的声明布局方式,之后再也不需要借助一些常见的主流css框架,也能减少很多手动实现的布局方式

如果你以前不熟悉CSS网格布局,那么你可以开始了解它了。它是一种适用于容器元素,并能指定子元素的间距、大小和对齐方式的布局工具。

CSS网格布局赋予我们更强大的能力——大家熟悉的水平垂直居中布局,不需要增加标签就能做到。同样,这也能让我们不需要媒体查询就能根据可用空间自动适应。

澳门新萄京官方网站 3

是否应该将网格用于主布局和Flexbox用于组件布局

随着大家开始接触和学习CSS Grid的布局,这个神话不断涌现。也许它来自于网格系统的使用,比如在Bootstrap或Foundation,大家关心的是一个整体网格上放置项目。这当然是使用网格布局的一种方法。不过,我还是会考虑在上一节提到的不同之处。问问你自己,这个布局是一维的还是二维的?

如果你可以使用你的组件,并且用行和列在它的上面绘制一个网格。它是二维的,那就使用CSS Grid来布局。澳门新萄京官方网站 4

如果相反,你希望单个项目在一行中进行扩展,而不考虑上面一行中发生的情况,那就应该使用Flexbox布局更为合适。

澳门新萄京官方网站 5

不管你想要展示的是一个完整的页面,还是一个很小的组件。重要的是你想在布局里面的项目分配空间和相互关联。

重要术语

在深入研究网格的概念之前,我们需要理解其相关术语概念。 因为这里所涉及的术语在概念上都有点类似,如果你不首先记住Grid规范定义,你就会很容易将其与其他概念相混淆。 但是不需要担心,这里的属性并没有很多。

不久以前,所有 HTML 页面的布局还都是通过 tables、floats 以及其他的 CSS 属性来完成的。面对复杂页面的布局,却没有很好的办法。

学习的最低要求

首先网格布局有不少新语法需要学习,但是你只需要稍微看下就能上手。本文将会用示例带你学习CSS网格布局各种各样重要的入门概念。

当前浏览器兼容性

网格轨道大小是否由内容来决定?

我们已经看到了如何在使用网格布局时,在容器上设置网格和网格大小。但是,网格中的项可以指定网格轨道大小。这里要记住的关键是,一个单元格大小的改变将会改变整个轨道的大小。如果你不希望这种情况发生,你可能需要一个单一维度的Flexbox布局。

最简单的方法就是使用auto,因为它会默认在隐式网格中创建网格轨道。一个自动大小的网格轨道将扩展到包含所有的内容。在下面的示例中,我有一个两列布局,在右边的列中添加更多的内容会导致整个行的扩展。第二行也是自动大小,再扩展以包含内容。

 DEMO6

我们可以使用两个参数来控制网格轨道大小,例如创建一个最小的网格轨道,但其仍然会增长以适应较大的网格项目。我们可以使用minmax()函数来做这个。传给minmax()函数的第一个值,它是网格轨道最小的值,第二个值是网格轨道最大的值。因此,你可以设置200px的行,但通过auto设置为网格轨道最大值,那么当有较多的内容时,不会出现内容溢出。

DEMO7

也有一些有趣的关键词可以设置大小,将在以后的文章中对它们进行适当的阐述。这些关键词在指定网格中允许内容来改变网格轨道大小,并且可以在CSS内部和外部的大小模块(CSS Intrinsic and Extrinsic Sizing Module)中找到相关的详细内容。例如min-content关键词的示例,使用它创建一个网格轨道时,将会创建尽可能小的网格轨道。

在我的例子中,这个词意味着其成为最宽的东西,网格轨首缩小以适应它。

 DEMO8

相反,如果你使用的是max-content,你会得到一个尽可能大的网格轨道。这可能会导致溢出情况,在下面的示例中,使用了overflow: scroll设置了网格溢出,所以max-content的网格轨道会导致滚动条出现。

DEMO9

关键要记住的是,这将会发生在整个网格轨道上。你需要确保网格轨道的其他网格项目也能巧妙地吸收额外的空间。

了解了如何对网格轨道大小进行调整,以及内容将如何改变网格轨道大小,这可能是新手使用CSS Grid布局中会感到最为困惑的事情之一。这需要花一点时间来理解 —— 我们之前没有任何类似的行为。这是理解事物如何运作的最好方法。

网格容器(Grid Container)

当一个元素的属性设置为display:grid时, 它是所有网格项(Grid Items)的直接父元素。 在下面示例中container就是网格容器。
HTML:

<div class="container">
  <div class="item item-1"></div>
  <div class="item item-2"></div>
  <div class="item item-3"></div>
</div>

然而Flexbox的出现,便轻松的解决了复杂的 Web 布局。它是一种专注于创建稳定的响应式页面的布局模式,并可以轻松地正确对齐元素及其内容。如今已是大多数 Web 开发人员首选的 CSS 布局方式。

浏览器兼容性

CSS网格布局从Safari 10.1, Firefox 52, Opera 44, Chrome 57开始收到支持,微软Edge在Edge 15会更新对网格布局的支持。

微软的浏览器(IE10–11和Edge 13-14)有一种比较旧的实现,所以有不少限制,我们会简单介绍新的实现方式和老的实现方式之间的区别,这样你能知道如何规避他们。

对于大多数布局,我们会使用下面的query特性来让老的浏览器对他们理解的特性也能工作:

@supports (display: grid) {
    .grid {
        display: grid;
    }
}

不支持浏览器@supports或网格的浏览器将不会生效。

为了能正确展示文中的示例,你需要使用支持网格布局的浏览器。

澳门新萄京官方网站 6

可以使用CSS Grid来实现瀑布流布局?

很多同学有一种误解,认为网格布局与瀑布流或Pinterest布局一样的。这通常是基于在网格布局中自动放置网格项目,这样的效果看上去的确有点像瀑布流布局。在下一个示例中,我有一个布局,使用grid-auto-flow设置为dense,实现网格项目自动流的布局。这将导致网格项目从源程序中取出,并尝试在网格填充空白区域。DEMO10

然而这并不是真正的瀑布流布局,因为我们仍然有一个网格(具有行和列),并且潜在的网格项目从源代码中移出。一个真正的瀑布流布局将使事物在源代码中工作。项目被推上去填充部分空间。它更像是在两个维度上做Flexbox布局。

澳门新萄京官方网站 7

你可以通过对所有的Grid项目进行定位处理来得到一个瀑布流外观的网格布局,但是自动流的瀑布流布局,网格布局还无法具备这方面的能力。不过,未来的规范正在做这方面的考虑。

网格项(Grid Item)

网格容器的子节点(例如直接后代)。这里 item元素都是网格项,但是sub-item不包含其中。
HTML:

<div class="container">
  <div class="item"></div> 
  <div class="item">
    <p class="sub-item"></p>
  </div>
  <div class="item"></div>
</div>

现在,又出现了一个构建 HTML 最佳布局体系的新竞争者。(冠军头衔正在争夺中…)它就是强大的CSS Grid布局。直到本月月底,它也将在Firefox 52和Chrome 57上得到原生支持,相信不久也会得到其他浏览器兼容性的支持。

创建带有间距(gutter)的两列(column)网格

为了演示CSS网格布局如何定义列,我们从下面的布局开始:

澳门新萄京官方网站 8

grid-template-columns 和 grid-gap

[使用grid-template-columns 和 grid-gap创建带间距的两列布局]

为了创建上述网格布局,我们需要使用grid-template-columnsgrid-gap
grid-template-columns表示网格中的列是如何布局的,它的值是一连串以空格分割的的值,这些值标识每列的大小,值的个数表示列的数目。

例如,四列250px宽度的网格布局可以这样表示:

grid-template-columns: 250px 250px 250px 250px;

也可以使用repeat关键字表示:

grid-template-columns: repeat(4, 250px);

Chrome启用实验性Web平台

如何向网格区域添加背景和边框?

一个网格尚未完成的问题,网格区域本身的背景和边框的样式。能在网格区域上直接添加背景和边框的样式吗?到目前是不可能的,如果要实现这样的一个效果需要插入一个元素或者添加一个伪元素来完成。

下面的这个示例中,我在网格中通过伪元素来完成,将其放置在基于行的位置,然后添加一个背景和边框到该网格区域。DEMO11

有时候可以绕过背景和边框来实现,比如通过网格间距(grid-gap) —— 用一个1px来模拟背景或边框,比如下面的这个示例:

 DEMO12

为了能够对网格区域进行适当的样式化,我们需要引入网格区域伪元素的概念,这是一种特殊的生成内容。在 CSS WG上有一个关于这方面的问题,所以你可以在这里参加讨论,把你的想法与大家一起参与讨论。

网格线(Gird Line)

分界线构成了网格的结构。它们可以是垂直的("列网格线")也可以是水平的("行网格线"),并且位于一行或一列的任一侧。下面图片中的黄线就是列网格线的示例。

澳门新萄京官方网站 9

列网格线

基本布局测试

要了解这两个体系构建布局的方式,我们将通过相同的 HTML 页面,利用不同的布局方式 (即 Flexbox 与 CSS Grid)为大家区分。

同时,你也可以通过文章顶部附近的下载按钮,下载演示项目进行对比,或者通过在线演示来察看它们:

简版静态页面布局

该页面的设计相对比较简单 – 它是由一个居中的容器组成,在其内部则包含了标头、主要内容部分、侧边栏和页脚。接下来,我们要完成同时保持 CSS 和 HTML 尽可能整洁的挑战事项:

  1. 在布局中将四个主要的部分进行定位。
  2. 将页面变为响应式页面;
  3. 对齐标头:导航朝左对齐,按钮向右对齐。

如你所见,为了便于比较,我们将所有事项从简处理。那么,让我们从第一个挑战事项开始吧!

定义间距

grid-gap定义了网格布局的间距大小,接收一个或两个值,如果定义两个值则表示列(column)和行(row)的间距大小。

在两列布局示例中,我们可以如下使用:

.grid {
  display: grid;
  grid-template-columns: 50vw 50vw;
  grid-gap: 1rem;
}

不幸的是,这个间距将会占用容器元素的整体宽度,计算出来就是100vw 1rem,最终这个布局会导致出现水平滚动条。

澳门新萄京官方网站 10

viewport导致的水平滚动条

[通过viewport单位创建带间距网格导致的水平滚动条]

为了解决这个空间溢出问题,我们需要些不同的方法来处理,需要用分数单位或者说是FR

澳门新萄京官方网站 11

跨越到网格的末端

网格布局具有隐式和显式网格的概念。显式网格是我们使用grid-template-rowsgrid-template-columns定义的网格。这个网格轨道定义了显式网格的范围。当我们在显式网格之外放置一个网格项目,或者我们通过自动旋转更多的网格项目时,隐式网格就将被创建。

除非你使用grid-auto-rowsgrid-auto-columns创建的网格轨道,否则在隐式网格中创建的网格轨道的大小将是自动的。

在很多情况下,隐式和显式网格的渲染行为是相同的,对于很多的布局,你会发现你定义了列,然后允许将行创建为隐式网格。不同的是,当你开始使用负的行号来引用网格的最后一行时,你会发现还是有一定区别的。

对于网格布局中的写作模式。在从左到右的语言(ltr)中,列第一行是在左边,而你可以用-1来指向右边的列。在从右到左的语言(rtl)中,列的第一行在右侧,而-1则指向左边的列。

 DEMO13

或许你已经发现了,只有显式的网格才可以向后计数。如果你在隐式网格中添加了行,然后尝试以-1来指定目标,你将会发现你得到是显式网格的最后网格线,而不是实际网格最末端的网格线。

DEMO14

网格轨道(Grid Track)

两个相邻网格线之间的空间。你可以把它们想象成网格的列或行。下图所示的是第二行和第三行网格线之间的网格轨道。

澳门新萄京官方网站 12

网格轨道

挑战 1:定位页面部分

Flexbox 解决方案

我们将从 Flexbox 解决方案开始。我们将为容器添加display: flex来指定为 Flex 布局,并指定子元素的垂直方向。

.container {
    display: flex;
    flex-direction: column;
}

现在我们需要使主要内容部分和侧边栏彼此相邻。由于 Flex 容器通常是单向的,所以我们需要添加一个包装器元素。

<header></header>
<div class="main-and-sidebar-wrapper">
    <section class="main"></section>
    <aside class="sidebar"></aside>
</div>
<footer></footer>

然后,我们给包装器在反向添加display: flexflex-direction属性。

.main-and-sidebar-wrapper {
    display: flex;
    flex-direction: row;
}

最后一步,我们将设置主要内容部分与侧边栏的大小。通过 Flex 实现后,主要内容部分会比侧边栏大三倍。

.main {
    flex: 3;
    margin-right: 60px;
}
.sidebar {
   flex: 1;
}

如你所见,Flex 将其很好的实现了出来,但是仍需要相当多的 CSS 属性,并借助了额外的 HTML 元素。那么,让我们看看 CSS Grid 如何实现的。

CSS Grid 解决方案

针对本项目,有几种不同的 CSS Grid 解决方法,但是我们将使用网格模板区域语法来实现,因为它似乎最适合我们要完成的工作。

首先,我们将定义四个网格区域,所有的页面各一个:

<header></header>
<!-- Notice there isn't a wrapper this time -->
<section class="main"></section>
<aside class="sidebar"></aside>
<footer></footer>

header {
    grid-area: header;
}
.main {
    grid-area: main;
}
.sidebar {
    grid-area: sidebar;
}
footer {
    grid-area: footer;
}

然后,我们会设置网格并分配每个区域的位置。初次接触 Grid 布局的朋友,可能感觉以下的代码会有些复杂,但当你了解了网格体系,就很容易掌握了。

.container {
    display: grid;

    /*  Define the size and number of columns in our grid. 
    The fr unit works similar to flex:
    fr columns will share the free space in the row in proportion to their value.
    We will have 2 columns - the first will be 3x the size of the second.  */
    grid-template-columns: 3fr 1fr;

    /*  Assign the grid areas we did earlier to specific places on the grid. 
        First row is all header.
        Second row is shared between main and sidebar.
        Last row is all footer.  */
    grid-template-areas: 
        "header header"
        "main sidebar"
        "footer footer";

    /*  The gutters between each grid cell will be 60 pixels. */
    grid-gap: 60px;
}

就是这样! 我们现在将遵循上述结构进行布局,甚至不需要我们处理任何的 margins 或 paddings 。

分数单位

分数单位标识占用可用空间的份额,如果900px是可用空间,其中的一个元素占有1份,另外的元素占有2份——那么第一个元素的宽度会是900px的1/3,另外的元素是900px的2/3。
修改后用分数代替view-port单位的新代码如下:

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-gap: 1rem;
}

FireFox上开启网格布局

百分比的问题

在文章开头之处,我描述了网格布局与之前的布局方法与众不同之处。由于浮动和基于Flexbox的网格的限制,我们需要变得擅长计算百分比来做布局,所以大多数人做的第一件事就是尝试在他们的网格布局中使用相同的方法。然而,在这样做之前不要忘记我们有一个新单位fr。这个单位是专门为网格布局设计的,因为网格设置父元素的大小。

fr单位允许我们分配可用网格布局中的可用空间。其通过查看网格容器中可用的空间(去掉间距所需的空间、固定宽度的网格项目或定义网格轨道),然后按照我们为网格轨道指定的比例来对剩余的网格空间进行分配。这意味着,我们使用浮动或Flexbox布局的场景,必须有灵活的间距。

 DEMO15

在大多数情况下,fr单位是一个比百分比更好的选择。你可能选择使用百分比的原因是你需要一个网格布局,以便与其他元素匹配使用其他布局方法,并依赖于百分比大小。然而,如果不是这样的话,看看fr单位是否能满足你的需求,然后对其进行计算。

网格单元格(Grid Cell)

两个相邻的行和两个相邻的列之间的网格线空间。它是网格的一个"单位"。下面图片所示的是行网格线line 1
line 2与列网格线line 2line 3之间的网格单元格。

澳门新萄京官方网站 13

网格轨道

挑战 2:将页面变为响应式页面

Flexbox 解决方案

这一步的执行与上一步密切相关。对于 Flexbox 解决方案,我们将更改包装器的flex-direction属性,并调整一些 margins。

@media (max-width: 600px) {
    .main-and-sidebar-wrapper {
        flex-direction: column;
    }

    .main {
        margin-right: 0;
        margin-bottom: 60px;
    }
}

由于网页比较简单,所以我们在媒体查询上不需要太多的重写。但是,如果遇见更为复杂的布局,那么将会重新的定义相当多的内容。

CSS Grid 解决方案

由于我们已经定义了网格区域,所以我们只需要在媒体查询中重新排序它们。 我们可以使用相同的列设置。

@media (max-width: 600px) {
    .container {
    /*  Realign the grid areas for a mobile layout. */
        grid-template-areas: 
            "header header"
            "main main"
            "sidebar sidebar"
            "footer footer";
    }
}

或者,我们可以从头开始重新定义整个布局。

@media (max-width: 600px) {
    .container {
        /*  Redefine the grid into a single column layout. */
        grid-template-columns: 1fr;
        grid-template-areas: 
            "header"
            "main"
            "sidebar"
            "footer";
    }
}

内容对齐

为了对齐示例中的内容,我们在子元素上使用grid布局,并加上对齐属性来定位他们到指定轨道(track),轨道就是一个网格的列或行的某个位置的常见的名称。网格跟Flex布局一样,有一系列对齐的属性——共有四种值——start, center, end, 和stretch,分别对应其子元素所在的轨道。stretch跟其他不太一样,它会将元素从所在轨道的头拉伸到尾。

澳门新萄京官方网站 14

align-items 和 justify-content

[align-items 和 justify-content]

例子中我们要将内容水平和垂直居中,可以通过在容器上设置下面这些属性:

.center-content {
    display: grid;
    align-items: center;
    justify-content: center;
}

示例地址

澳门新萄京官方网站 15

网格可以嵌套使用?

网格项目也可以成为网格容器,就好比Flex项目也可以成为一个Flex容器一样。但是,这些嵌套网格也父网格没有任何关系,因此不能使用它们与其他嵌套网格对齐内部元素。DEMO16

在将来的网格布局中,很可能会有一种创建嵌套网格的方法,它可以维护与父网格的关系。这意味着,除了网格的直接子节点,其他网格项目可能参与整个网格布局。

网格区域(Grid Area)

网格区域为四条网格线所包围的总空间。 网格区域可以由任何数量的网格单元组成。下面图片所示的是行网格线line 1line3和列网格线line 1line 3之间的网格区域。

澳门新萄京官方网站 16

网格区域

挑战 3:对齐标头组件

Flexbox 解决方案

我们的标头包含了导航和一个按钮的相关链接。我们希望导航朝左对齐,按钮向右对齐。而导航中的链接务必正确对齐,且彼此相邻。

<header>
    <nav>
        <li><a href="#"><h1>Logo</h1></a></li>
        <li><a href="#">Link</a></li>
        <li><a href="#">Link</a></li>
    </nav>
    <button>Button</button>
</header>

我们曾在一篇较早的文章中使用 Flexbox 做了类似的布局:响应式标头最简单的制作方法。这个技术很简单:

header {
    display: flex;
    justify-content: space-between;
}

现在导航列表和按钮已正确对齐。下来我们将使<nav>内的 items 进行水平移动。这里最简单的方法就是使用display:inline-block属性,但目前我们需要使用一个 Flexbox 解决方案:

header nav {
    display: flex;
    align-items: baseline;
}

仅两行代码就搞定了! 还不错吧。接下来让我们看看如何使用 CSS Grid 解决它。

CSS Grid 解决方案

为了拆分导航和按钮,我们要为标头定义display: grid属性,并设置一个 2 列的网格。同时,我们还需要两行额外的 CSS 代码,将它们定位在相应的边界上。

header{
    display: grid;
    grid-template-columns: 1fr 1fr;
}
header nav {
    justify-self: start;
}
header button {
    justify-self: end;
}

至于导航中的内链 - 这是我们使用 CSS grid 最好的布局展示:

虽然链接为内链形式,但它们不能正确的对齐。由于 CSS grid 不具备基线选项(不像 Flexbox 具备的align-items属性),所以我们只能再定义一个子网格。

header nav {
    display: grid;
    grid-template-columns: auto 1fr 1fr;
    align-items: end; 
}

CSS grid 在此步骤中,存在一些明显的布局上的缺陷。但你也不必过于惊讶。因为它的目标是对齐容器,而不是内部的内容。所以,用它来处理收尾工作,或许不是很好的选择哦。

使用旧的网格布局实现两栏布局

如果使用旧的网格布局方式创建,我们需要考虑实现中的诸多限制。旧的布局方式不仅没有grid-gap,而且你需要在每一个网格元素上声明网格元素的起始位置,否则默认会设置为1,这样所有的网格都会堆在第一列。

旧版本的布局方式需要通过增加间距作为网格轨道的一部分,也需要设置每个网格从哪里开始:

.grid-legacy {
   display: -ms-grid;
   -ms-grid-columns: 1fr 1rem 1fr; // 取代 gap 间距
}
.grid-legacy:first-child {
   -ms-grid-column: 1;
}
.grid-legacy:last-child {
    -ms-grid-column: 3;
}

FireFox上开启网格布局

网格布局有对应的Polyfill吗?

我经常会被问到是否有网格布局的Polyfill,大家都想知道是否有一种方法可以支持旧的浏览器。

我的建议是,这并不是你需要做的事情。这可能会为那些已经在努力渲染现代网站的浏览器造成一定的性能影响,带来不好的用户体验。如果你南非要较旧的浏览器与现代浏览器相同,那么你可能要考虑在这个项目中是否使用网格布局。不过,在大多数情况下,可以使用较老的方法来为不支持的设备创建一个简单的降级处理,而不需要创建两个完全不同的CSS代码。这方面真的需要用一篇文章来详细阐述,所以我将尽快在Smashing Magazine发布这方面的教程。

网格属性目录(Grid Properties Table of Contents)

网格容器属性 网格项目属性
display grid-column-start
grid-template-columns grid-column-end
grid-template-rows grid-row-start
grid-template-areas grid-row-end
grid-column-gap grid-column
grid-row-gap grid-row
grid-gap grid-area
justify-items justify-self
align-items align-self
justify-content
align-content
grid-auto-columns
grid-auto-rows
grid-auto-flow
grid

结论

如果你已经浏览完整篇文章,那么结论不会让你感到意外。事实上,并不存在最好的布局方式。Flexbox 和 CSS grid 是两种不同的布局形式,我们应该根据具体的场景将它们搭配使用,而不是相互替代。

对于那些跳过文章只想看结论的朋友(不用担心,我们也这样做),这里是通过实例比较后的总结:

  1. CSS grids 适用于布局大画面。它们使页面的布局变得非常容易,甚至可以处理一些不规则和非对称的设计。
  2. Flexbox 非常适合对齐元素内的内容。你可以使用 Flex 来定位设计上一些较小的细节。
  3. 2D 布局适合使用 CSS grids(行与列)。
  4. Flexbox 适用于单一维度的布局(行或列)。
  5. 共同学习并使用它们。

感谢你的阅读。若你有所收获,欢迎点赞与分享。

注:

  1. 本文版权归原作者所有,仅用于学习与交流。
  2. 如需转载译文,烦请按下方注明出处信息,谢谢!

英文原文:CSS Grid VS Flexbox: A Practical Comparison
作者:Danny Markov
译者:IT程序狮
译文地址:http://www.jianshu.com/p/6262c3e48443

旧的布局方式实现对齐和全高度

旧的布局方式跟IE 11中Flexbox有一样的问题,在容器上设置最小高度(min-height)不一定会生效。这个问题通过网格布局来解决更方便。

为了实现这个效果我们在父容器的行属性上使用minmax方法,minmax指定了行或列的最大和最小值。

-ms-grid-rows: minmax(100vh, 1fr);

在子元素上我们声明一个单位为1fr的单列单行的网格:

.ms-cell {
   -ms-grid-columns: 1fr;
   -ms-grid-rows: 1fr;
}

最后,因为我们不能像Flexbox或最新网格布局那样根据父元素对齐,我们必须使用元素自身的对齐方式来对齐:

.ms-align-center {
    -ms-grid-column: 1;
    -ms-grid-column-align: center; // 新型grid布局中的 align-self
    -ms-grid-row-align: center; // 新型grid布局中的 justify-self
}

旧的两列布局示例

到此我们实现了如何创建列、实现间距、内容对齐及对旧的网格布局的支持。接下来让我们实验下如何通过grid实现内边距。

博客布局的重新设计

博客的布局是我们比较熟知的常用布局之一,有页眉(header),内容(content),侧边栏(sidebar),和页尾(footer)组成。我们接下来就围绕博客布局去介绍网格布局的基本概念。

澳门新萄京官方网站 17

博客布局

调试网格布局

当你开始使用网格布局时,你肯定希望能看到你的网格和其网格项目是如何布局的。我建议你使用Firefox Nightly,并在Firefox 浏览器开发者工具中使用网格检查器。如果你选择一个网格,可以点击这个小网格图标 —— 我喜欢把它想像成一个华夫饼(Waffle) —— 来显示网格。

澳门新萄京官方网站 18

Firefox已经在这方面做得很好了,而且Chrome也在着手在Chrome开发者工具中实现这方面的功能。

有关于在Firefox浏览器中怎么使用网格检查器来调试网格布局,可以阅读以前翻译的一篇文章《使用Firefox 网格检查器调试 CSS网格布局》。

网格容器的属性(Properties for the Grid Container)

通过CSS网格实现内边距(Negative Space)

网格布局允许你通过grid-column-start属性指定列开始的位置,所以就有了可以在网格内创建内边距的可能性。

澳门新萄京官方网站 19

使用grid-template-columns和grid-column-start创建内边距

[使用grid-template-columns和grid-column-start创建内边距]

创建内边距的一种方式是在列的实际位置上设置一个数字,空出网格元素的原始空间, 网格元素也会被push到新的网格列。

澳门新萄京官方网站 20

grid-column-start push

[随着grid-column-start push 第一项]

在上面的内边距示例中,html结构中用一个div包裹另外一个div:

<div class="grid">
    <div class="child"><!-- 内容 --></div>
</div

网格像这样设置:

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

为了让子元素从右侧开始,我们设置子元素从第2列开始:

.child {
    grid-column-start: 2;
}

注意:在Firefox 52中的一个差异导致一个垂直对齐问题——基于FR单位的行不会拉伸得跟整个窗口一样高。为了解决(address)这个问题我们设置子元素为网格项,并给每一行设置一个想要的高度:

.l-grid--full-height {
    grid-template-rows: minmax(100vh, 1fr);
}

设置内边距示例

网格布局术语

  • 网格容器
  • 网格线
  • 网格轨道
  • 网格单元格
  • 网格区域

这对于我们所有人来说仍然是新东西

我很了解CSS网格规范,但是我从3月份就开始使用它了,就像其他人一样。当我们从创建小示例开始,也可以说真正的在生产中开始推动Grid相关的规范,我们将开始寻找使用网格的新方法,当然还有新问题要解决!我很乐意看到你自己编写的有关于网格相关的案例。在接下来的几个月的时间里,我还将在Smashing Magazine中深入探讨网格布局相关的问题。

1 赞 1 收藏 评论

澳门新萄京官方网站 21

display

将元素定义为网格容器,并为其内容建立新的网格格式上下文。
属性值:
grid : 声明一个块级的网格
inline-grid : 声明一个内联级的网格
subgrid:如果你的网格容器本身是一个网格项(即嵌套网格),你可以使用此属性来表示你希望其行/列的大小从其父项继承,而不是自定义属性。

.container{
   display: grid | inline-grid | subgrid;
}

column, float, clear, 和 vertical-align 元素对网格容器不起作用。

用内容死区(content dead-zones)创建空白

在四列布局中,给本来在第三列的网格项上设置grid-column-start:2;,那么会找到下一个可用的第二列来填充空间。

网格轨道会跳过某些列,直到找到下一列。我们可以利用这个方法在网格内创建空白,没有内容的网格也会被分配。
[创建空白示例]

澳门新萄京官方网站 22

[使用grid-template-columns 和 grid-column-start创建空白]

网格容器

网格容器为其中的内容建立新的网格格式化上下文( grid formatting context ),网格容器构成了内部网格项的边界

澳门新萄京官方网站 23

网格容器

grid-template-columns 和 grid-template-rows

使用以空格分隔的值定义网格的列和行。 这些值的大小表示轨道大小,它们之间的空间表示网格线。
属性值:
<track-size> :可以是一个长度、百分比或者是网格中自由空间的一小部分(使用fr单位)
<line-name> :你选择的任意名称

.container{
    grid-template-columns: <track-size> ... | <line-name> <track-size> ...;
    grid-template-rows: <track-size> ... | <line-name> <track-size> ...;
}

示例:
当你在轨道值之间留有空格时,网络线就会自动分配数值名称:

.container{
    grid-template-columns: 40px 50px auto 50px 40px;
    grid-template-rows: 25% 100px auto;
}

澳门新萄京官方网站 24

grid-numbers

但是你也可以显示命名,请参考括号语法中的行名称命名方式:

.container{
    grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
    grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];
}

澳门新萄京官方网站 25

grid-names

请注意,一条网格线可以具有有多个名称。例如,这里的第二行将有两个名字: row1-endrow2-start:

.container{
  grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];
}

如果你的定义中包含重复的部分,你可以使用 repeat()标识进行精简:

.container{
  grid-template-columns: repeat(3, 20px [col-start]) 5%;
}

等同于:

.container{
  grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start] 5%;
}

fr单位允许你将轨道的大小设置为网格容器的可用空间的一小部分。 例如,如下所示把每个项目设置为网格容器宽度的三分之一:

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

这里可用空间表示除去非弹性项后剩余的空间。在此示例中的fr单位的可用空间表示减去50px以后的空间大小:

.container{
  grid-template-columns: 1fr 50px 1fr 1fr;
}

创建行

如果我们想分割布局为四份,我们目前所了解的关于列的布局方式对行同样有效:

.grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 250px 250px;
}

澳门新萄京官方网站 26

[同时使用grid-template-columns 和 grid-template-rows创建网格布局]

理想情况下这个示例是没问题的。因为此时每个网格项的内容足够少而不会撑开每行。但随着内容的变化,一切都不一样了。当示例中的内容超出指定行的大小后,看下会发生什么:

澳门新萄京官方网站 27

[内容超出声明的行高]

我们创建了250px高的两行,如果内容超过每行的高度,将会打破布局并和后面的行的内容重叠。并不是一个我们想要的结果。

网格线

网格线是水平和垂直分隔线。 我们将使用它们来构建网格轨道,网格单元格和网格区域。 他们有一个数字索引,或者我们也可以给他们一个特定的名字。

澳门新萄京官方网站 28

网格线

grid-template-areas

通过使用grid-area属性来定义网格区域名称,从而定义网格模板。网格区域重复的名称就会导致内容跨越这些单元格。句点表示一个空单元格。语法本身提供了一种可视化的网格结构。
属性值:
<grid-area-name> -:使用grid-area属性定义网格区域名称
. :句点表示一个空的单元格
none - 表示无网格区域被定义

.container{
  grid-template-areas: "<grid-area-name> | . | none | ..."
                       "..."
}

示例:

.item-a{
  grid-area: header;
}
.item-b{
  grid-area: main;
}
.item-c{
  grid-area: sidebar;
}
.item-d{
  grid-area: footer;
}
.container{
  grid-template-columns: 50px 50px 50px 50px;
  grid-template-rows: auto;
  grid-template-areas: "header header header header"
                       "main main . sidebar"
                       "footer footer footer footer"
}

这将创建一个四列三行的网格。最上面的一行为header区域。中间一行由两个main区域,一个空单元格和一个sidebar区域。最后一行是footer区域。

澳门新萄京官方网站 29

grid-template-areas

你所声明的每一行都需要具有相同数目的单元格。
你可以使用任意数量的句点(.)声明单个空单元格。只要句点之间没有空格它们就表示一个空单元格。
注意,你只是使用此语法进行网格区域命名,而不是网格线命名。当你使用此语法时,区域两边的线就会得到自动命名。如果网格区域名称为foo,则其行线和列线的名称就将为foo-start,最后一行线及其最后一列线的名字就会为foo-end。这意味着一些线就可能具有多个名称,如上面示例中所示,拥有三个名称:header-start,main-start, 以及footer-start

灵活的设置最小值

我们在该场景下需要的是设置最小尺寸的能力,但又要允许尺寸可以根据内容弹性变化。这里我们通过上面旧浏览器示例中的minmax关键字实现。

.grid {
    grid-template-rows: minmax(250px, auto) minmax(250px, auto);
}

创建有最小值的弹性行

现在我们已经了解了创建带有内容的行的基础方法,我们开始来创建水平和垂直交错的更复杂网格布局。

澳门新萄京官方网站 30

[使用grid-column-start和span关键字创建复杂网格布局Unsplash]

网格轨道

网格轨道是两条线之间的垂直或水平空间。

澳门新萄京官方网站 31

网格轨道

grid-column-gap 和 grid-row-gap

指定网格线的大小。你可以把它想像成在行/列之间设置间距宽度。
属性值:
<line-size> : 一个长度值

.container{
  grid-column-gap: <line-size>;
  grid-row-gap: <line-size>;
}

示例:

.container{
  grid-template-columns: 100px 50px 100px;
  grid-template-rows: 80px auto 80px;   
  grid-column-gap: 10px;
  grid-row-gap: 15px;
}

澳门新萄京官方网站 32

grid-column-row-gap

间距仅仅在列/行之间产生,而不会在边缘区。

创建更复杂的网格

我们开始创建更复杂的网格布局。将网格中的每个网格项设置成占据多条轨道,在一列内,我们能通过grid-column-startgrid-column-end实现,或者通过如下所示更简单的写法:

grid-column: 1 / 3;

用这种实现方式的弊端是难以“模块化”,为了定位每块内容需要写很多代码。span关键字更符合模块化的思路,因为我们能放在任何地方,让网格来控制他。我们可以定义网格项的开始位置,及其占据的轨道数:

.span-column-3 {
    grid-column-start: span 3;
}

任何添加该class的网格将会从其开始位置,占据三个轨道。

[通过span实现的复杂网格]

网格单元格

网格单元是在两个相邻的水平网格线和两个相邻的垂直网格线之间的项目。 它是我们可以把内容放入的最小单位。

澳门新萄京官方网站 33

网格单元格

grid-gap

grid-column-gapgrid-row-gap的简写值。
属性值:
<grid-column-gap> 和<grid-row-gap> : 长度值

.container{
  grid-gap: <grid-column-gap> <grid-row-gap>;
}

示例:

.container{
  grid-template-columns: 100px 50px 100px;
  grid-template-rows: 80px auto 80px;   
  grid-gap: 10px 15px;
}

如果没有指定grid-row-gap属性的值,默认与grid-column-gap属性值相同

使用span设计一个布局

我们能设计一个多轨道布局,通过将布局分解为grid布局中的最小单元。本示例中的最小单位是图中高亮的部分。

澳门新萄京官方网站 34

[通过最小网格单位结合span创建更大的网格]

围绕最小单位,我们能灵活的使用span来创建一些有意思的布局,因为span是可以叠加的——你可以结合列和行的轨道在网格中创建多层级。

网格区域

澳门新萄京官方网站 35

网格区域

justify-items

沿着列轴对齐网格项中的内容(相反于align-items属性定义的沿行轴对齐)。此值适用于容器内所有的网格项。
属性值:
start : 内容在网格区域中左端对齐
end :内容在网格区域中右端对齐
center :内容在网格区域居中对齐
stretch :内容宽度占满整个网格区域(默认值)

.container{
  justify-items: start | end | center | stretch;
}

示例:

.container{
  justify-items: start;
}

澳门新萄京官方网站 36

grid-justify-items-start

.container{
  justify-items: end;
}

澳门新萄京官方网站 37

grid-justify-items-end

.container{
  justify-items: center;
}

澳门新萄京官方网站 38

grid-justify-items-center

.container{
  justify-items: stretch;
}

澳门新萄京官方网站 39

grid-justify-items-stretch

以上特性也可以使用justify-self属性对各个网格项进行设置。

不需要媒体查询(media queries)的弹性网格

虽然上面说到的例子能在可用空间内适应变化,但是没有一个是专门为空间变化设计的。网格有两个非常有用的特性来适应可用空间的变化。这两个属性叫‘auto-fit’和‘auto-fill’,像下面这样结合repeat functionminmax function使用:

grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));

这些值代替了repeat中的数字,并计算在每条轨道上会填充多少行或列。二者之间最大不同是当一条轨道上空白的溢出时的他们的处理方式不同。

auto-fit尝试在不导致列溢出的情况下,放置该列能处理的最大数量的重复元素。当没有足够的空间来放置更多的元素时,之后的元素将会放到下一行,不能填满的空间将会被保留。

澳门新萄京官方网站 40

auto-fill

[示例:auto-fill. auto-fill会保留后面空间,反之auto-fit会让空白收缩为0px]

auto-fill的表现跟auto-fit类似,但是任何的空白空间都会自动收缩,同时这一行的元素也会被拉升——类似flexbox的效果,列会随着可用空间变小发生折叠。

澳门新萄京官方网站 41

grid-auto-fit示例

[grid-auto-fit示例]

依赖媒体查询的布局跟窗口大小关系很大,这不够模块化——系统内的组件应该能根据可用空间自适应。那么在实践中会是什么样的呢?

澳门新萄京官方网站 42

auto-fit

[grid auto-fit的真实示例]

[网格auto-fit示例]

网格布局的完整实现

现在我们用网格布局实现一下博客布局:

<div class="blog">
  <div class="header">Header</div>
  <div class="content">Content</div>
  <div class="sidebar">Sidebar</div>
  <div class="footer">Footer</div>
</div>

首先我们要设置displaygrid属性,对于其他的设置,我使用绝对值(pixels)作为长度单位,当然,也有更好的其他尝试(例如百分比、em、rem、vw和vh)。
属性 grid-template-columnsgrid-template-rows将生成网格轨道划分最外面的网格容器。 这两个属性的值既可以用固定值也可以使用auto。

.blog {
  display: grid;
  grid-template-columns: 400px 20px 180px;
  grid-template-rows: 100px 20px 210px 20px 100px;
}

澳门新萄京官方网站 43

Paste_Image.png

定义网格的外观,看下面的代码,以及代码下面的解释图片:

.header {
  grid-row-start: 1;
  grid-row-end: 2;
  grid-column-start: 1;
  grid-column-end: 4;
}
.content {
  grid-row-start: 3;
  grid-row-end: 4;
  grid-column-start: 1;
  grid-column-end: 2;
}
.sidebar {
  grid-row-start: 3;
  grid-row-end: 4;
  grid-column-start: 3;
  grid-column-end: 4;
}
.footer {
  grid-row-start: 5;
  grid-row-end: 6;
  grid-column-start: 1;
  grid-column-end: 4;
}

澳门新萄京官方网站 44

我们也可以使用缩写:

.header {
  grid-row: 1 /2;
  grid-column: 1 /4;
}
.content {
  grid-row: 3 /4;
  grid-column: 1 /2;
}
.sidebar {
  grid-row: 3 /4;
  grid-column: 3 /4;
}
.footer {
  grid-row: 5 / 6;
  grid-column: 1 / 4;
}

怎么样才能更短呢?grid-area 遵循以下顺序: grid-row-start , grid-column-start, grid-row-end, grid-column-end

.header {
  grid-area: 1 / 1 / 2 / 4;
}
.content {
  grid-area: 3 / 1 / 4 / 2;
}
.sidebar {
  grid-area: 3 / 3 / 4 / 4;
}
.footer {
  grid-area: 5 / 1 / 6 / 4;
}

最终代码是这样的:

.wrapper {
  display: grid;
  grid-template-columns: 400px 20px 180px;
  grid-template-rows: 100px 20px 210px 20px 100px;
}
.header {
  grid-area: 1 / 1 / 2 / 4;
}
.content {
  grid-area: 3 / 1 / 4 / 2;
}
.sidebar {
  grid-area: 3 / 3 / 4 / 4;
}
.footer {
  grid-area: 5 / 1 / 6 / 4;
}

上面这个例子很容易让你对即将到来的CSS网格布局充满憧憬,它真的是很好玩的东西,它入门很简单,通俗易懂,使人非常容易接受。但是更深入的接触之后会发现其实网格布局是很复杂的,甚至超过了Flexbox,它足足有17个新特性,并且围绕着我们编写CSS的方式介绍了许多新的概念,所以为了理解这个新的规范,弄清实战中它是怎样工作的,我们用它来创建一个圣杯布局。


align-items

沿行轴对齐网格项中的内容(相反于justify-items属性定义的沿列轴对齐)。此值适用于容器内所有的网格项。
属性值:
start : 内容在网格区域中顶端对齐
end :内容在网格区域中底部对齐
center :内容在网格区域居中对齐
stretch :内容宽度占满整个网格区域(默认值)

.container{
  align-items: start | end | center | stretch;
}

示例:

.container{
  align-items: start;
}

澳门新萄京官方网站 45

grid-align-items-start

.container{
  align-items: end;
}

澳门新萄京官方网站 46

grid-align-items-end

.container{
  align-items: center;
}

澳门新萄京官方网站 47

grid-align-items-center

.container{
  align-items: stretch;
}

澳门新萄京官方网站 48

grid-align-items-stretch

以上特性也可以使用align-self属性对各个网格项进行设置。

这只是冰山一角

我们已经经历了快十五年的CSS浮动为主的布局方式,我们上面学习了几乎所有你能用float实现的布局——CSS网格布局是这个领域的新代表,仍然还有许多东西需要去尝试和学习。

现在最重要的步骤是开始使用它。在构建、创建更多高级布局的时候会很方便。网格布局还有不少未知领域,一旦我们更好地理解其能力并开始与其他特性结合,我们便能用更少代码创造更多有趣、灵活的布局,并能减少些框架抽象的麻烦。

如果你感兴趣并想进一步探究CSS网格,可以试下Rachel Andrew的例子,这里面通过带解释说明的实例探讨了CSS网格布局的每一个特性。

澳门新萄京官方网站 49

什么是圣杯布局(Holy Grail Layout)

圣杯布局是一种网页布局,由四部分组成:一个页眉,页脚和一个主要内容区域,有两个侧边,每边一个。布局遵循一下规则:

  • 两边带有固定宽度中间可以流动(fluid)
  • 中心列最先出现在标记中
  • 所有三列不管其中内容如何变化,都应该是相同的高度
  • 页脚应该总是在浏览器视窗的底部,即便内容不填满整个适口的宽度
  • 响应式布局,在较小的视口中,各部分要进行折叠,宽度100%显示

圣杯布局在CSS中,如果不用任何Hack是很难去实现的。

justify-content

如果你的网格项目都是使用像px这样的非响应式单位来计算的,就有可能出现一种情况--网格的总大小可能小于其网格容器的大小。 在这种情况下,您可以设置网格容器内的网格的对齐方式。 此属性沿着列轴对齐网格(相反于align-content属性定义的沿行轴对齐)。
属性值:
start -网格在网格容器中左端对齐
end - 网格在网格容器中右端对齐
center - 网格在网格容器中居中对齐
stretch - 调整网格项的大小,使其宽度填充整个网格容器
space-around -在网格项之间设置偶数个空格间隙,其最边缘间隙大小为中间空格间隙大小的一半
space-between - 在网格项之间设置偶数个空格间隙,其最边缘没有间隙
space-evenly - 在网格项之间设置偶数个空格间隙,其最边缘间隙与其相同

.container{
  justify-content: start | end | center | stretch | space-around | space-between | space-evenly;    
}

.container{
  justify-content: start;   
}

澳门新萄京官方网站 50

grid-justify-content-start

.container{
  justify-content: end; 
}

![Uploading grid-justify-content-center]
](http://upload-images.jianshu.io/upload_images/1673685-51053776bcc7111a.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)

.container{
  justify-content: center;  
}

澳门新萄京官方网站 51

grid-justify-content-center

.container{
  justify-content: stretch; 
}

澳门新萄京官方网站 52

grid-justify-content-stretch

.container{
  justify-content: space-around;    
}

澳门新萄京官方网站 53

grid-justify-content-space-around

.container{
  justify-content: space-between;   
}

澳门新萄京官方网站 54

grid-justify-content-space-between

.container{
  justify-content: space-evenly;    
}

澳门新萄京官方网站 55

grid-justify-content-space-evenly

用网格布局的解决方案

html

<body class="hg">  
  <header class="hg__header">Title</header>
  <main class="hg__main">Content</main>
  <aside class="hg__left">Menu</aside>
  <aside class="hg__right">Ads</aside>
  <footer class="hg__footer">Footer</footer>
</body>  

它的CSS只有31行!

.hg__header { grid-area: header; }
.hg__footer { grid-area: footer; }
.hg__main { grid-area: main; }
.hg__left { grid-area: navigation; }
.hg__right { grid-area: ads; }

.hg {
    display: grid;
    grid-template-areas: "header header header"
                         "navigation main ads"
                         "footer footer footer";
    grid-template-columns: 150px 1fr 150px;
    grid-template-rows: 100px 
                        1fr
                        30px;
    min-height: 100vh;
}

@media screen and (max-width: 600px) {
    .hg {
        grid-template-areas: "header"
                             "navigation"
                             "main"
                             "ads"
                             "footer";
        grid-template-columns: 100%;
        grid-template-rows: 100px 
                            50px 
                            1fr
                            50px 
                            30px;
    }
}

澳门新萄京官方网站 56

Holy_Grail_CSS_Grid.gif

align-content

如果你的网格项目都是使用像px这样的非响应式单位来计算的,就有可能出现一种情况--网格的总大小可能小于其网格容器的大小。 在这种情况下,您可以设置网格容器内的网格的对齐方式。 此属性沿着行轴对齐网格(相反于justify-content属性定义的沿列轴对齐)。
属性值:
start -网格在网格容器中顶端对齐
end - 网格在网格容器中底端对齐
center - 网格在网格容器中居中对齐
stretch - 调整网格项的大小,使其宽度填充整个网格容器
space-around -在网格项之间设置偶数个空格间隙,其最边缘间隙大小为中间空格间隙大小的一半
space-between - 在网格项之间设置偶数个空格间隙,其最边缘没有间隙
space-evenly - 在网格项之间设置偶数个空格间隙,其最边缘间隙与其相同

.container{
  align-content: start | end | center | stretch | space-around | space-between | space-evenly;  
}

示例:

.container{
  align-content: start; 
}

澳门新萄京官方网站 57

grid-align-content-start

.container{
  align-content: end;   
}

澳门新萄京官方网站 58

grid-align-content-end

.container{
  align-content: center;    
}

澳门新萄京官方网站 59

grid-align-content-center

.container{
  align-content: stretch;   
}

澳门新萄京官方网站 60

grid-align-content-stretch

.container{
  align-content: space-around;  
}

澳门新萄京官方网站 61

grid-align-content-space-around

.container{
  align-content: space-between; 
}

澳门新萄京官方网站 62

grid-align-content-space-between

.container{
  align-content: space-evenly;  
}

澳门新萄京官方网站 63

grid-align-content-space-evenly

分解代码

上面说过,CSS网格布局可以非常复杂,然后,我创建这个圣杯布局只用了17个新特性的4个:

  • grid-area
  • grid-template-areas
  • grid-template-columns
  • grid-template-rows

我们用这些网格属性去实现圣杯布局布局可分为5个步骤。

grid-auto-columns和 grid-auto-rows

指定任何自动生成的网格轨道(也称为隐式网格轨道)的大小。 当显式定位超出定义网格范围的行或列(通过grid-template-rows / grid-template-columns)时,将创建隐式网格轨道。
属性值:
<track-size> :可以是一个长度、百分比或者是网格中自由空间的一小部分(使用fr单位)

.container{
  grid-auto-columns: <track-size> ...;
  grid-auto-rows: <track-size> ...;
}

为了说明隐式网格轨道是如何创建的,请思考一下:

.container{
  grid-template-columns: 60px 60px;
  grid-template-rows: 90px 90px
}

澳门新萄京官方网站 64

grid-auto

这里创建了2x2的网格。
但现在试想一下你使用grid-columngrid-row来定位你的网格项如下:

.item-a{
  grid-column: 1 / 2;
  grid-row: 2 / 3;
}
.item-b{
  grid-column: 5 / 6;
  grid-row: 2 / 3;
}

澳门新萄京官方网站 65

implicit-tracks

我们告诉.item-b在第列线 5开始,在列线6结束,但是我们从未定义过列线 5或6。因为我们引用了不存在的列,所以创建宽度为0的隐式轨道来填充这个间隙。 我们可以使用grid-auto-columnsgrid-auto-rows来指定这些隐式轨道的宽度:

.container{
  grid-auto-columns: 60px;
}

澳门新萄京官方网站 66

implicit-tracks-with-widths

1.定义网格

我们要做的第一件事情就是确认网格的区域,所以我们可以在创建网格时通过这个别名来引用它们。 我们使用grid-area属性。

.hg__header { grid-area: header; }
.hg__footer { grid-area: footer; }
.hg__main { grid-area: main; }
.hg__left { grid-area: navigation; }
.hg__right { grid-area: ads; }

然后,使用grid-template-areas属性,我们可以用非常直观的方式指定网格的布局。 grid-template-areas属性接受一个空格分隔的字符串列表,每个字符串表示一行。 在每个字符串中,我们有一个空格分隔的网格区域列表,定义的每个网格区域占用一列。 因此,如果我们想要一个区域跨越两列,我们定义它两次。
在我们的圣杯布局中,我们有3列和3行。 页眉和页脚行横跨3列,而其他区域各跨1列。

.hg {
    display: grid;
    grid-template-areas: "header header header"
                         "navigation main ads"
                         "footer footer footer";
}                         

使用这个标记,我们得到以下的结果:

澳门新萄京官方网站 67

定义网格

grid-auto-flow

如果您有未明确放置在网格上的网格项,则自动布局算法会启动,以自动放置项。 此属性用来控制自动布局算法的工作原理。
属性值:
row : 告诉自动布局算法依次填充每一行,并根据需要添加新行
column :告诉自动布局算法依次填充每一列,并根据需要添加新列
dense : 告诉自动布局算法尝试在网格更早的时候填充接下来出现较小的项目留有的空白

.container{
  grid-auto-flow: row | column | row dense | column dense
}

请注意,dense可能会导致您的项目无序显示。
示例:
思考下面的HTML:

<section class="container">
    <div class="item-a">item-a</div>
    <div class="item-b">item-b</div>
    <div class="item-c">item-c</div>
    <div class="item-d">item-d</div>
    <div class="item-e">item-e</div>
</section>

这里定义了一个两列五行的网格,并将 grid-auto-flow属性设置为row(即默认值):

.container{
    display: grid;
    grid-template-columns: 60px 60px 60px 60px 60px;
    grid-template-rows: 30px 30px;
    grid-auto-flow: row;
}

当在网格上放置项目时,您只需要指定其中两个的网格项

.item-a{
    grid-column: 1;
    grid-row: 1 / 3;
}
.item-e{
    grid-column: 5;
    grid-row: 1 / 3;

因为我们将grid-auto-flow属性设置为了row,所以我们的网格看起来会像这个样子。注意我们没有进行设置的三个网格项(item-b, item-c and item-d),会沿行轴进行布局。

澳门新萄京官方网站 68

grid-auto-flow-row

如果我们将grid-auto-flow属性设置为 column,item-b, item-citem-d 就会沿列轴进行布局。

.container{
    display: grid;
    grid-template-columns: 60px 60px 60px 60px 60px;
    grid-template-rows: 30px 30px;
    grid-auto-flow: column;
}

澳门新萄京官方网站 69

grid-auto-flow-column

2.定义列宽

下一步,我们要定义的列的宽度。我们使用grid-template-columns属性定义列的宽度。该属性接受空格分格的宽度列表,网格中的每一列都有一个宽度。因为我们的布局有3列,我们可以指定3个宽度:

grid-template-columns: [column 1 width]  [column 2 width]  [column 3 width];  

对于圣杯布局,我们希望2个侧边宽度为150px。

.hg {
  grid-template-columns: 150px  [column 2 width] 150px;
}

我们还希望中间列占据空间的其余部分。 我们可以通过使用新的fr单位来做到这一点。 此单位表示网格中剩余的自由空间的一小部分。 在我们的例子中,剩余自由空间是网格的当前宽度减去300px(两个边栏的宽度)。

.hg {
    grid-template-columns: 150px 1fr 150px;
}

设置网格列之后,这是布局的样子 :

澳门新萄京官方网站 70

定义列宽

grid

在一行声明中设置一下所有属性的简写形式:grid-template-rows, grid-template-column, grid-template-areas, grid-auto-rows,grid-auto-columns, 以及 grid-auto-flow。它将grid-column-gapgrid-row-gap
属性设置为初始值,即使它们不能由此属性显式去设置。
属性值:
none: 将所有的子属性设置为初始值
subgrid: 将grid-template-rowsgrid-template-columns属性值设置为subgrid其余子属性设置为初始值
<grid-template-rows> / <grid-template-columns>: 将grid-template-rowsgrid-template-columns
分别设置为指定值,其余子属性设置为初始值
<grid-auto-flow>[<grid-auto-rows> [ / <grid-auto-columns>] ] : grid-auto-flow, grid-auto-rowsgrid-auto-columns属性分别接受相同的值,如果省略了grid-auto-columns属性,它将设置为grid-auto-rows属性的值。如果两者均被忽略,那么都将被设置为初始值。

.container{
    grid: none | subgrid | <grid-template-rows> / <grid-template-columns> | <grid-auto-flow> [<grid-auto-rows> [/ <grid-auto-columns>]];
}

示例:
以下两个代码块是等效的:

.container{
    grid: 200px auto / 1fr auto 1fr;
}

.container{
    grid-template-rows: 200px auto;
    grid-template-columns: 1fr auto 1fr;
    grid-template-areas: none;
}

以下两个代码块同样也是等效的:

.container{
    grid: column 1fr / auto;
}

.container{
    grid-auto-flow: column;
    grid-auto-rows: 1fr;
    grid-auto-columns: auto;        
}

澳门新萄京官方网站:布局入门,Grid中的陷阱和阻碍。它还接受一次性设置所有属性,更复杂但相当方便的语法。指定 grid-template-areas
, grid-auto-rowsgrid-auto-columns属性,其他所有子属性都将设置为其初始值。你现在所做的是在其网格区域内,指定网格线名称和内联轨道大小。这里最容易用一个例子来描述:

.container{
  grid: [row1-start] "header header header" 1fr [row1-end]
        [row2-start] "footer footer footer" 25px [row2-end]
        / auto 50px auto;
}

等同于:

.container{  
  grid-template-areas: "header header header"
                       "footer footer footer";
  grid-template-rows: [row1-start] 1fr [row1-end row2-start] 25px [row2-end];
  grid-template-columns: auto 50px auto; 
}
3.定义行高

接下来,我们要定义行的高度。 类似于我们grid-template-columns定义列宽,我们使用 grid-template-rows定义行高。此属性还接受用空格分隔列表。虽然我们可以写在一行,但是我认为一行一行去写会更加直观清楚。

.hg {
    grid-template-rows: 100px 
                        1fr
                        30px;
}

因此,我们的标题高度是100px,我们的页脚高度是30px,中间行(主要内容和两个侧边栏)占用.hg元素的剩余可用空间。

澳门新萄京官方网站 71

定义行高

网格项的属性(Properties for the Grid Items)

grid-column-start
grid-column-end
grid-row-start
grid-row-end
通过使用特定的网格线确定网格项在网格内的位置。grid-column-start/grid-row-start属性表示网格项的网格线的起始位置,grid-column-end/grid-row-end属性表示网格项的网格线的终止位置。
属性值:
**<line>
**: 可以是一个数字来指代相应编号的网格线,或者使用名称指代相应命名的网格线
span <number>: 网格项包含指定数量的网格轨道
span <name>: 网格项包含指定名称网格项的网格线之前的网格轨道
auto: 表明自动定位,自动跨度或者默认跨度为一

.item{
  grid-column-start: <number> | <name> | span <number> | span <name> | auto
  grid-column-end: <number> | <name> | span <number> | span <name> | auto
  grid-row-start: <number> | <name> | span <number> | span <name> | auto
  grid-row-end: <number> | <name> | span <number> | span <name> | auto
}

示例:

.item-a{
  grid-column-start: 2;
  grid-column-end: five;
  grid-row-start: row1-start
  grid-row-end: 3
}

澳门新萄京官方网站 72

grid-start-end-a

.item-b{
  grid-column-start: 1;
  grid-column-end: span col4-start;
  grid-row-start: 2
  grid-row-end: span 2
}

澳门新萄京官方网站 73

grid-start-end-b

如果没有声明grid-column-end/grid-row-end属性,默认情况下网格项的跨度为1。
网格项可以互相重叠。可以使用z-index属性控制堆叠顺序。
grid-column
grid-row
grid-column-start grid-column-end, 和grid-row-start grid-row-end属性分别的简写形式。
属性值:
<start-line> / <end-line>: 每一个属性均接收自定义的一个相同值,包括跨度。

.item{
  grid-column: <start-line> / <end-line> | <start-line> / span <value>;
  grid-row: <start-line> / <end-line> | <start-line> / span <value>;
}

示例:

澳门新萄京官方网站 74

grid-start-end-c.png

.item-c{
  grid-column: 3 / span 2;
  grid-row: third-line / 4;
}

如果没有声明结束网格线值,默认网格轨道跨度为1.
grid-area
属性值:
<name> - 你定义的名字
<row-start> / <column-start> / <row-end> / <column-end> - 可以是数字或者命名行
示例:
为网格项命名的一种方式:

.item-d{
  grid-area: header
}

grid-row-start grid-column-start grid-row-end grid-column-end属性的一种简写方式:

.item-d{
  grid-area: 1 / col4-start / last-line / 6
}

澳门新萄京官方网站 75

grid-start-end-d

justify-self
沿列轴对齐网格项中的内容(相反于align-item属性定义的沿行轴对齐)。此值适用于单一网格项中的内容。
属性值:
start: 内容与网格区域的左端对齐
end: 内容与网格区域的右端对齐
center: 内容处于网格区域的中间位置
stretch: 内容宽度占据整个网格区域空间(默认值)

.item{ justify-self: start | end | center | stretch;}

示例

.item-a{
  justify-self: start;
}
![grid-justify-self-start](http://upload-images.jianshu.io/upload_images/1673685-7852d1a5d23c8293.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)

.item-a{
  justify-self: end;
}

澳门新萄京官方网站 76

grid-justify-self-end

.item-a{
  justify-self: center;
}

澳门新萄京官方网站 77

grid-justify-self-center

.item-a{
  justify-self: stretch;
}

澳门新萄京官方网站 78

grid-justify-self-stretch

设置网格中所有网格项的对齐方式,可以使用网格容器上的justify-items属性。

align-self
沿行轴对齐网格项中的内容(相反于justify-item属性定义的沿列轴对齐)。此值适用于单一网格项中的内容。
属性值:
start: 内容与网格区域的顶端对齐
end: 内容与网格区域的底部对齐
center: 内容处于网格区域的中间位置
stretch: 内容高度占据整个网格区域空间(默认值)

.item{
  align-self: start | end | center | stretch;
}

示例:

.item-a{
  align-self: start;
}

澳门新萄京官方网站 79

grid-align-self-start

.item-a{
  align-self: end;
}

澳门新萄京官方网站 80

grid-align-self-end

.item-a{
  align-self: center;
}

澳门新萄京官方网站 81

grid-align-self-center

.item-a{
  align-self: stretch;
}

澳门新萄京官方网站 82

grid-align-self-stretch

本文翻译自 http://chris.house/blog/a-complete-guide-css-grid-layout/#prop-grid-template-areas
转载请注明英文原版出处

4.固定页脚

在圣杯布局中,我们希望页脚始终位于视口的底部,即使页面上的内容不被充满一屏。 为了实现这一点,我们可以将.hg元素的最小高度设置为视口的高度。

.hg {
    min-height: 100vh;
}

因为我们指定中间行应该填充剩余的可用空间,它会伸展到填满屏幕。

澳门新萄京官方网站 83

固定页脚

5.设置响应式

最后,我们想让布局响应。 在较小的设备上,所有网格项目应该一个接一个地显示在一列中。 为此,我们需要重新定义之前定义的3个属性:
grid-template-areasgrid-template-columnsgrid-template-rows
首先,我们想要网格中的所有项目按照特定的顺序在一个列中:

@media screen and (max-width: 600px) {
    .hg {
        grid-template-areas: "header"
                             "navigation"
                             "main"
                             "ads"
                             "footer";
    }
}

接下来,我们想要所有项目占满网格宽度的100%:

@media screen and (max-width: 600px) {
    .hg {
        grid-template-columns: 100%;
    }
}

最后,我们需要重置每一行的高度。 除了主行之外,所有行限定它的高度:

@media screen and (max-width: 600px) {
    .hg {
        grid-template-rows: 100px /* Header */
                            50px /* Navigation */
                            1fr /* Main Content */
                            50px /* Ads */
                            30px; /* Footer */
    }
}

澳门新萄京官方网站 84

设置响应式

完成!在这里你可以看到它的演示和源码(你可能需要在浏览器中启用实验性的网络功能来查看它)

Grid Layout Module vs Flexbox

Flexbox适用于许多布局和很多“页面组件”元素,因为它们大多是基本线性的。 Grid适用于整体页面布局,以及非线性的复杂页面组件。
这两个可以任意组合,所以一旦广泛支持,我相信大多数页面将由一个外部网格的整体布局,混合嵌套flexbox和网格的页面组件,最后block/ inline-block /table布局在页面装饰文本和内容。

网格布局资源

上面讲的两种布局只使用了网格布局的4种属性,没有涵盖所有的网格布局概念和语法,如果对网格布局有兴趣,可以去下面的资源中更深入学习:

CSS Grid Layout Module spec

A Complete Guide to CSS Grid Layout

CSS Grid Layout Examples
Grid by Example

The future of layout with CSS: Grid Layouts

还有Rachel Andrew的关于网格布局的最新信息和资源。 她为网格布局做了许多贡献。

总结

正如你所看到的,即将到来的CSS网格布局是强大的,因为它的代码简洁易懂,你很容易去设计和改变布局顺序。这些功能可以帮助我们永久改变网络开发中创建布局的方式,所以,我相信网格布局是CSS布局的未来!

http://chris.house/blog/a-complete-guide-css-grid-layout/

https://en.wikipedia.org/wiki/Holy_Grail_(web_design))

https://bitsofco.de/holy-grail-layout-css-grid/

https://www.sitepoint.com/introduction-css-grid-layout-module/

本文由澳门新萄京官方网站发布于澳门新萄京赌场网址,转载请注明出处:澳门新萄京官方网站:布局入门,Grid中的陷阱和

关键词: