栅格布局想必大家都很了解,我们做页面开发的时候,往往对页面板式的要求很高,如何对各个区域的内容排版,并使之对齐是我们的一大难题。而栅格系统就是我们排版的利器,他支持自动对齐、自动计算边距、流式布局等优点,简单好用的特性使得栅格布局成为所有主流框架的必备的功能。

我们简单分析一下栅格布局的原理:

容器/行/列/栅间距

一个栅格布局需要3部分组成——容器(container)行(row)列(column,也可称为栅)。容器是用于确定宽度的,行需要放到容器中;行是将列分组,并把一组列合并为一个行;列是正真的显示内容的元素,我们的内容就写在列里面。具体可参考下图

如果仅是行与列来布局,自适应布局也能满足需求,栅格布局的高明之处在于它还提供了列与列之间存的间距,我们称之为栅间距(gutter),栅间距仅存在列与列之间,列和容器之间是不应该存在栅间距的。栅间距的存在使得我们不用自己去计算padding,设置布局更加简单,对齐也更加容易。

列宽

完善的栅格布局框架,都会提供一个类似自适应布局一样的声明列宽的class类。首先系统把容器分为若干份,这个总份数一般都是3、4的倍数,这样利于排版。然后再提供若干代表份数的类,让列去继承,这样列就会占据容器总宽度的指定份数(span)了。如上面我们的例图,容器的总份数是9,各个列继承不同的份值,并保证了一行里面的所有列的份值相加也是9。

栅格嵌套

同时栅格系统是可以嵌套的,即列里面也可以作为容器,里面可以再声明一行,然后继续声明子列,这种行为我们称之为栅格嵌套,如下图:

列的换行行为

早期的栅格系统框架,列与列之间是不能换行的,即一行中的所有列都必须确保在同一行中。但是随着响应式布局的兴起,一行中的列也需要出现换行行为,而且换行后也没不能出现显示错误,这种行为我们称为列的换行行为,如下图。因为涉及栅间距的计算,所以不是每一个栅格系统都可以支持“列的换行行为”的。列的换行行为对于完成响应式布局非常重要的,最为明显的例子就是bootstrap3的响应式功能要远远比bootstrap2强大,原因就是因为bootstrap3的栅格支持“列的换行行为”。

列宽的计算

根据上面我们对原理的分析,可以看出,如何计算栅间距是栅格系统的核心。没有了栅间距,栅格布局也就成了普通的自适应布局,那么如何去计算栅间距、列宽、行宽的关系呢?从栅格系统的表现形式可以看出,一行中栅间距的个数等于总份数减一。如果容器的宽度是width,总份数是n,列间距的宽度是gutter,列的份数是span,列宽是colwidth。那么有:

colwidth = (width + gutter) / n * span - gutter

这个计算并不复杂,但是想要通过css2去自动计算几乎是不可能的。

同时栅格系统还有一个难点,就是如何控制哪个列有栅间距,哪个列没有。css中控制元素与元素之间的间隔用的是margin,而且栅格与容器之间是没有栅间距的,因此每个列的margin计算就是另一个难题。

这两个问题很难直接用css2解决,但是使用一些黑科技还是可以解决这两个问题。如果是面向的浏览器支持css3,利用css3的语法解决这两个计算问题也是可行的。根据市面上的几个流行框架,笔者大致总结出了确定列宽、栅间距的几种方法:

1.固定container宽度法

这个方法比较简单,首先框架要确定容器的宽度,这样因为容器的宽度是固定的,就可以计算出列宽了。

至于栅间距的确定也十分简单,就是让开发人员自己去设置。框架在每一列都设置一个向左或者向右的margin,然后再定义一个最后一列或者第一列的样式类(如“.first”或者“.last”),通过开发人员手动设置这个样式类,将最后一列(或者第一列)多出来的margin去除掉。

如果浏览器支持css3,可以用css3的伪类“:last”和“:first”代替人工设置法的“.last”和“.first”,这样更加自动化一些。

这种方法是不支持“列的换行行为”,因为一旦出现了一行被挤到了第二行,他的栅间距的计算就会出现问题。即便是用伪类去辅助计算行间距,仍然无法去除换行后元素的多出来的栅间距。

总结:这种方法好处是简单,兼容性好。缺点是仅支持固定的container,适用性很差,同时还不支持列的换行行为。

代表框架:蓝图(blueprint)

2.行单向偏移法

这个方法非常巧妙,使用很简单的方法将列宽度和栅间距的确定问题解决列,思路上是这样的,因为一行中栅间距的个数等于总份数减一,如果把让行宽等于容器的宽度加上一个栅间距,那么一行能容纳的行间距的个数刚好等于总份数,这样计算列宽也简单了。具体可参考下图

