[译] 简单的响应式现代 CSS 网格布局

在本文中,咱们将展现如何建立响应式现代 CSS 网格布局,演示如何在旧浏览器上使用降级代码,如何逐步添加 CSS 网格,如何使用对齐属性从新构建小型设备的布局以及居中元素。css

在以前的文章中,咱们探索了四种不一样的技术,能够轻松构建响应式网格布局。那篇文章是在 2014 年写的 —— 在 CSS 网格可用以前 —— 所以在本教程中,咱们将使用相似的 HTML 结构,但使用现代 CSS 网格布局。前端

在本教程中,咱们将使用浮动来建立一个带有基本布局的演示项目,而后使用 CSS 网格对其进行加强。咱们将演示许多有用的实用工具,例如居中元素,跨越元素,以及经过从新定义网格区域和使用媒体查询轻松更改小型设备上的布局。你能够在此 pen 中找到代码:codepen.io/SitePoint/p…android

响应式现代 CSS 网格布局

在咱们开始建立响应式网格演示项目以前,首先介绍一下 CSS 网格。ios

CSS 网格是一个功能强大的二维系统,在 2017 年被添加到大多数现代浏览器中。它极大地改变了咱们建立 HTML 布局的方式。网格布局容许咱们在 CSS 而不是 HTML 中建立网格结构。git

除了 IE11 以外,大多数现代浏览器都支持 CSS 网格,IE11 支持可能产生一些问题的旧版标准。你可使用 caniuse.com 来检查支持状况。github

网格布局有一个 display 属性为 gridinline-grid 的父容器。容器的子元素是网格项,由强大的网格算法隐式定位。你还能够应用不一样的类来控制网格项的放置,尺寸,位置和其余方面的东西。算法

让咱们从一个基本的 HTML 页面开始。建立 HTML 文件并添加如下内容:后端

<header>
    <h2>CSS Grid Layout Example</h2>
</header>
<aside>
  .sidebar
</aside>

<main>
  <article>
    <span>1</span>
  </article>
  <article>
    <span>2</span>
  </article>
  <!--... -->
  <article>
    <span>11</span>
  </article>
</main>

<footer>
  Copyright 2018
</footer>
复制代码

咱们使用 HTML 语义标签来定义页面的头部,侧边栏,主体和页脚部分。在主体部分中,咱们使用 <article> 标签添加一组子项。<article> 是一个 HTML5 语义标签,可用于包装独立和自包含的内容。单个页面能够包含任意数量的 <article> 标签。浏览器

这是此阶段页面的屏幕截图:bash

The basic HTML layout so far

接下来,让咱们添加基本的 CSS 样式。在文档的头部添加 <style> 标签并添加如下样式:

body {
  background: #12458c;
  margin: 0rem;
  padding: 0px;
  font-family: -apple-system, BlinkMacSystemFont,
            "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell",
            "Fira Sans", "Droid Sans", "Helvetica Neue",
            sans-serif;
}

header {
  text-transform: uppercase;
  padding-top: 1px;
  padding-bottom: 1px;
  color: #fff;
  border-style: solid;
  border-width: 2px;
}

aside {
  color: #fff;
  border-width:2px;
  border-style: solid;
  float: left;
  width: 6.3rem;
}

footer {
  color: #fff;
  border-width:2px;
  border-style: solid;
  clear: both;
}

main {
  float: right;
  width: calc(100% - 7.2rem);
  padding: 5px;
  background: hsl(240, 100%, 50%);
}

main > article {
  background: hsl(240, 100%, 50%);
  background-image: url('https://source.unsplash.com/daily');
  color: hsl(240, 0%, 100%);
  border-width: 5px;
}
复制代码

这是一个小型演示页面,所以咱们将直接设置标签样式以提升可读性,而不是应用类命名系统。

