【QCon】精华内容上线92%,全面覆盖“人工智能+”的典型案例!>>> 了解详情
写点什么

迈向 Grid 二维布局时代

  • 2021-06-14
  • 本文字数:4784 字

    阅读完需:约 16 分钟

迈向 Grid 二维布局时代

CSS Grid 布局是一种强大并且富有创意的的布局方案,这篇文章专门为不了解 Grid 的 web 开发人员来介绍它,我将从以下几个方面来介绍它


  1. 为什么需要 Grid。Grid Line 在生产环境中怎么安全的使用 Grid

  2. 介绍 Gird 基本概念。

  3. 开始学习使用 Gird。

  4. 在生产环境中怎么安全的使用 Grid。


为什么需要 Grid


目前我们有很多种布局方案,比如最初我们使用表格布局,后面使用 float, position 和 inline-block 来进行布局, 由于这些方法在设计之初上并不是用于布局的,而是用于图文展示,由此 CSS 当初设计的不是很完美,并且遗漏了许多功能,比如说无法很方便的实现垂直居中; 无法显式的去创建 BFC,只能通过一些 hack 手段去处理,比如 overflow: hidden, 或者使用 clear:both 去清除浮动带来的副作用。


2009 年,W3C 提出了一种新的方案 ----Flexbox 布局, Flex 布局是轴线布局,只能指定 "项目" 针对轴线的位置,可以看作是一维布局,但是对于复杂的二维布局就有心无力了。


Grid 布局是 CSS 诞生以来第一个专门为解决布局问题而生的方案, 它将容器划分成 "行" 和 "列",产生单元格,然后指定 "项目所在" 的单元格,可以看作是二维布局。Grid 布局与 Flex 布局有一定的相似性,都可以指定容器内部多个项目的位置。但是,它们也存在重大区别,Grid 主要是用于布局的,而 Flex 是主要用于内容的,两种方案并不是水火不容的,而是相辅相成的。


另外值得一提的一点是在栅格系统方案,我们也遇见过很多的 CSS 框架,例如 Bootstrap 和 Foundation, 它们都提供了很优秀的 grid layout 模板,但是它们本质上并不是 grid,而是通过 float 来实现,CSS grid 而跟他们是完全不同的。


web 网页的布局基础是最初是基于 float 的,这导致了布局的模型是一维的,所以当我们去进行设计布局的时候都是从行去考虑方案的。下面是一个简单两列布局的实例,虽然看起来图片 B 下方似乎有一个列,但是实际上没有,我们都是通过行去进行布局操作的。



相比之下 CSS Gird 布局,我们会通过以下图片所展示的方式来进行思考。



在图中我们有 二维系统, 不单单只有行,其实还有列,这是一个全新的思考方式,类似于出现 React/Vue Hook 时候需要调整思考问题的方式, 接下来我会带你去理解它。


介绍 Gird 基本概念。


在深入了解 Grid 的概念之前,重要的是了解术语,由于此处涉及的术语在概念上有点相似,因此,如果你不理解它们所代表的含义,就很容易将它们混淆。


Grid Container


在元素上设置 display: grid, 能够使它成为一个 Grid Container,它的直接子元素都将成为 grid Item


<style>.container {  display: grid;}</style><div class="container">  <div class="item"></div>  <div class="item"></div>  <div class="item"></div></div>
复制代码

Grid Item

grid container 的 直系子元素,例如下列代码中的 item 元素是 grid item,但是其中 sub-item 并不是 grid item


<style>.container {  display: grid;}</style><div class="container">  <div class="item"></div>  <div class="item">    <p class="sub-item"></p>  </div>  <div class="item"></div></div>
复制代码

Grid Line

网格结构的分界线,它们可以是水平的,或者是垂直的,位于行或者列的任意一侧,在下图中黄线是一个列网格线。

Grid Cell

两个相邻的行和两个相邻的列网格线之间的空间。它是网格的单个 “单位”。例如下图中黄色的单元格

Grid Area

一个网格区域可以包含多个单元格, 例如下图中黄色区域。


开始学习使用 Gird

grid-template-columns / grid-template-rows

让我们从最基础的开始,下图是一个有 3 行 6 列的网格

其中是 4 行 grid line 和 7 列 grid line,另外的两个 grid line 之前的区域叫做 grid area,就在下图的橙色区域内,还有每个网格的单元格我们叫做 grid cell,就如下图中的绿色区域。

如果想要生成这样的布局很简单,我们只关注 CSS,代码如下

.grid {  display: grid;  grid-template-columns: 100px 100px 100px 100px 100px 100px;  grid-template-rows: 100px 100px 100px;}
复制代码