这个方法巧妙在通过扩充行的宽,并使-margin的方法使之再偏移之一个栅间距的距离,这样多出一个不影响列显示的栅间距,使整个栅格系统的计算变得非常简单。

使用这个方法的另一个好处就是,他支持“列的换行行为”。我们之前说过“列的换行行为”是完成栅格的响应式布局的重要特性,使用行偏移法,我们不需要去控制个别列的padding或者margin的行为,这样使得列在换行后仍能正常显示成为可能。

当然这种方法也存在缺点,就是如何确定扩偏移后的行的宽度。因为偏移后的行的宽度要正好等于栅间距加上容器宽度,如果不使用css3的calc是很难的,也只能在用在固定容器宽度的情况下才能算出。

另外一个问题就是列宽的计算要使用padding和box-sizing属性,这使得我们需要多声明一个元素用于布局,这样一个栅格布局中就会多声明两层元素去用于布局,文档的语义化会减弱,而且一旦栅格嵌套,就会产生更多的无用的dom。

代表类库:bootstrap2的栅格就是使用这个方式,因为bootstrap2的栅格系统容器是定宽的,所以列宽就可以通过less事先计算好,这样就可以省去列通过padding计算列宽的步骤,使得栅格系统更加简洁。

3.行双向偏移法

这个方法是目前最流行方法,相当于利用了一个黑科技来完成这个艰巨的任务。这个方法和上一个“行单向偏移法”非常相似,只是因为行单向偏移法存在难以计算实际行宽的问题,而双向偏移法就是为了解决这个问题而诞生的。

方法是向左右各偏移半个栅间距,利用偏移后的效果由浏览器自动去计算行实际的行宽,而不是指定行宽。我们知道块级元素的宽度表现特性为:块级元素的宽度默认会占满整个容器,如果元素定义了margin,那么宽度将是父容器宽度去除margin后的宽度。即使margin是负值,这个计算方法同样适用,这其实是个hack,但是这样就可以利用来解决行宽的计算问题。具体方法如下图:

目前很多流行框架都使用这个方法,不过这个方法笔者很不喜欢,因为这样列也成为了一个布局元素,想要完成一个布局,要多生成三层元素,感觉这样做很不值得。不妨我们看看bootstrap3中文官网的dom结构,看看他那复杂的令人发狂的dom树你就会对这个方法的感到失望。不过不管怎么说他都很棒的解决列栅格系统的两大难题

代表类库:妹子ui、bootstrap3、Foundation

4.使用calc计算法

calc属性是css3中最令人着迷的属性之一,以往ie浏览器也提供过类似calc这种可计算的属性的方法,但是因为效率低下并且是非标准语法,一直被大家拒之门外。而calc的到来,终于让css中运用数值运算来计算尺寸成为可能。

我们之前分析出的公式直接使用calc上运算就行,因为calc是支持百分比与有单位的数值进行运算的。

当然,这仅是解决列列宽的问题,例如如何实现“列的换行行为”的问题还是没有解决,因此这个方法可以和“行单向偏移法”一起使用。

当然calc方法的最大缺点就是兼容性问题,ie低版本和诸多移动端浏览器都不支持这个属性,因此目前还没见过哪个主流框架是使用calc来实现栅格系统的。不过未来在各大主流浏览器均支持calc后,使用calc开发栅格系统必将成为主流,因为这个方法比起上面的hack方法更加简单。

5.使用flex布局

一些移动框架开始使用flex来提供栅格布局,不过flex布局并没有和上述几种方法有什么不同,原理上也是上述的4种形式,仅是用flex代替列float而已。不过在垂直方向上,flex利用自身特性,提供了一套垂直对齐的模式,算是对栅格系统进一步的补充。

代表类库:ionic

总结

栅格布局的实现方法主要就是上述的几种,了解列这些方法,我们就可以自己开发属于简单的栅格系统,从而不再依赖那些又大又笨的样式框架,使我们的项目更加坚定干净。

