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

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

容器/行/列/栅间距

一个栅格布局需要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. 初步认识JUnit

    初步认识JUnit 目前大多数的基于Java的企业应用软件,肯定少不了单元测试,程序员通过编写单元测试来验证自己程序的有效性:管理者通过持续自动的执行单元测试和分析单元测试覆盖率来确保软件本身的质量. ...

  2. android: SQLite更新数据

    学习完了如何向表中添加数据,接下来我们看看怎样才能修改表中已有的数据. SQLiteDatabase 中也是提供了一个非常好用的 update()方法用于对数据进行更新,这个方法 接收四个参数,第一个 ...

  3. win10 uwp 模拟网页输入

    有时候需要获得网页的 js 执行后的源代码,或者模拟网页输入,如点按钮输入文字. 如果需要实现,那么就需要用 WebView ,使用方法很简单. 首先创建一个 WebView ,接下来的所有输入都需要 ...

  4. TensorFlow激活函数+归一化-函数

    激活函数的作用如下-引用<TensorFlow实践>: 这些函数与其他层的输出联合使用可以生成特征图.他们用于对某些运算的结果进行平滑或者微分.其目标是为神经网络引入非线性.曲线能够刻画出 ...

  5. ant design + react,自动获取上传音频的时长(react-audio-player)

    在后台管理项目中,用户要求上传音频,并且自动获取音频时长. 第一步, import { Upload, Button, Icon } from 'antd'; 第二步,在表单中使用 Upload 组件 ...

  6. 计算机网络原理和OSI模型与TCP模型

    计算机网络原理和OSI模型与TCP模型 一.计算机网络的概述 1.计算机网络的定义 计算机网络是一组自治计算机的互连的集合 2.计算机网络的基本功能 a.资源共享 b.分布式处理与负载均衡 c.综合信 ...

  7. 《linux内核设计与实现》第一章

    第一章Linux内核简介 一.unix 1.Unix的历史 Unix是现存操作系统中最强大和最优秀的系统. ——1969年由Ken Thompson和Dernis Ritchie的灵感点亮的产物. — ...

  8. C/C++语言中闭包的探究及比较

    这里主要讨论的是C语言的扩展特性block.该特性是Apple为C.C++.Objective-C增加的扩展,让这些语言可以用类Lambda表达式的语法来创建闭包.前段时间,在对CoreData存取进 ...

  9. CSS3选择器之学习笔记

    首先说first-child与last-child,这两个选择器很容易明白,就是父元素下的第一个子元素和最后一个子元素.而nth-child和nth-last-child则是父元素下指定序号的子元素, ...

  10. sc58x config

    addip=set bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0:off ...