震惊!很多人都不知道 CSS Grid 框架早就有了!

前言
写作本文起源于知乎的一个问题:【CSS Grid 布局那么好,为什么至今没有人开发出基于 Grid 布局的前端框架呢?】
这篇文章拖沓了两个月,是因为真的不知道从哪里说好。这个问题的所有回答几乎都没有切中问题的本质,而且对 CSS Grid 也有很深的误解。另外这个问题的描述可能不太恰当,因为基于 CSS Grid 的框架已经有了。感兴趣的朋友可以了解一下 Flex-Layout,它是一个基于指令布局的神器。大家不要被项目名误导,虽然叫 flex-layout,其实有 flex 和 grid 两种指令。
我觉得这个问题更恰当的描述应该是【为什么没有基于 Grid 布局的纯 CSS 前端框架呢】,基于 Float 和 Flex 的 CSS 布局框架多如牛毛,但是一直没看到基于 CSS Grid 的实现。我在写 Snack 的时候也曾考虑过在 v3 版本中整合 CSS Grid,但是后来发现有些不现实,下文详述。据说 Bootstrap 也曾打算在 v5 版本整合 CSS Grid,但是目前来看依然沿用了 Flex 布局。我个人觉得基于指令实现的 flex-layout 应该是整合 CSS Grid 的最佳方式。
本文打算从相反的角度聊一聊,假如要实现一个基于 CSS Grid 的布局框架,我们会遇到哪些问题呢?
浏览器兼容性
先说一下兼容性,很多人总觉得 CSS Grid 的兼容性不行。其实不然,下图的统计数据能够看出大部分浏览器对 CSS Grid 的支持还是不错的,要知道 Flex 在 IE10 上面可以使用的属性也非常有限。据统计目前 CSS Grid 使用率和 Flex 已经基本持平了。所以兼容性并不能回答开篇提出的问题。


CSS 布局框架的特点
CSS 布局主要有四种,上古时期用的是 table,这个就不说了,我们只讨论新世纪常用的 Float、Flex、Grid。这三种布局方式就是递进的关系,逐步加强了 CSS 布局的便利性。CSS 布局的最佳实践当属 Bootstrap,其中 Float 和 Flex 布局方案都已经被 Bootstrap 实现,唯独 Grid 方案迟迟不见踪影。
CSS 布局框架的关键在于如何设计栅格,我们先看看在 Bootstrap 中是怎么进行布局的。
<div class="row">
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
</div>
<div class="row">
  <div class="col-md-8">.col-md-8</div>
  <div class="col-md-4">.col-md-4</div>
</div>
<div class="row">
  <div class="col-md-4">.col-md-4</div>
  <div class="col-md-4">.col-md-4</div>
  <div class="col-md-4">.col-md-4</div>
</div>
<div class="row">
  <div class="col-md-6">.col-md-6</div>
  <div class="col-md-6">.col-md-6</div>
</div>
用过 Bootstrap 的人对以上结构一定不陌生。在 Bootstrap v4 中,由于 Flex 布局功能的增强,row 也可以搭配 utility 使用。
<div class="row align-items-start">
  <div class="col">One of three columns</div>
  <div class="col">One of three columns</div>
  <div class="col">One of three columns</div>
</div>
<div class="row align-items-center">
  <div class="col">One of three columns</div>
  <div class="col">One of three columns</div>
  <div class="col">One of three columns</div>
</div>
<div class="row align-items-end">
  <div class="col">One of three columns</div>
  <div class="col">One of three columns</div>
  <div class="col">One of three columns</div>
</div>
row 和 col 的组合几乎已经成为栅格布局的共识和标准。接下来我们就用这种设计方式手撕一个 Grid 栅格看看效果。
手撕 CSS 布局栅格
其实手撕一个 CSS 布局栅格并不难,关键是要熟悉预处理器的循环功能。下面我们分别用 Float、Flex 及 Grid 实现一个简化版的栅格布局并对比一下它们之间的差异。
Float
Float 是过去实现流体布局的唯一方式,难点在于处理父元素的塌陷,这算是一个老生常谈的问题了,本文不再赘述。以下是一个简易版的 Float 栅格:
See the Pen float-columns by Zongbin (@nzbin)
  on CodePen.
这种栅格简单实用,堪称经典。但是 Float 布局的局限性很大,如果栅格的高度不相同(比如将第一个栅格的高度加高),布局就会出现塌陷。
Flex
Flex 的诞生几乎解决了 Float 栅格的所有痛点,比如上面提到的塌陷问题。以下是一个简易版的 Flex 栅格:
See the Pen flex-columns by Zongbin (@nzbin)
  on CodePen.
