Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >124. 精读《用 css grid 重新思考布局》

124. 精读《用 css grid 重新思考布局》

作者头像
黄子毅
发布于 2022-03-14 09:15:43
发布于 2022-03-14 09:15:43
6130
举报
文章被收录于专栏:前端精读评论前端精读评论

1 引言

Flex 与 Grid 相比就像功能键盘和触摸屏。触摸屏的控制力相比功能键盘来说就像是降维打击,因为功能键盘只能上下左右控制(x、y 轴),而触摸屏打破了布局障碍,直接从(z 轴)触达,这样 无论 UI 内部布局再复杂,都可以通过 touch 直接定位。

Flex 是一维布局方式,我们需要不断嵌套 Div 才能形成复杂结构,而一旦布局产生了变化,原有嵌套结构如果不能 “兼容变化” 到新结构,代码就需要重构。而 Grid 就像触摸屏一样,可以二维布局,即便布局方式做了翻天覆地的调整,也仅需少量修改就能适配。

这就是这次精读 用 css grid 重新思考布局 的原因,理解这个革命性布局技术给布局,甚至代码逻辑组织带来的变化。

2 概述

作者首先抛出了 Flex 的问题,其实是 block float flex 这三种布局模式的通病:

  • 布局结构由 Div 层级结构描述,导致 Div 层级复杂且遇到结构变更时难以维护。
  • 定制能力弱。Flex 布局有一些不受控制的智能设定,比如宽度 50% 的子元素会被同级元素挤到 50% 以下,这种智能化在某些场景是需要的,但由于没有提供像 Grid 的 minmax 之类的 API,所以定制型不足。

举个例子,上图的结构用 Flex 描述可能是这样的:

代码语言:javascript
AI代码解释
复制
<div class="card">
  <div class="profile-sidebar">
    <img src="https://i.pravatar.cc/125?image=3" alt="" class="profile-img" />
    <ul class="social-list">
      <li>
        <a href="#" class="social-link"
          ><i class="fab fa-dribbble-square"></i
        ></a>
      </li>
      <li>
        <a href="#" class="social-link"
          ><i class="fab fa-facebook-square"></i
        ></a>
      </li>
      <li>
        <a href="#" class="social-link"
          ><i class="fab fa-twitter-square"></i
        ></a>
      </li>
    </ul>
  </div>
  <div class="profile-body">
    <h2 class="profile-name">Ramsey Harper</h2>
    <p class="profile-position">Graphic Designer</p>
    <p class="profile-info">
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Facere a tempore,
      dignissimos odit accusantium repellat quidem, sit molestias dolorum
      placeat quas debitis ipsum esse rerum?
    </p>
  </div>
</div>

利用 HTML 嵌套结构,我们将图形纵向分成两大块,然后在每块内部继续嵌套划分布局,这是最经典的布局行为了。

样式文件里,我们需要对每层布局进行描述,同时支持多分辨率弹性布局,包括顶层 card 容器在内的一些样式需要做一定调整:

代码语言:javascript
AI代码解释
复制
.card {
  width: 80%;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  max-width: 600px;
  background: #005e9b;
  flex-basis: 250px;
  color: white;
  padding: 2em;
  text-align: center;
}

.profile-info {
  font-weight: 300;
  opacity: 0.7;
}

.profile-sidebar {
  margin-right: 2em;
  text-align: center;
}

.profile-name {
  letter-spacing: 1px;
  font-size: 2rem;
  margin: 0.75em 0 0;
  line-height: 1;
}

.profile-name::after {
  content: "";
  display: block;
  width: 2em;
  height: 1px;
  background: #5bcbf0;
  margin: 0.5em auto 0.65em;
  opacity: 0.25;
}

.profile-position {
  text-transform: uppercase;
  font-size: 0.875rem;
  letter-spacing: 3px;
  margin: 0 0 2em;
  line-height: 1;
  color: #5bcbf0;
}

