1. 圣杯布局的传统实现方法
利用圣杯布局的方法,可以轻松实现下面的布局效果:
下面来一一说明上图中五种布局效果的实现方法。
1)布局一:2栏布局,侧边栏固定在左边,右侧是主体内容栏:
<div class="layout"> <aside class="layout_aside">侧边栏宽度固定</aside> <div class="layout_main">主内容栏宽度自适应</div> </div>
.layout:after{ clear: both; content: " "; display: table; } .layout_aside, .layout_main { float: left; } .layout { padding-left: 210px; } .layout_main { width: 100%; } .layout_aside { width: 200px; margin-left: -210px; }
效果是:
2)布局二:2栏布局,侧边栏固定在右边,左侧是主体内容栏:
<div class="layout"> <div class="layout_main">主内容栏宽度自适应</div> <aside class="layout_aside">侧边栏宽度固定</aside> </div>
.layout:after { clear: both; content: " "; display: table; } .layout { padding-right: 210px; } .layout_main { width: 100%; float: left; } .layout_aside { float: right; width: 200px; margin-right: -210px; }
效果是:
3)布局三:3栏布局,2个侧边栏分别固定在左边和右边,中间是主体内容栏:
<div class="layout"> <aside class="layout_aside layout_aside-left">左侧边栏宽度固定</aside> <div class="layout_main">主内容栏宽度自适应</div> <aside class="layout_aside layout_aside-right">右侧边栏宽度固定</aside> </div>
.layout:after { clear: both; content: " "; display: table; } .layout_aside, .layout_main { float: left; } .layout { padding:0 210px; } .layout_main { width: 100%; } .layout_aside { width: 200px; } .layout_aside-left { margin-left: -210px; } .layout_aside-right { margin-right: -210px; float: right; }
效果是:
4)布局四:3栏布局,2个侧边栏同时固定在左边,右边是主体内容栏:
<div class="layout"> <aside class="layout_aside layout_aside-first">第1个侧边栏宽度固定</aside> <aside class="layout_aside layout_aside-second">第2个侧边栏宽度固定</aside> <div class="layout_main">主内容栏宽度自适应</div> </div>
.layout:after { clear: both; content: " "; display: table; } .layout_aside, .layout_main { float: left; } .layout { padding-left: 420px; } .layout_main { width: 100%; } .layout_aside { width: 200px; } .layout_aside-first { margin-left: -420px; } .layout_aside-second { margin-left: -210px; }
效果是:
5)布局五:3栏布局,2个侧边栏同时固定在右边,左边是主体内容栏:
<div class="layout"> <div class="layout_main">主内容栏宽度自适应</div> <aside class="layout_aside layout_aside-first">第1个侧边栏宽度固定</aside> <aside class="layout_aside layout_aside-second">第2个侧边栏宽度固定</aside> </div>
.layout:after { clear: both; content: " "; display: table; } .layout { padding-right: 420px; } .layout_main { width: 100%; float: left; } .layout_aside { width: 200px; float: right; } .layout_aside-first { margin-right: -210px; } .layout_aside-second { margin-right: -420px; }
效果是:
PS:
1)本文提供的这个布局方法,比网上看到的更加简洁一些,主要是因为不考虑兼容IE8及以下,不考虑把layout_main这个元素放在最前面,虽然经典的做法都要求把layout_main做法放在前面,这样可以让网页主体内容优先渲染
2)css布局类的命名采用了BEM的命名规则,这个可以帮助你写出结构化,规范化的css,有兴趣的可以去了解:
http://www.zhihu.com/question/21935157
3)在使用以上方法时,需注意html结构中layout_main与layout_aside的顺序;
3. 圣杯布局传统实现方法的一种变体
第2部分介绍的方法,使用诀窍是:
1)layout元素根据分栏布局的要求设置合适的padding,比如布局一,需配置padding-left;
2)layout_main和layout_aside元素都需要浮动,layout_main需配置float: left;layout_aside需根据分栏布局要求配置合适的float值,比如布局一,需配置为float: left;而布局二需配置float: right;
3)layout_main和layout_aside的顺序也很关键,具体内容可对比前面五种布局的html;
4)layout_aside需根据分栏布局要求,配置合适的margin-left或margin-right,比如布局一,需配置margin-left;布局二需配置margin-right。
虽然我不喜欢一定要坚持把layout_main放在前面,但是从第2部分这种方法的思路,衍生出的另外一种方法,却不得不要求始终把layout_main放在最前面,这种变体做法,也被称之为双飞翼布局。下面来看看双飞翼布局的实现方法
1)布局三:3栏布局,2个侧边栏分别固定在左边和右边,中间是主体内容栏:
<div class="layout_main-wrapper"> <div class="layout_main">主内容栏宽度自适应</div> </div> <aside class="layout_aside layout_aside-left">左侧边栏宽度固定</aside> <aside class="layout_aside layout_aside-right">右侧边栏宽度固定</aside> <footer class="clear">底部</footer>
.clear { clear: both; } .layout_main-wrapper,.layout_aside { float: left; } .layout_main-wrapper { width: 100%; } .layout_main { margin: 0 210px; } .layout_aside { width: 200px; } .layout_aside-left { margin-left: -100%; } .layout_aside-right { margin-left: -200px; }
这段代码的效果与第2部分布局三的效果一样,这种布局的诀窍是:
1)可以没有layout这一层包裹元素;
2)浮动清除需在外部元素上处理;
3)float和margin属性的设置方向相对统一,基本都是一个方向即可;
4)布局四和布局五实现起来,双飞翼布局还需要借助position:relative才行,相对要复杂一点。
4. 圣杯布局的纯浮动实现
前面两种方法都有2个共同点:
1)layout_main或layout_main-wrapper和layout_aside都会同时浮动;
2)都得借助负值属性实现。
其实还存在一种更加简洁的做法,不需要浮动layout_main或layout_main-wrapper,也不需要借助负值属性,只要浮动layout_aside,给layout_main加上合适的margin值,就可以利用浮动元素的特性,完成想要的分栏布局效果。还是以布局三为例:
<aside class="layout__aside layout__aside--left">左侧边栏宽度固定</aside> <aside class="layout__aside layout__aside--right">右侧边栏宽度固定</aside> <div class="layout__main">主内容栏宽度自适应</div> <footer class="clear">底部</footer>
.clear { clear: both; } .layout__main { margin: 0 210px; } .layout__aside--left { width: 200px; float: left; } .layout__aside--right { width: 200px; float: right; }
这段代码的效果与第2部分布局三的效果一样,这种方法的特点是:
1)清除浮动需借助外部元素;
2)layout_main上面不能使用clear属性。
5. 圣杯布局的flex实现
如果你还没有了解过flex布局,建议你赶紧去学习,虽然它在pc上兼容性还有点问题,但是在移动端已经完全没有问题了,微信官方推出的weui这个框架就大量地使用了这种布局,以下是2个学习这种布局方式的非常好的资源:
http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
http://www.ruanyifeng.com/blog/2015/07/flex-examples.html
flex布局即将成为网页布局的首选方案,当你看到用flex来实现圣杯布局的代码有多简单的时候,你就会觉得前面那句话一点都没错。使用flex,可以只用同一段css实现第2部分提到的五种布局:
<div class="layout"> <aside class="layout__aside">侧边栏宽度固定</aside> <div class="layout__main">主内容栏宽度自适应</div> </div> <div class="layout"> <div class="layout__main">主内容栏宽度自适应</div> <aside class="layout__aside">侧边栏宽度固定</aside> </div> <div class="layout"> <aside class="layout__aside">左侧边栏宽度固定</aside> <div class="layout__main">主内容栏宽度自适应</div> <aside class="layout__aside">右侧边栏宽度固定</aside> </div> <div class="layout"> <aside class="layout__aside">第1个侧边栏宽度固定</aside> <aside class="layout__aside">第2个侧边栏宽度固定</aside> <div class="layout__main">主内容栏宽度自适应</div> </div> <div class="layout"> <div class="layout__main">主内容栏宽度自适应</div> <aside class="layout__aside">第1个侧边栏宽度固定</aside> <aside class="layout__aside">第2个侧边栏宽度固定</aside> </div>
.layout { display: flex; } .layout__main { flex: 1; } .layout__aside { width: 200px; } .layout > .layout__aside:not(:first-child), .layout > .layout__main:not(:first-child){ margin-left: 10px; }
效果与第2部分每种布局做法的结果一模一样,但是代码减少了很多,而且适用的场景更多,比如4栏布局,5栏布局。