咱们使用浮动将侧边栏定位到左侧,将主体部分定位到右侧,将侧边栏的宽度设置为固定的 6.3rem。而后咱们使用 CSS calc() 函数来计算并设置主体部分可用的剩余宽度。主体部分包含一些垂直排列的子项。

A gallery of items organized as vertical blocks

布局并不完美。例如,侧边栏与主体内容部分的高度并不相同。有各类 CSS 技术能够解决这些问题,但大多数都是 hack 或变通方法。因为此布局是网格的降级,所以快速减小的用户也能够看到效果。降级是可用的,足够了。

最新版本的 Chrome、Firefox、Edge、Opera 和 Safari 都支持 CSS 网格,这意味着若是你的访问者使用这些浏览器,则无需提供降级。你还须要考虑常青浏览器。最新版本的 Chrome、Firefox、Edge 和 Safari 是常青浏览器。也就是说,它们会在不提示用户的状况下自动静默更新。为确保你的布局适用于每一个浏览器,你能够从默认的基于浮动的降级开始,而后使用渐进加强技术应用现代网格布局。那些使用旧浏览器的用户将没法得到相同的体验,但这样足够了。

渐进加强:你没必要所有覆盖

在降级布局的顶部添加 CSS 网格布局时,实际上不须要覆盖全部标签或使用彻底独立的 CSS 样式:

  • 在不支持 CSS 网格的浏览器中,你添加的网格属性将被忽略。
  • 若是你使用浮动来布置元素,请记住网格项优先于浮动项。也就是说,若是将 float: left|right 样式添加到也是网格元素的元素(具备 display: grid 样式的父元素的子元素)中,则将忽略浮动以支持网格。
  • 可使用 @supports 规则在 CSS 中检查特定功能的支持状况。这容许咱们在必要时覆盖降级样式,而旧浏览器会忽略 @supports 代码块。

如今,让咱们在页面中添加 CSS 网格。首先,咱们让 <body> 成为一个网格容器并设置网格列,行和区域:

body {
  /*...*/
  display: grid;
  grid-gap: 0.1vw;
  grid-template-columns: 6.5rem 1fr;
  grid-template-rows: 6rem 1fr 3rem;
  grid-template-areas: "header header"
                       "sidebar content"
                       "footer footer";  
}
复制代码

咱们使用 display:grid 属性将 <body> 标记为网格容器。将网格 gap 设为 0.1vw。gap 容许你在网格单元格之间建立间距,而不是使用外边距。

咱们用 grid-template-columns 来添加两列。第一列宽度固定为 6.5rem,第二列为剩余宽度。fr 是一个小数单位,1fr 等于可用空间的一部分。

接下来,咱们用 grid-template-rows 添加三行。第一行高度固定为 6rem,第三行高度固定为 3rem,剩余可用空间(1fr)指定给第二行。

而后咱们用 grid-template-areas 将由列和行的交集产生的虚拟单元格分配给区域。如今咱们须要使用 grid-area 实际定义区域模板中指定的区域:

header {
  grid-area: header;
  /*...*/
}
aside {
  grid-area: sidebar;
  /*...*/
}
footer {
  grid-area: footer;
  /*...*/
}
main {
  grid-area: content;
  /*...*/
}
复制代码

咱们的大多数降级代码对 CSS 网格没有任何反作用,除了主体部分的宽度 width: calc(100% - 7.2rem);,它在减去侧边栏的宽度加上外边距/内边距后计算主体部分的剩余宽度。

这是结果的屏幕截图。注意主体区域并无占满剩余的所有宽度:

Progressive layout with current grid settings

要解决此问题,咱们能够在支持网格时添加 width: auto;

@supports (display: grid) {
  main {
    width: auto;
  }
}
复制代码

这是结果的屏幕截图:

The effect of adding width: auto

添加嵌套网格

网格子项能够是网格容器自己。让咱们将主体部分做为一个网格容器:

