浅谈css的栅格布局
栅格布局想必大家都很了解,我们做页面开发的时候,往往对页面板式的要求很高,如何对各个区域的内容排版,并使之对齐是我们的一大难题。而栅格系统就是我们排版的利器,他支持自动对齐、自动计算边距、流式布局等优点,简单好用的特性使得栅格布局成为所有主流框架的必备的功能。
我们简单分析一下栅格布局的原理:
容器/行/列/栅间距
一个栅格布局需要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的栅格布局的更多相关文章
- 转:浅谈CSS在前端优化中一些值得注意的关键点
前端优化工作中要考虑的元素多种多样,而合理地使用CSS脚本可以在很大程度上优化页面的加载性能,以下我们就来浅谈CSS在前端优化中一些值得注意的关键点: 当谈到Web的“高性能”时,很多人想到的是页面加 ...
- CSS实现栅格布局
CSS实现栅格布局 设置容器container: .grid-container { width: 100%; max-width: 1200px; } 清除浮动: .row:before, .row ...
- 浅谈CSS模块化
为什么要CSS模块化? 你是否为class命名而感到苦恼? 你是否有怕跟别人使用同样class名而感到担忧? 你是否因层级结构不清晰而感到烦躁? 你是否因代码难以复用而感到不爽? 你是否因为commo ...
- 浅谈css的伪元素::after和::before
css中的::after和::before已经被大量地使用在我们日常开发中了,使用他们可以使我们的文档结构更加简洁.但是很多人对::after和::before仍不是特别了解,究竟他们是做什么的?如何 ...
- 浅谈CSS布局
在No.4中谈及了下盒子模型,引出布局模型 1.布局模型有三类: 1)流动模型 flow(默认) 2)浮动模型 float 3)层模型 layer 2.文档流 :指的是文本沿着从左到右的方向展开 ...
- [浅谈CSS核心概念] CSS布局模型:float和position
1.流动模型 HTML元素在默认情况下都是按照"流动模型"进行布局的,网上也有人称之为"普通流"."文档流"之类的.这种布局模式的特点在于: ...
- 浅谈css中的盒模型(框模型)
css中的盒模型是css的基础,盒模型的理解可以帮助我们进行对样式进行修改.废话不多说,进入正题: 在w3c中,CSS 框模型 (Box Model) 规定了元素框处理元素内容.内边框.边框 和 外边 ...
- 浅谈CSS盒子模型
[摘要]盒子模型是CSS中的一个重要概念,虽然CSS中没有盒子这个单独的属性对象,但它却是CSS中无处不在的一个重要组成部分.掌握盒子模型的原理和使用方法可以极大地丰富HTML元素的表现效果,同时对于 ...
- 浅谈CSS hack(浏览器兼容)
今天简单写一点关于浏览器兼容的处理方法,虽然百度上已经有很多,但是我还是要写! 先看一个图 这个图描述了2016年1月至8月网民们所使用的浏览器市场份额(来源:http://tongji.baidu. ...
随机推荐
- 水印第三版 ~ 变态水印(这次用Magick.NET来实现,附需求分析和源码)
技能 汇总:http://www.cnblogs.com/dunitian/p/4822808.html#skill 以前的水印,只是简单走起,用的是原生态的方法.现在各种变态水印,于是就不再用原生态 ...
- 使用HttpClient的优解
新工作入职不满半周,目前仍然还在交接工作,适应环境当中,笔者不得不说看别人的源码实在是令人痛苦.所幸今天终于将大部分工作流畅地看了一遍,接下来就是熟悉框架技术的阶段了. 也正是在看源码的过程当中,有一 ...
- bzoj1079--记忆化搜索
题目大意:有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块.所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n.相邻两个木块涂相同色显得 ...
- Java获取本机的IP与MAC地址
有些机器有许多虚拟的网卡,获取IP地址时会出现一些意外,所以需要一些验证: // 获取mac地址 public static String getMacAddress() { try { Enumer ...
- “老坛泡新菜”:SOD MVVM框架,让WinForms焕发新春
火热的MVVM框架 最近几年最热门的技术之一就是前端技术了,各种前端框架,前端标准和前端设计风格层出不穷,而在众多前端框架中具有MVC,MVVM功能的框架成为耀眼新星,比如GitHub关注度很高的Vu ...
- AFNetworking图片上传
//上传图片 -(void)upLoadImage:(UIImage *)upImage { //创建管理 AFHTTPRequestOperationManager *manager = [AFHT ...
- [AlwaysOn Availability Groups] 健康模型 Part 2 ——扩展
健康模型扩展 第一部分已经介绍了AlwayOn健康模型的概述.现在是创建一个自己的PBM策略,然后设置为制定的归类.创建这些策略,创建之后修改一下配置,dashboard就会自动评估这些策略. 场景, ...
- CentOS:Yum源的配置
# cd /etc/yum.repos.d/ # mv CentOS-Base.repo CentOS-Base.repo.bak # wget http://mirrors.163.com/.hel ...
- Linux目录结构
- Xamarin. Android实现下拉刷新功能
PS:发现文章被其他网站或者博客抓取后发表为原创了,给图片加了个水印 下拉刷新功能在安卓和iOS中非常常见,一般实现这样的功能都是直接使用第三方的库,网上能找到很多这样的开源库.然而在Xamarin. ...