一、什么是流式布局
流式布局已经不是什么新概念了。为了文章的完整性,还是提一提吧。很久很久以前,当大部分人的屏幕分辨率还是1024*768的时候,网页设计师一般都按照960px或是980px的固定宽度进行设计。现在很多大型网站也依然使用这个宽度,为了不落下某些使用窄屏和IE6的用户(比如我们的父母)。然后页面中的其他布局元素也使用固定宽度。流式布局也正是相对这样的固定布局来说的。看下面两幅图就可以一目了然的区分固定布局和流式布局。
图1 固定布局
图2 流式布局
可以看到,流式布局使用百分比宽度来限定布局元素,这样可以根据客户端分辨率的大小来进行合理的显示。那么,是不是只要把布局元素换成百分比就算是流式布局了呢?当然不是啦,一个页面中还有各种字号、边框、间距、浮动层以及动态的元素,还必须让它们也在不同屏幕下能正确显示。我看过一些例子,发现没有哪个能站出来说,这就是标准的流式布局。而事实恰恰是整体的页面采用百分比布局,在细小的地方依然需要使用像素计算来达到效果。
我一直认为流式布局中不能使用position:absolute这样的写法,因为固定了位置,显然就不能“流动”了嘛。但有时候这样的属性是不得不用的,想新浪微博的消息提示,如图(图标右上角的小红点):
这样的定位显然是需要position:absolute这样的属性的。所以,以我粗浅的理解,流式布局的特征应该是这样的:
①凡是布局元素,即与其他版块相互分离的区块,宽度间距都要用百分比;
②区块内的细节定位,还是得需要像素来计算;
③float属性尽量不使用,这样会破坏“流动性”;
④布局元素通过彼此之间的间距来进行定位,不用left、top这样的属性把位置定死
而且还需要一个权衡,哪里使用百分比哪里使用像素,并没有标准的答案。
二、响应式设计与流式布局的和谐共处
按照上面提到的权衡之后,会引起一个大问题,就是不能像素级别的精确还原设计图,拖动浏览器窗口的大小会发现元素间的相对位置会有大大小小的偏差。每当这个时候,我就有种对不住设计师的赶脚~怎么办呢?亲,还记得媒体查询码?对了,解决办法便是让这两者协调工作,使用百分比创建流动的弹性界面,同时使用媒体查询来限制元素的变动范围,这样便可以更精确的还原设计图了。
三、开始流式布局吧
拿过设计师的界面原型图,不管他是按960px还是1000px宽度设计的,首要工作便是把这些像素转化为百分比。如何转化呢?看作者给出的公式:
目标元素宽度 / 上下文元素宽度 = 百分比宽度
好了,可以拿出你的计算器了。诶,等等,这个上下文元素宽度是什么啊?就是目标元素的父亲吗?万一它的父亲没有宽度怎么办?幸好前几天看了BFC的概念,我觉得这里的上下文元素就可以认为是目标元素所处的最靠近的具有BFC的元素,就是把它隔离开的可参照的父级元素,具体页面具体分析,相信你你能找到的。那如果上下文元素没有宽度呢?同样,相信你自己,它的宽度只是没有显式指定而已,你总是可以把它的宽度找出来的,是不是默认100%了?那就再看看它的父级元素的宽度(是不是废话了。。。)。如果实在找不出来呢,那就给它设置一个宽度得了,在能正确布局你的页面的前提下。
来举个例子,比如整个设计图的宽度是960px,按照1024px屏幕分辨率做参照的话,百分比应该是960/1024 = 93.75%。其他的宽度也可以按照960px为参照计算出来了。另外要提的一点是,如果除下来的结果是很长的小数,比如340/960 = 0.3541666666666667 ,要不要四舍五入呢?作者此处的建议是不要,这样可以保持最高的精确度,而且你写的再长,浏览器也能认识,所以这些小数还是尽可能完整保留。
下来再看看字体大小。同样我们要使用相对值。现代浏览器默认的字体大小是16px,即相当于你已经拿到了body的字号16px作为参考值。我们用em为单位来表示字体的相对大小。计算公司依然使用上面的 目标元素宽度 / 上下文元素宽度 = 百分比宽度。例如,你的某个div的字体大小为48px,转化后为48/16=3em。同样,如果你得到的是一个很长的小数,也尽管使用它,像2.235423em这样的写法也是没什么问题的。
提到字体大小就不能不提行高(line-height),行高的计算是以自身的字体大小为参照的,这一点不要忘记。所以,同样把line-height也转化为em单位。
下来该看看图片该怎么处理了。弹性图片这个名字是不是已经很熟悉了。其实也没有什么神秘的,就是让图片的宽度变为百分比的,让其能自适应罢了。那这和其他布局元素的百分比处理有什么区别呢?区别当然是有的啦,首先图片不是布局元素,它里面是不包含子元素的。其次,图片还有失真的问题,缩放不当都会造成失真。作者提到,只要给图片添加样式max-width:100%就可以实现弹性图片了,因为图片所处的容器是自动缩放的,只要让图片限制在父级的宽度之内,就可以随父级一块缩放了。嗯,是个不错的想法。但是此做法有个大大的问题呀,比如,父元素的样式为width:80%,在屏幕分辨率较大的情况下可能计算得出的实际像素为1000px,同时假如图片的实际宽度为500px,小于父亲宽度,这样父元素在500px~1000px之间缩放时,图片始终保持500px的实际大小没有变化,因为它始终没有超出父元素的宽度。
看来作者也有疏漏啊。所以弹性图片不光是用max-width就可以的。还得使用百分比宽度。就像计算布局元素的宽度一样来。(真没意思)不过不要忘了图片的失真问题。当用户使用的一个超宽屏幕时,图片被放大到原大小的两倍甚至更多,这图就没法看了。所以还需为图片设置阈值,也就是上限啦,看来这个max-width还是不可少的。所以一个弹性图片的比较理想的组合应该是像这样:width:30%; max-width:400px;不让它超过一个宽度。那这样是不是就没问题了呢?
还是一个使用超宽屏幕的用户,按照正常的页面设计比例,这张图片被放大到500px了,但是现在只能显示最大宽度400px,岂不是与设计稿不符了。看来还是个问题呀。此处作者又给出另一个组合,把max-width加到图片的父级元素上,从源头上就限制放大的最大值,这样图片与它的相邻兄弟的比例就不会失调了。可以看到也是个权衡的结果。不敢保证这样的方案就一定没有问题,因为页面结构千变万化,这里指提供一个思路,具体的解决办法,还是得具体分析页面。
哎哟,差点忘了,媒体查询呀!为了防止放大的过宽,你完全可以通过媒体查询来设置不同分辨率下的阈值。再加上这个神器,相信你会组合出完美的方案。响应式设计,说到底还是一个权衡的过程。
四、提供不同尺寸的图片
如果你不满足于经过种种权衡后的结果,还有一种方案可以保证你的图片可以高保真显示:在不同的设备上提供不同尺寸的图片。你可能会发愁准备图片的事情了,现在不必了,因为已经有工具可以替你做了。好,有请这位神器出场:adaptive-images。官网地址:http://adaptive-images.com/
其原理是,在页面加载图片的时候,先向服务端的一个php文件发送请求,该PHP文件会在服务端处理图片,生成对应大小尺寸的图片,例如你用手机访问这个页面,服务端将生成一个小尺寸的图片来供你显示,这样将节省很大的带宽。你也可以设置这个小图片的缓存时间,超时后它将会被删除,不会占用服务器空间。是不是很爽呢,快去试试吧,官网有使用方法,只需几步,很简单。
五、总结
关于如何编写流式布局页面的章节结束了,这一章确实学到了不少使用的技术。不过还是感觉博客的技术含量不高,我想一个原因是我的博客中没有写代码示例。光是一些描述性的文字。好,从下章开始,弥补一下这方面的不足。