main {
  /*...*/
  display: grid;  
  grid-gap: 0.1vw;
  grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
  grid-template-rows: repeat(auto-fill, minmax(12rem, 1fr));
}
复制代码

咱们将网格 gap 设为 0.1vw 并使用 repeat(auto-fill, minmax(12rem, 1fr)); 函数定义列和行。auto-fill 选项会尝试使用尽量多的列或行填充可用空间,必要时会建立隐式列或行。若是要将可用列或行放入可用空间,则须要使用 auto-fit。详情请阅读 auto-fillauto-fit 的差别

这是结果的屏幕截图:

A nested grid

使用网格 grid-columngrid-rowspan 关键词

CSS 网格提供了 grid-columngrid-row,它们容许你使用网格线在父网格中对网格项进行定位。它们是如下属性的简写:

  • grid-row-start: 指定网格行中网格项的起始位置
  • grid-row-end: 指定网格行中网格项的结束位置
  • grid-column-start: 指定网格列中网格项的起始位置
  • grid-column-end: 指定网格列中网格项的结束位置。

你还可使用关键字 span 指定要跨越的列数或行数。

咱们让主体区域的第二个子项跨越四列、两行,并让其从第二列和第一行(也是它的默认位置)开始放置:

main article:nth-child(2) {
  grid-column: 2/span 4;
  grid-row: 1/span 2;
}
复制代码

这是结果的屏幕截图:

Second child spanning four columns and two rows

使用网格对齐工具

咱们想让头部,侧边栏和页脚中的文本以及 <article> 元素内的数字居中。

CSS 网格提供了六个属性 justify-itemsalign-itemsjustify-contentalign-contentjustify-selfalign-self,可用于对齐和分散网格项。它们其实是 CSS 盒对齐模型的一部分。

在头部内,侧边栏,文章和页脚选择器内添加如下内容:

display: grid;
align-items: center;
justify-items: center;
复制代码
  • justify-items 用于沿行轴或在水平方向上对齐网格项。
  • align-items 沿着列轴或在垂直方向上对齐网格项。它们均可以使用 startendcenterstretch

这是居中元素后的屏幕截图:

Numbers are now centered horizontally and vertically in each cell

重构小型设备中的网格布局

咱们的演示布局适用于中型和大型屏幕,但可能不是在小屏幕设备中构建页面的最佳方式。使用 CSS 网格,咱们能够轻松地更改此布局结构,使其在小型设备中平滑过渡 —— 经过从新定义网格区域及使用媒体查询。

这是在添加代码重构小型设备上的布局以前的屏幕截图:

The initial mobile layout

如今,添加如下 CSS 代码:

@media all and (max-width: 575px) {
  body {
    grid-template-rows: 6rem  1fr 5.5rem  5.5rem;  
    grid-template-columns: 1fr;
    grid-template-areas:
      "header"
      "content"
      "sidebar"
      "footer";
    }
}
复制代码

在宽度 <= 575px 的设备上咱们使用宽度分别为 6rem1fr5.5rem5.5rem 的四行,以及占满全部可用空间的一列。咱们还从新定义了网格区域,让侧边栏在小型设备上处于主体内容区域下面的第三行:

The developing mobile layout

请注意,侧边栏的宽度并未占满可用宽度。这是由降级代码引发的,因此咱们须要作的是在支持网格的浏览器上用 width: auto; 覆盖掉 width: 6.3rem;

@supports (display: grid) {
  main, aside {
    width: auto;
  }
}
复制代码

这是最终结果的屏幕截图:

The final mobile layout

你能够在本文开头附近的 pen 中找到最终代码,也能够直接访问此 pen

结论

在本教程中,咱们使用 CSS 网格建立了一个响应式演示布局。咱们已经演示了如何针对旧版浏览器使用降级代码,逐步添加 CSS 网格,在小型设备中重构布局以及使用对齐属性居中元素。

若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

相关文章
相关标签/搜索