其实在一维布局中,Flex 已经足够好用,至少在流体布局中没发现需要改进的地方,所以我们是否还有必要引入二维布局方案?
Grid
重点来了!重点来了!重点来了!
Grid 是比 Flex 更高级的布局技术,所以单纯替换 Flex 实现一套栅格布局系统完全没有问题。以下是一个极其简易的 Grid 栅格,几乎和 Flex 栅格的效果没有区别。
See the Pen grid-columns by Zongbin (@nzbin)
  on CodePen.
Grid 除了能实现 Flex 的布局之外,还可以在纵向空间对每一行进行调整(比如设置 grid-template-rows: 1fr 2fr)。另外,Grid 设置其它列数的栅格也比较容易,比如设置 10 列栅格,只需要设置 grid-template-columns: repeat(10, 1fr) 即可;如果是 Flex,则需要重新计算栅格的宽度。
上面示例中展示的 CSS Grid 的功能只是冰山一角。作为一个二维布局技术,它的属性写法非常繁杂,比如另外一个强大的功能 grid-template-areas MDN Demos。这种属性定义方式很难使用类名的叠加组合实现对应的功能。
如果只是简单地将 Flex 栅格替换成 Grid 栅格,我个人感觉意义不大,一个基于 CSS Grid 全新的栅格系统应该尽可能的发挥它所有的优势。这或许就是 CSS Grid 栅格系统迟迟没有出现的原因吧。我不知道文章写到这里是否清楚的表达了我的观点,或者说能否解答大家对于开篇问题的疑惑。接下来再看看 flex-layout 中的 Grid。
Flex-Layout 中的 Grid
因为 flex-layout 是基于指令的实现,所以不像类名叠加的方式那样有很大的局限性,几乎可以发挥 CSS Grid 的全部优势。以下就是 grid-template-areas 的定义方法。
<div gdAreas.xs="header | sidebar | content | sidebar2 | footer" gdGap="1em"
     gdColumns.xs="none"
     gdAreas.sm="header header | sidebar content | sidebar2 sidebar2 | footer footer"
     gdColumns.sm="20%!"
     gdAreas.gt-sm="header header header | sidebar content sidebar2 | footer footer footer"
     gdColumns.gt-sm="120px auto 120px" gdGap.gt-sm="20px" [ngStyle]="{'max-width': 'auto'}"
     [ngStyle.gt-sm]="{'max-width': '600px'}">
  <div class="blocks one" gdArea="header">Header</div>
  <div class="blocks two" gdArea="sidebar">Sidebar</div>
  <div class="blocks three" gdArea="sidebar2">Sidebar 2</div>
  <div class="blocks four" gdArea="content">Content
    <br /> More content than we had before so this column is now quite tall.</div>
  <div class="blocks five" gdArea="footer">Footer</div>
</div>
flex-layout 无论是设计思路还是实现方式都让我顶礼膜拜,它与传统的 Bootstrap 形式的栅格有着本质区别。本文的重点不是介绍 flex-layout,如果大家感兴趣,还是看官网介绍吧 Flex-Layout。
总结
酝酿了两个月个文章,感觉还是没有把自己的观点表达清楚。回到问题本身,【为什么没有基于 Grid 布局的纯 CSS 前端框架呢】,个人觉得最主要的还是传统写法无法发挥 CSS Grid 的全部优势,至少用以往的类叠加方式是无法做到的。CSS Grid 属性的特殊性也决定了不可能也不应该只是单纯的叠加类名。
震惊!很多人都不知道 CSS Grid 框架早就有了!的更多相关文章
- 很多人都在埋怨没有遇到好的团队,但好的团队不可能凭空出现,一流的团队不能仅靠团队成员努力,作为Leader,要有可行的规划,并坚定地执行、时势地调整(转)
		
<西游记>中的唐僧团队历经千难万险,终于求得真经,目标明确.分工合理为这支队伍最终走向成功奠定了基础.唐僧从一开始,就为这个团队设定了西天取经的目标,虽然经历各种挫折与磨难,但目标从未动摇 ...
 - 上传伪技术~很多人都以为判断了后缀,判断了ContentType,判断了头文件就真的安全了。是吗?
		
今天群里有人聊图片上传,简单说下自己的经验(大牛勿喷) 0.如果你的方法里面是有指定路径的,记得一定要过滤../,比如你把 aa文件夹设置了权限,一些类似于exe,asp,php之类的文件不能执行,那 ...
 - [转帖](区块链补习班)ERC20很多人都听过,但ERC是什么你真的了解吗?
		