.profile-img {
  max-width: 100%;
  border-radius: 50%;
  border: 2px solid white;
}

.social-list {
  list-style: none;
  justify-content: space-evenly;
  display: flex;
  min-width: 125px;
  max-width: 175px;
  margin: 0 auto;
  padding: 0;
}

.social-link {
  color: #5bcbf0;
  opacity: 0.5;
}

.social-link:hover,
.social-link:focus {
  opacity: 1;
}

.bio {
  padding: 2em;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

@media (min-width: 450px) {
  .bio {
    text-align: left;
    max-width: 350px;
  }
}

.bio-title {
  color: #0090d1;
  font-size: 1.25rem;
  letter-spacing: 1px;
  text-transform: uppercase;
  line-height: 1;
  margin: 0;
}

.bio-body {
  color: #555;
}

.profile {
  display: flex;
  align-items: flex-start;
}

@media (min-width: 450px) {
  .card {
    flex-direction: row;
    text-align: left;
  }

  .profile-name::after {
    margin-left: 0;
  }
}

让我们看看 Grid 是怎么做的吧!Grid 有许多 API,我们重点看 grid-template-areas 这个属性,利用它,我们可以不关心模块的 HTML 结构,直接平铺方式描述:

代码语言:javascript
AI代码解释
复制
<div class="card">
  <img src="https://i.pravatar.cc/125?image=3" alt="" class="profile-img" />
  <ul class="social-list">
    <li>
      <a href="#" class="social-link"><i class="fab fa-dribbble-square"></i></a>
    </li>
    <li>
      <a href="#" class="social-link"><i class="fab fa-facebook-square"></i></a>
    </li>
    <li>
      <a href="#" class="social-link"><i class="fab fa-twitter-square"></i></a>
    </li>
  </ul>
  <h2 class="profile-name">Ramsey Harper</h2>
  <p class="profile-position">Graphic Designer</p>
  <p class="profile-info">
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Facere a tempore,
    dignissimos odit accusantium repellat quidem, sit molestias dolorum placeat
    quas debitis ipsum esse rerum?
  </p>
</div>

可以看到,使用 Grid 可以将 UI 结构与 HTML 结构分离,HTML 结构仅描述包含关系,我们只需在样式文件中描述具体 UI 结构。

样式文件只截取 Grid 相关部分:

代码语言:javascript
AI代码解释
复制
.card {
  width: 80%;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  max-width: 600px;
  background: #005e9b;
  flex-basis: 250px;
  color: white;
  padding: 2em;
  text-align: left;

  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-column-gap: 2em;
  grid-template-areas:
    "image name"
    "image position"
    "social description";
}

.profile-name {
  grid-area: name;
}
.profile-position {
  grid-area: position;
}
.profile-info {
  grid-area: description;
}
.profile-img {
  grid-area: image;
}
.social-list {
  grid-area: social;
}

可以看到,grid-template-areas 是进一步抽象的语法,将页面结构通过直观的文本描述,无论是理解还是修改都更为轻松。

这种描述方式适配不同分辨率下也具有优势,只要重组 grid-template-areas 即可:

代码语言:javascript
AI代码解释
复制
@media (min-width: 600px) {
  .card {
    text-align: left;
    grid-template-columns: 1fr 3fr;
    grid-template-areas:
      "image name"
      "image position"
      "social description";
  }
}

归根结底,Grid 通过二维结构描述,将子元素布局控制收到了父级,使布局描述更加直观。

最后作者也提到,Flex 依然有使用场景,即简单的一维结构,或者 space-between 等 Flex 独有语法的情况。因此推荐整体、复杂的二维布局采用 Grid,一维的简单布局采用 Flex。

3 精读

Grid 的布局思路给了我很多启发,HTML 结构与 UI 结构的分离有助于减少 DIV 的层级结构,使代码看上去更清晰。

也许有人会疑惑,Grid 无非将 HTML 布局部分功能挪到了 CSS,整体复杂度应该不变。其实,从 grid-template-areas 这个 API 可以看到,Grid 不仅仅将布局功能抽到 CSS 中,更是将布局描述进行了一层抽象,使代码更易维护。

抽象,再抽象

为什么 Grid 可以对布局进行抽象?因为 Grid 将二维结构都掌握在手中,得到了更大的布局能力,才能进一步将结构化语法抽象为字符串的描述。

抽象的好处是不言而喻的,你觉得一堆嵌套的 DIV 与下面的代码,哪个更易读呢?

代码语言:javascript
AI代码解释
复制
.card {
  grid-template-areas:
    "image name"
    "image position"
    "social description";
}

这就是抽象的好处,一般来说,代码抽象程度越高就越易读,越易维护。

再看一个 Chrome Grid 插件,将 Grid 可视化显示出来,并可以以 UI 方式进行调整:

UI 是对文本的再抽象,同时可以规避一些不可能存在的语法,比如:

代码语言:javascript
AI代码解释
复制
.card {
  grid-template-areas:
    "image name"
    "image position"
    "social image";
}

布局只能以凸多边形方式拓展,不可能分离,也不可能突然插入一个其他模块而变成凹多边形。因此 UI 可以将这个错误规避,并简化为横竖多条线的方式对 UI 进行划分,显然这种描述方式效率更高。

不得不说,Grid 以及图形化插件的探索,是布局领域的一大进步,是不断抽象的尝试,要解决的问题只有一个:如何提供一种更直观的描述 UI 的方式。

布局对模块化的影响

Grid 将布局方式提高了一个维度,会直接影响到 JS 模块化方式。

尤其是以 JSX 组织代码的情况下,一个模块等于 UI + JS,通过嵌套方式的布局会让我们更倾向于站在 UI 视角划分模块。

比如对于上图模块,如果用 Flex 方式布局,我们可能会首先创建模块 X 作为左侧容器,子元素是 A 和 B,创建模块 Y 作为右侧容器,子元素是 C 以及新容器 Z,Z 容器的子元素是 D 和 E。

如果你的第一印象是这么组织代码,不得不承认模块化会受到布局方式的影响。虽然许多时候这样划分是正确的,但当这 5 个模块各自没有关联时,我们创建的容器 X、Y、Z 就失去了复用性,在新的组合场景我们又要重新组合一遍。

但是在 Grid 语法中,我们不需要 X、Y、Z,只需要用 css grid generator 按照上图的方式拖拖拽拽即可自动生成如下布局代码:

代码语言:javascript
AI代码解释
复制
.parent {
  display: grid;
  grid-template-columns: 3fr repeat(2, 1fr);
  grid-template-rows: repeat(5, 1fr);
  grid-column-gap: 0px;
  grid-row-gap: 0px;
}

.div1 {
  grid-area: 1 / 1 / 3 / 2;
}
.div2 {
  grid-area: 3 / 1 / 6 / 2;
}
.div3 {
  grid-area: 1 / 2 / 2 / 4;
}
.div4 {
  grid-area: 2 / 2 / 6 / 3;
}
.div5 {
  grid-area: 2 / 3 / 6 / 4;
}

其实 grid-template-columns grid-template-rows 组合起来使用比 grid-template-areas 更强大,但是纯代码方式描述没有 grid-template-areas 直观,可是配合一些可视化系统就非常直观了:

将 A ~ E 这 5 个模块布局抽出来后,它们之间的关系就打平了,我们可以完全从逻辑视角审视如何做模块化了。

4 总结

CSS Grid 本质上是一种二维布局的语法,相比 Block、Flex 等一维布局方案,多了一个维度可以同时从行与列角度定义布局,因此派生出 grid-template-areas 等语法,整体上更内聚更直观,抽象度也更高了。

理解了这些也就理解了布局未来的发展方向,让布局与 Dom 分离 一直是前端的一个梦想,开发 UI 部分时,只需关心页面由哪些模块组成,去实现这些模块就行了,而不需要关心模块之间应该如何组合。在描述组合时,可以通过可视化或比较抽象的字符串描述布局的结构,并对应到写好的模块上,这样的代码维护性远高于用 DIV 描述结构的方案。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端精读评论 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
如何使用Flexbox和CSS Grid,实现高效布局
CSS 浮动属性一直是网站上排列元素的主要方法之一,但是当实现复杂布局时,这种方法不总是那么理想。幸运的是,在现代网页设计时代,使用 Flexbox 和 CSS Grid 来对齐元素,变得相对容易起来。
葡萄城控件
2022/05/09
4.6K0
如何使用Flexbox和CSS Grid,实现高效布局
【CSS】343- CSS Grid 网格布局入门
CSS Grid(网格) 布局使我们能够比以往任何时候都可以更灵活构建和控制自定义网格。Grid(网格) 布局使我们能够将网页分成具有简单属性的行和列。
pingan8787
2019/09/09
2.4K0
【CSS】343- CSS Grid 网格布局入门
Grid布局简介
没错,这其实就是我们小时候写的小格子本本,其实它跟我们今天要讲的主题Grid布局非常类似,其实Grid布局就是它的升级加强版。
桃翁
2018/08/16
7.8K2
Grid布局简介
CSS 中的 Grid 布局 完全指南
Grid 是一个基于二维网格布局的系统,有了它我们可以非常方便的实现过去很复杂布局,无需再使用float, inline-block, position 这些本质上是 hack 的方法。
羽月
2022/10/08
4.7K0
CSS 中的 Grid 布局 完全指南
CSS进阶12-网格布局 Grid Layout
(注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!) (注2:更多内容请查看我的目录。)
love丁酥酥
2018/08/27
6.8K0
CSS进阶12-网格布局 Grid Layout
10分钟理解CSS3 Grid
上一篇文章我们介绍了 css3 flexbox,今天我们再来说说css3的另外一个强大的功能:Grid。 Grid做前端的同学应该都很熟悉了,翻译成中文为“栅格”,用过bootstrap、semantic ui、ant design的同学肯定都了解grid layout(删格布局),以往css框架中的grid布局一般是通过float和百分比的宽度实现的,这种实现有几种缺点:
MudOnTire
2019/05/26
8810
grid网格布局
​ 距今来看已经十多年了,确确实实占据了前端布局中很大的地位,相比大家对flex都很熟悉,所以今天我们的主角就是-------> Grid
Snine
2022/02/11
2.3K0
grid网格布局
全栈之前端 | 6.CSS3基础知识之网页几种布局方法学习(1)
描述: 前面相信大家已经跟着【WeiyiGeek】作者一起学习了CSS基础知识了,并且了解了盒子模型、以及元素的定位浮动方面的知识。现在我们在此基础上继续深入学习CSS布局,它是学习CSS之路上一个重点,是在进行前端开发时常常使用到的,所以说我们需要认真学习,若有不懂的地方可以在文章末尾,以及作者交流群【在公众号回复微信交流群】进行留言交流。
全栈工程师修炼指南
2023/10/31
1.8K0
全栈之前端 | 6.CSS3基础知识之网页几种布局方法学习(1)
【CSS】Grid 栅格布局学习笔记
使用display:grid或display:inline-grid即可创建一个栅格容器,这个容器下的所有直接子节点都会成为栅格项(Grid Item)。
前端修罗场
2023/10/07
5440
【CSS】Grid 栅格布局学习笔记
Grid layout + 媒体查询轻易实现常用的响应式布局
最近在整理前端知识体系,怎么可以少了布局这一环呢?先问大家一个问题,如果让css只保留一种布局,留下来解决前端布局问题?你会选择那个布局呢?如果问我,我会选择 网格布局,根据二八原则,网格布局基本上可以帮助我解决 80% 的布局场景,颇有一套布局打遍天下布局的气势,因此非常值得一探究竟。
老码小张
2023/11/28
1.3K0
Grid layout + 媒体查询轻易实现常用的响应式布局
最强大的 CSS 布局 —— Grid 布局
Grid 布局即网格布局,是一种新的 CSS 布局模型,比较擅长将一个页面划分为几个主要区域,以及定义这些区域的大小、位置、层次等关系。号称是最强大的的 CSS 布局方案,是目前唯一一种 CSS 二维布局。利用 Grid 布局,我们可以轻松实现类似下图布局,演示地址[1]
GopalFeng
2020/09/24
26.4K0
最强大的 CSS 布局 —— Grid 布局
【CSS】最强大的布局之grid布局精讲
轮播图swiper框架的基本使用 【Transform3D】转换详解(看完就会) 【css动画】移动的小车
坚毅的小解同志的前端社区
2022/11/28
3.4K0
【CSS】最强大的布局之grid布局精讲
一次性把所有普通和经典的网页布局讲得通通透透的,多图预警,建议收藏
超干货长文预警。这次把网页布局方案讲得通通透透的,等高布局,水平垂直居中,经典的圣杯布局等等全都有了。建议收藏
夜尽天明
2020/09/17
6.4K0
一次性把所有普通和经典的网页布局讲得通通透透的,多图预警,建议收藏
11·灵魂前端工程师养成-CSS最强大的布局Grid
-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。
DriverZeng
2022/09/26
2440
11·灵魂前端工程师养成-CSS最强大的布局Grid
CSS3中Grid布局
Grid 布局与Flex 布局有一定的相似性,都可以指定容器内部多个项目的位置。但是,它们也存在重大区别。
码客说
2023/08/17
8430
CSS3中Grid布局
【Web前端】项目实训:CSS基本布局理解
对CSS学习已经接近尾声,下面你可以对以下两道“小卡拉米”测试进行测试下CSS理解程度。
一条晒干的咸鱼
2024/11/19
8150
【Web前端】项目实训:CSS基本布局理解
使用网络构建复杂布局超实用的技巧,赶紧收藏吧!
作者:Shadid Haque 译者:前端小智 来源:soshace 点赞再看,微信搜索 【大迁世界】 关注这个没有大厂背景,但有着一股向上积极心态人。本文 GitHub https://github.com/qq44924588... 上已经收录,文章的已分类,也整理了很多我的文档,和教程资料。 1024程序员节,160就能买到400的书,红宝书 5 折 网格布局是现代CSS中最强大的功能之一。使用网格布局可以帮助我们在没有任何外部 UI 框架的情况下构建复杂的、快速响的布局。在这篇文章中,将会介绍所有
前端小智@大迁世界
2020/10/30
1.4K0
使用网络构建复杂布局超实用的技巧,赶紧收藏吧!
CSS Grid 新手入门
另外,下面一段话摘自A Complete Guide to Grid,对于CSS Grid会有更加清楚地释义
糊糊糊糊糊了
2018/09/28
2.4K0
CSS Grid 新手入门
万字总结 CSS 布局
本文总结了主流的几种 CSS 的布局方法,无论你是一个想要学习 CSS 布局的新手,还是一个比较有经验但想要进一步巩固与了解最新CSS布局知识的前端开发者,这篇指南都能帮你全面了解如今CSS布局发展的现状。
用户8921923
2022/10/24
6.8K0
万字总结 CSS 布局
grid布局了解一下
首先,看一张图,了解一下容器和项目(不难理解,容器就是包在外层的元素,项目就是内部的元素)
用户4793865
2023/01/12
5990
grid布局了解一下
相关推荐
如何使用Flexbox和CSS Grid,实现高效布局
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
首页
学习
活动
专区
圈层
工具
MCP广场
首页
学习
活动
专区
圈层
工具
MCP广场