部分转自:什么是圣杯布局、双飞翼布局?
圣杯布局和双飞翼布局解决的问题是一样的,就是两边定宽,中间自适应的三栏布局,中间栏要放在文档流前面以优先渲染。
但是圣杯布局和双飞翼布局在实现方式上有一点差别。
圣杯布局的来历是2006年发在a list part上的这篇文章:
http://alistapart.com/article/holygrail
双飞翼布局介绍-始于淘宝UED:
http://www.imooc.com/wenda/detail/254035
圣杯布局
- 三者都设置向左浮动。
- 设置中间的宽度为100%。
- 设置负边距margin-left。左部分设置-100%,.右部分设置-width px。
- 设置容器的padding值给左右两部分留出空间。
- 设置左右部分为相对定位。左部分left的为-width,右部分right为-width。
HTML
<div id="container"> <!--先写中间部分--> <div id="main" class="col"></div> <div id="left" class="col"></div> <div id="right" class="col"></div> </div>
主体main放置在最前面可以优先加载。
CSS
body {min-width: 550px;}
.col {position: relative;float: left;} #container {padding: 0 190px 0 190px;} #main {width: 100%;height: 400px;background-color: #ccc;} #left {width: 190px;height: 400px;margin-left: -100%;left: -190px;background-color: #0000FF;} #right {width: 190px;height: 400px;margin-left: -190px;right: -190px;background-color: #FF0000;}
圣杯布局有个问题,当面板的中间部分比两边的子面板宽度小的时候,布局就会乱掉。
双飞翼布局
HTML
<div id="container"> <div id="main" class="col"> <div id="main-wrap"></div> </div> <div id="left" class="col"></div> <div id="right" class="col"></div> </div>
与圣杯布局相比,双飞翼HTML中为main添加了一个子元素main-wrap,这个小小的改动是为了之后处理main中内容被遮盖的问题,这也是两者实现方式最大的不同点。
CSS
body {min-width: 550px;} .col {float: left;} #main {width: 100%;height: 400px;background-color: #ccc;} #main-wrap {margin: 0 190px 0 190px;} #left {width: 190px;height: 400px;margin-left: -100%;background-color: #0000FF;} #right {width: 190px;height: 400px;margin-left: -190px;background-color: #FF0000;}
与圣杯布局一样,一开始三个col都设置float: left
,为了把left和right定位到左右部分,采用负边距,left部分margin-left: -100%
,right部分margin-right: -190px
。
之后就是处理main中内容的遮盖问题,只需设置main-wrap的左右外边距即可解决。
相比圣杯布局,双飞翼不必设置左右栏的position: relative
,也不必设置左右left、right值,只需#main多添加一个子元素包含,相应的padding换成margin。总的说来简单不少。
双飞翼布局的好处:
- 主要的内容先加载的优化;
- 兼容目前所有的主流浏览器,包括IE6在内;(就一个针对ie6的清除浮动hack:_zoom: 1;)
- 实现不同的布局方式,可以通过调整相关CSS属性即可实现。(可搭配实现一套栅格化布局系统)
什么是栅格化布局:
简单点说就是:像ps
中的参考线一样,用若干水平参考线和垂直参考线将画布(网页)分割成若干份以便于布局排版。当然这个水平参考线和垂直参考线并不是随便拉的而是有规律的。
标准的栅格化公式
W = c * n + g * (n - 1) + 2 * m
在实际操作过程中,我们会省略掉最左边和最右边的那两个外边距,也就是说w1
的宽度才是总宽度。
w1=(c + g) * n - g
写模板与是有讲究的,为了尽可能减少代码且发挥代码最大的公用性,我们可以使用父级控制子级。每次布局结构不同时,我们只修改父级样式名就可以实现布局变换。
如果我们要求布局如下:
回到前面的公式中,我们套用下公式可得出:190=(c+10)*n-10
,化简后:200=(c+10)*n
此时,c
和n
是未知的,所以可以有推算出几种组合(注意:n是正整数!)。
例:c=190,n=1
、c=90,n=2
、c=40,n=4
、c=30,n=5
、c=15,n=8
等。如果让c=30
,此时父级样式名为:grid-c2-m0s5
,如果让c=40
,此时父级样式名为:grid-c2-m0s4
。
这个要看个人喜好了,如果习惯c=30
。有了父级样式后,我们来改造下css
样式即可实现灵活布局了。
html:
<div class="col grid-c2-m0s1 clearfix"> <div class="col-main"> <div class="main-wrap">grid-c2-m0s1</div> </div> <div class="col-sub">sub=30</div> </div>
css:
双飞翼:
.col-main{float:left;width:100%;height:50px;} .main-wrap{background:#666;height:100%} .col-sub{float:left;height:50px;background:#ccc;}
栅格:
/*两列 左主右侧*/ .grid-c2-m0s1{} .grid-c2-m0s1 .main-wrap{margin-right:40px} .grid-c2-m0s1 .col-sub{width:30px;margin-left:-30px}
有了这些模板库后,当我们页面布局需要变动时直接修改父级class
即可实现对应布局