(区块链补习班)ERC20很多人都听过,但ERC是什么你真的了解吗? http://baijiahao.baidu.com/s?id=1600948969290990883&wfr=spide ...
 - 这个 Spring 循环依赖的坑,90% 以上的人都不知道
		
1. 前言 这两天工作遇到了一个挺有意思的Spring循环依赖的问题,但是这个和以往遇到的循环依赖问题都不太一样,隐藏的相当隐蔽,网络上也很少看到有其他人遇到类似的问题.这里权且称他非典型Spring ...
 - 听说特斯拉花了4个月研发出新ERP,然后很多人都疯了
		
欢迎关注微信公众号:sap_gui (ERP咨询顾问之家) 最近这件事儿在SAP圈里炒的挺火的,最主要是因为这几个关键词: 放弃SAP.4个月.自研ERP: 这则新闻一出来,很多人都兴高采烈,都要疯了 ...
 - 很多人都搞不清楚C语言和C++的关系!今天我们来一探究竟为大家解惑~
		
最近,身边有许多小伙伴已经开始学习编程了,但是呢,学习又会碰到许多的问题,其中作为新手小白提到最多的问题就是编程语言的选择. 每次遇到这种问题,看起来很简单,但是又有很多小伙伴搞不清编程语言之间的关系 ...
 - 一道月薪3W的java面试题 (小明和小强都是张老师的学生,张老师的生日是某月某日,2人都不知道张老师的生日)
		
小明和小强都是张老师的学生,张老师的生日是M月N日,2人都知道张老师的生日 是下列10组中的一天,张老师把M值告诉了小明,把N值告诉了小强,张老师问他们知道他的生日是那一天吗? 3月4日 3月5日 3 ...
 - 7个现在就该学习Python 的理由【80%的人都不知道】
		
Python 是一门更注重可读性和效率的语言,尤其是相较于 Java,PHP 以及 C++ 这样的语言,它的这两个优势让其在开发者中大受欢迎. 诚然,它有点老了,但仍是 80 后啊 —— 至少没有 C ...
 - 原来现在很多人都用SignalR来实现Chat Room
		
今天从一个业余开发的群里,看到有人要求这样一个项目需求: 1,)学员可以通过在线课堂找到自己喜欢的老师和课程. 2,)每个人可以建立自己课堂,每个课堂扣分多个子房间,交流群.设置管理员:有录音功能,可 ...
 
随机推荐
- C++vector and opencv Mat
			
转载:https://blog.csdn.net/u012507022/article/details/50979011?utm_source=blogxgwz5 最近在写Opencv程序,用到离散小 ...
 - P4279 [SHOI2008]小约翰的游戏(Anti_nim)
			
Link 题面 题目描述 小约翰经常和他的哥哥玩一个非常有趣的游戏:桌子上有 \(n\) 堆石子,小约翰和他的哥哥轮流取石子,每个人取的时候,可以随意选择一堆石子, 在这堆石子中取走任意多的石子,但不 ...
 - 一键安装PyCharm
			
1.准备阶段,首先去官网下载:https://download.jetbrains.8686c.com/python/pycharm-professional-2019.1.exe 官网地址:http ...
 - Excel-VLOOKUP函数跨表匹配查找①
			
问题场景 对表中的员工进行测评总结,从所有员工考核明细表中匹配这些参与测评的员工的得分和相关信息: 场景一 从所有员工明细表中匹配需要参与测评的员工相关信息. 建了两个sheet页,考核员工表和全员考 ...
 - JavaScript reduce()的使用
			
语法 arr.reduce(callback(accumulator, currentValue, index, array), initialValue) 参数 callback 执行数组中每个值 ...
 - JS判断PC操作系统版本
			
var version = navigator.userAgent; console.log(version); //"Mozilla/5.0 (Windows NT 10.0; WOW64 ...
 - 多测师讲解requests __介绍_高级讲师肖sir
			
我们今天讲解的内容 一.什么是Requests? Requests是用Python语言编写的简单易用的HTTP库,用来做接口测试的库. 二.安装requests库 1.按住Windows标志+r,在运 ...
 - IE下文件上传, SCRIPT5: 拒绝访问 问题
			
最近遇到一个比较奇葩的问题,某些ie浏览器在页面中上传文件时,无法上传.查看控制台报错: SCRIPT5: 拒绝访问. jquery-3.2.1.min.js, 行4 字符5725 .并且我的最新版I ...
 - go 不停模拟 写日志
			
package main import ( "os" "errors" "math/rand" "time" " ...
 - lumen laravel response对象返回数据
			
Route::get('home', function () { $content = "内容"; $status = 301; $value = 'text/html'; // ...