写点什么

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

评论 1 条评论

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

5分钟学会本地Pypi源搭建

Python研究所

Python

相约山城重庆!HarmonyOS Connect伙伴峰会将于7月16日举办

科技汇

“京东商城”亿级高并发秒杀系统到底是怎么设计的?自己做该如何下手?

Java架构师迁哥

区块链时代下,企业如何打造数据要素的“新竞争力”?

CECBC

阿里P8手抄本惨遭泄露,并出现病毒式传播,致28人斩获大厂offer

Java架构师迁哥

“用友 • 华为云杯”第三届企业云服务开发者大赛

ToB行业头条

开发者 低代码 用友

【架构实战营】第 7 模块作业

swordman

架构实战营

聊聊事务与分布式系统-从零讲到通透

刘绍

sql 分布式 事务 2PC XA

百度搜索稳定性问题分析的故事(上)

百度开发者中心

百度搜索

Flink进入大厂面试准备,收藏这一篇就够了

五分钟学大数据

flink 7月日更

3分钟评估 你的运维监控系统是“救命稻草”还是“鸡肋”

鹿小U

运维自动化 监控系统 运维平台

云南智慧公安研判分析系统搭建,重点人员研判分析平台

底层技术支撑智慧出行,汽车智能化发展下区块链大放异彩

CECBC

【Redis】数据结构

awen

redis 数据结构

北鲲云助力生命科学,高性能计算突破屏障

北鲲云

接任务时一定要锁定需求啊!(转自小明同学)

BinTools图尔兹

数据库 dba 国产数据库 运维开发

正式发布!中国首个LF Edge捐赠项目Baetyl 2.2发布

百度开发者中心

物联网 开源技术

香帅:2021年财富格局新变化

石云升

读书笔记 7月日更

网络攻防学习笔记 Day68

穿过生命散发芬芳

网络攻防 7月日更

我是如何从设计师转到软件行业的? | 可怜巴巴的程序猿

Python研究所

随笔 话题讨论

每天学习10个实用Javascript代码片段(三)

devpoint

JavaScript JSON格式化 7月日更

技术干货 | 录屏采集实现教程 —— Android端

ZEGO即构

大前端 音视频 录屏采集 Android端

图的应用——拓扑排序

若尘

数据结构 拓扑排序

爆款阿里P5到P7晋升之路,九大源码文档助我超神果然努力幸运并存

Java BAT

构筑智能制造时代“四重护城河”,联想中国开创产业新格局

科技大数据

CDH 的安装(四)

大数据技术指南

CDH 7月日更

Clickhouse Projection 特性探索

GrowingIO技术专栏

数据库 大数据 数据分析 OLAP Clickhouse

模块七 - 王者荣耀商城异地多活架构设计

华仔架构训练营

5分钟速读之Rust权威指南(三十八)模板语法

wzx

rust

Redis学习之Redis概述及原理、基本操作及持久化

Linux服务器开发

redis 分布式 后端 中间件 Linux服务器开发

MindSpore教程免费学,还有入门奖品

Geek_6cdeb6

人工智能 机器学习 深度学习 自我提升 羊毛

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