2 月 6 日 14:00 低代码 |GMTC 北京 2023 专场直播 戳此预约 >>> 了解详情
写点什么

迈向 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:002008

评论 1 条评论

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

JVM空间分配担保机制

W🌥

Java JVM 8月日更

《社会心理学》-怎样说服他人?

箭上有毒

8月日更

架构课程第4次作业

听闻

二叉查找树的迭代遍历

泽睿

二叉树

没有银弹

escray

学习 极客时间 如何落地业务建模 8月日更

【设计模式】备忘录模式

Andy阿辉

C# 编程 后端 设计模式 8月日更

随机字符串,随机密码生成器

入门小站

工具

占楼

IT蜗壳-Tango

8月日更

JavaScript new 关键词解析及原生实现 new

zhoulujun

JavaScript new

select、poll、epoll之间的区别

一个大红包

8月日更

消息队列架构设计

thewangzl

架构实战营 毕业设计项目

梦寻解语花

架构实战营

模块五作业

秀聪

架构训练营

可视化接口管理平台 YApi,让你轻松搞定 API 的管理问题

xcbeyond

工具 接口管理 YAPI 8月日更

毕业总结

梦寻解语花

架构实战营

传统企业数字化转型的三大技术误区

码猿外

数字化转型 敏捷精益

5000字阐述云原生消息中间件Apache Pulsar的核心特性和设计概览

王知无

企业研发效能提升之道 —— 管中窥豹,窥一斑而知全豹

在天涯的海角

研发效能

架构实战营毕业设计

林子钧

架构实战营 毕业设计

TypeScript那些最佳实践

思诚^_^

typescript

讲透学烂二叉树(四):二叉树的存储结构—建堆-搜索-排序

zhoulujun

二叉树 堆排序 二叉堆 二叉堆排序 二叉树排序

现代分布式架构设计原则-伸缩性

余朋飞

可伸缩 伸缩 弹性扩容

QDS05 Prometheus

耳东@Erdong

Prometheus 8月日更

架构实战营毕业总结

林子钧

架构实战营 毕业总结

MinIO存储服务客户端使用指南(三)

liuzhen007

8月日更

instanceof运算符的实质:Java继承链与JavaScript原型链

zhoulujun

JavaScript 继承 原型链 instanceof 继承链

Linux之scp命令

入门小站

Linux

10篇校招/社招面经请你查收~

王知无

讲透学烂二叉树(五):分支平衡—AVL树与红黑树伸展树自平衡

zhoulujun

二叉树 平衡二叉树 红黑树

讲透学烂二叉树(六):二叉树的笔试题:翻转|宽度|深度

zhoulujun

二叉树 二叉树遍历 二叉树翻转

讲透学烂二叉树(三):二叉树的遍历图解算法步骤及JS代码

zhoulujun

二叉树 二叉树遍历 前序遍历 中序遍历 后续遍历

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