首先我们要将容器从一个普通容器变成 grid 容器,接下来我们定义了每一行高度为 100px,一共有 3 行,每一列宽度为 100px,一共有 6 列。

你可以通过这个来查阅相关代码,在上面实例中有很多重复的 100px,我们也可以改写成如下

.grid {  display: grid;  grid-template-columns: repeat(6, 100px);  grid-template-rows: repeat(3, 100px);}
复制代码

现在我们来给它加点边距,通过 grid-gap 来完成。

.grid {  display: grid;  grid-template-columns: repeat(6, 100px);  grid-template-rows: repeat(3, 100px);  gap: 30px;}
复制代码

所以现在看起来如下


当然你也可以可以给行和列的边距设置成不一样的,使用 grid-gap: 30px 10px; 来让行边距为 30px,列边距为 10px,这样就完成了一个简单的网格布局。

grid-row / grid-column

接下来我们来学习第二组属性 grid-row 和 grid-column

在以下内容的预览图上大家会看到有各种辅助虚线,这个在真实渲染中是不存在的,使用过 firebox 的 Debug 模式下才会显式出来,在这里我建议大家使用 firefox 去调试 Gird 布局,这点 Chrome 远远比不上 firefox,希望 Chrome 能够尽快跟进布局上的调试功能

<style>.container {  display: grid;  grid-template-columns: repeat(3, 100px);  grid-template-rows: repeat(3, 100px);}.grid-item {  background: red;  grid-row: 2 / 3;  grid-column: 2 / 3;}</style>  <div class="container">  <p class="grid-item"> 挂号网 </p></div>
复制代码


grid-row 代表将这个 grid-item 设置在从第二根行线开始,到第三根行线结束,grid-column 代表将这个 grid-item 设置在从第二根列线开始,到第三根列线结束,示例代码

到这里大家可能会觉得这里很惊艳,以往很麻烦的布局,grid 却能够轻松做到。grid 网格布局因为拥有独立行和列的系统,所以才能让我们 轻松定位 / 重新定位 内容。

接下来让我们继续来介绍 span 关键词,如果我们想要上图布局能够占满中间一行的三个格子,其中一个办法是设置 grid-column: 1 / 4, 代表从第一列线开始,一直到第四列线停止,这样如果觉得不好计算的话,可使用 span 关键字,grid-column: 1 / span 3, 代表从第一个格子出发,穿过三个格子(包括出发的格子)为止,效果也是和上述一样的。

示例代码

grid-template-areas

然后我们来介绍一下 grid-template-areas 属性,我认为这是一个革命性的属性,能够以一种二维数组的方式来定位你的布局。

grid-template-areas 属性接受一个或多个字符串作为值。每个字符串(用引号引起来)代表网格的一行。您可以在使用 grid-template-rows 和 grid-template-columns 定义的网格上使用该属性,也可以创建布局,在这种情况下,所有行都将自动调整大小

.container {  grid-template-areas: "one one two two"                       "one one two two"                       "three three four four"                       "three three four four";}.one {  grid-area: one;}.two {  grid-area: two;}.three {  grid-area: three;}.four {  grid-area: four;}
复制代码


其中要注意的是,我们的网格区域一定要形成规整的矩形区域,什么 L 形,凹的或凸的形状都是不支持的,会认为是无效的属性值, 当然如果你不需要把全部网格填满那也是可以的,使用. 号来进行占位

.container {  grid-template-areas: "one . two two"                       "one . two two"                       ". three four four"                       ". three four four";}.one {  grid-area: one;}.two {  grid-area: two;}.three {  grid-area: three;}.four {  grid-area: four;}
复制代码


到目前为止我们已经简单的介绍了 grid 布局出现的前因后果和它核心的几个属性的基础语法,其中除了本文中介绍的几种语法外,还有另外的语法可以使用,但是由于这篇文章的主题是介绍 css grid 的使用方法,而不是每个 api 的详细介绍,这里不多赘述。


实战

经过以上的学习,我们来进行一个实战例子,以挂号网 www.guahao.com 的官网首屏来举例,我们可以把布局切分为 4 行 3 列。

html 结构定义如下