浅谈css的栅格布局的更多相关文章

  1. 转:浅谈CSS在前端优化中一些值得注意的关键点

    前端优化工作中要考虑的元素多种多样,而合理地使用CSS脚本可以在很大程度上优化页面的加载性能,以下我们就来浅谈CSS在前端优化中一些值得注意的关键点: 当谈到Web的“高性能”时,很多人想到的是页面加 ...

  2. CSS实现栅格布局

    CSS实现栅格布局 设置容器container: .grid-container { width: 100%; max-width: 1200px; } 清除浮动: .row:before, .row ...

  3. 浅谈CSS模块化

    为什么要CSS模块化? 你是否为class命名而感到苦恼? 你是否有怕跟别人使用同样class名而感到担忧? 你是否因层级结构不清晰而感到烦躁? 你是否因代码难以复用而感到不爽? 你是否因为commo ...

  4. 浅谈css的伪元素::after和::before

    css中的::after和::before已经被大量地使用在我们日常开发中了,使用他们可以使我们的文档结构更加简洁.但是很多人对::after和::before仍不是特别了解,究竟他们是做什么的?如何 ...

  5. 浅谈CSS布局

    在No.4中谈及了下盒子模型,引出布局模型 1.布局模型有三类: 1)流动模型  flow(默认) 2)浮动模型  float 3)层模型  layer 2.文档流 :指的是文本沿着从左到右的方向展开 ...

  6. [浅谈CSS核心概念] CSS布局模型:float和position

    1.流动模型 HTML元素在默认情况下都是按照"流动模型"进行布局的,网上也有人称之为"普通流"."文档流"之类的.这种布局模式的特点在于: ...

  7. 浅谈css中的盒模型(框模型)

    css中的盒模型是css的基础,盒模型的理解可以帮助我们进行对样式进行修改.废话不多说,进入正题: 在w3c中,CSS 框模型 (Box Model) 规定了元素框处理元素内容.内边框.边框 和 外边 ...

  8. 浅谈CSS盒子模型

    [摘要]盒子模型是CSS中的一个重要概念,虽然CSS中没有盒子这个单独的属性对象,但它却是CSS中无处不在的一个重要组成部分.掌握盒子模型的原理和使用方法可以极大地丰富HTML元素的表现效果,同时对于 ...

  9. 浅谈CSS hack(浏览器兼容)

    今天简单写一点关于浏览器兼容的处理方法,虽然百度上已经有很多,但是我还是要写! 先看一个图 这个图描述了2016年1月至8月网民们所使用的浏览器市场份额(来源:http://tongji.baidu. ...

随机推荐

  1. Hello Web API系列教程——Web API与国际化

    软件国际化是在软件设计和文档开发过程中,使得功能和代码设计能处理多种语言和文化习俗,在创建不同语言版本时,不需要重新设计源程序代码的软件工程方法.这在很多成熟的软件开发平台中非常常见.对于.net开发 ...

  2. python之路 - 基础1

    1.安装windows安装双版本Python2,Python3 下载Python2和Python3https://www.python.org/downloads/ 分别安装两个版本 进入Python ...

  3. C#基础篇 - 正则表达式入门

    1.基本概念 正则表达式(Regular Expression)就是用事先定义好的一些特定字符(元字符)或普通字符.及这些字符的组合,组成一个“规则字符串”,这个“规则字符串”用来判断我们给定的字符串 ...

  4. UE4新手引导入门教程

    请大家去这个地址下载:file:///D:/UE4%20Doc/虚幻4新手引导入门教程.pdf

  5. 用游标实现查询当前服务器所有数据库所有表的SQL

    declare @name varchar(100) DECLARE My_Cursor CURSOR --定义游标 FOR (SELECT Name FROM Master..SysDatabase ...

  6. 彻底搞懂Javascript的“==”

    本文转载自:@manxisuo的<通过一张简单的图,让你彻底地.永久地搞懂JS的==运算>. 大家知道,==是JavaScript中比较复杂的一个运算符.它的运算规则奇怪,容让人犯错,从而 ...

  7. Oracle 分页

    --1:无ORDER BY排序的写法.(效率最高) --(经过测试,此方法成本最低,只嵌套一层,速度最快!即使查询的数据量再大,也几乎不受影响,速度依然!) SELECT * FROM (SELECT ...

  8. Linux学习日记-EF6的安装升级(三)

    在vs2013中使用EF是5的但是如果想使用 “来自数据库据的Code First” 这个生成模板就会发现 它会提示你EF的版本太低请升级 下面就是解决办法: 安装实体框架6 在工具菜单中,点击NuG ...

  9. “前.NET Core时代”如何实现跨平台代码重用 ——源文件重用

    微软在2002年推出了第一个版本的 .NET Framework,这是一个主要面向Windows 桌面(Windows Forms)和服务器(ASP.NET Web Forms)的基础框架.在此之后, ...

  10. PropertyGrid控件由浅入深(二):基础用法

    目录 PropertyGrid控件由浅入深(一):文章大纲 PropertyGrid控件由浅入深(二):基础用法 控件的外观构成 控件的外观构成如下图所示: PropertyGrid控件包含以下几个要 ...