<main>  <img src="https://static.guahao.cn/front/portal-pc-static/img/new-wy-logo.png" alt="logo" class="logo" />  <div class="search">    <section class="searchBox">      <input />      <button > 搜索 </button>    </section>    <ul>      <li > 微医病友群 </li>      <li > 千万助孕补贴 </li>      <li > 治疗腋下多汗 </li>      <li > 整形修复 </li>      <li > 假体隆鼻 </li>      <li > 脱发怎么办 </li>    </ul>  </div>  <img src="https://static.guahao.cn/front/portal-pc-static/img/2015/platform-logo-new.png" alt="guide" class="guide" />  <div class="slider"></div>  <div class="sub-project"></div>  <img src="https://kano.guahao.cn/5gu296857515" alt="swiper" class="swiper">  <div class="help"></div>  <div class="news"></div></main>
复制代码

能明显的看到与以往的布局不同,每一个区块都可以作为 main 标签的直接子元素,而不用去使用各种标签嵌套来布局, 接下里是容器的 css 代码。

main {  display: grid;  grid-template-areas:                    'logo search guide'                    'slider sub-project sub-project'                    'slider swiper help'                    'slider news news';  grid-template-columns: 240px 800px 240px;  grid-template-rows: auto auto auto auto;}
复制代码

其中 grid-template-areas 一个属性就轻易定义了整个页面的布局结构,十分的方便,接下去通过给每一个子元素定义 grid-area 属性来指定放置的位置。

.logo {  grid-area: logo;  width: 190px;  align-self: center;  justify-self: center;}.search {  grid-area: search;  align-self: center;  justify-self: center;}/* more code */
复制代码

安全使用 Grid



截止目前为止,大量的现代浏览器已经支持 Grid,截止 2020 年 5 月,大部分的高级浏览器都已经支持了 Grid,并且对于不支持的我们可以通过 polyfill 进行兼容,另外你还可以通过 @supports 来查询浏览器是否支持 gird 布局,从而来决定是否使用 grid


@supports (display: grid) {  .container {    /* some css code */  }}
复制代码

结语


虽然Grid的使用起来很简单,但是在哪些场景可以使用Grid能够带来更好的收益却是需要进行进一步思考的,而且也并不是用了Grid就要抛弃其他的的布局方法,这就需要使用者根据实际情况来因地制宜,灵活运用了。


头图:Unsplash

作者:翁斌斌

原文:https://mp.weixin.qq.com/s/GpQOMVYBRK80x0I8jtmefQ

原文:迈向 Grid 二维布局时代

来源:微医大前端技术 - 微信公众号 [ID:wed_fed]

转载:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2021-06-14 08:002223

评论 1 条评论

发布
用户头像
firebox还是firefox?
2021-06-18 10:57
回复
没有更多了
发现更多内容

Spring 源码学习 - @Async注解实现原理

公众号:好奇心森林

Spring Boot aop

搞定 HTTP 协议(三):如何严谨地描述一个 HTTP 报文?

零和幺

https HTTP

架构师训练营-第 03 周作业提交

Eric

极客大学架构师训练营

技术学习进阶(死磕法)

dudu

学习 技术

程序员的晚餐 | 6 月 21 日 自制小火锅

清远

美食

设计模式练习及感想(训练营第三课)

看山是山

设计模式 极客大学架构师训练营

十万同时在线用户,需要多少内存?——Newbe.Claptrap 框架水平扩展实验

newbe36524

架构师训练营 - 第 02 周学习总结

Eric

Go:使用Delve和Core Dump来调试

陈思敏捷

debug gdb Go 语言

故障演练利器之ChaosBlade介绍

心平气和

故障演练 故障注入

信息的表示与存储-整数的运算

引花眠

计算机基础

三周作业

飞雪

第三周总结

Geek_5d0795

极客大学架构师训练营

ARTS打卡 第4周

引花眠

ARTS 打卡计划

架构师训练营-第 02 周作业

Eric

week3 学习总结

任小龙

ARTS-WEEK4

一周思进

ARTS 打卡计划

架构师训练营第 3 周 _ 课后作业

方舟勇士

课程作业

区块链中的“链上”和“链下”

CECBC

区块链技术 分布式身份标识 难以篡改

架构师训练营-第 03 周总结

Eric

极客大学架构师训练营

架构师训练营 - 第三周作业

teslə

架构师训练营第三周作业

CATTY

week3 命题作业

任小龙

易纲:上海可以在人民币自由兑换等方面先行先试

CECBC

数字货币 区块链技术 金融科技中心

138 张图带你 MySQL 入门

cxuan

MySQL 数据库

架构师训练营 - 第三周总结

teslə

ARTS 第 3 周

乌拉里

单例模式和组合模式

鲁米

代码重构-学习总结

飞雪

Open-Falcon安装注意事项

wong

Open-Falcon Nightingale Monitor

ARTS-WEEK3

Allen

迈向 Grid 二维布局时代_语言 & 开发_微医大前端技术_InfoQ精选文章