三栏布局常见方案
三栏布局(两边固定,中间自适应) 常用方案及演变过程
1. 浮动方式:
实现关键点: 要把中间放在左右块的后面,然后左右设置左右浮动即可。
优点: 简单
缺点: 中间 main 不能清除浮动,宽度较小布局混乱
代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>浮动实现三栏布局</title>
<style>
.header {
width: 100%;
height: 200px;
background-color: black;
}
.footer {
width: 100%;
height: 200px;
background-color: black;
}
.left {
float: left;
width: 300px;
height: 300px;
background-color: aqua;
}
.right {
float: right;
width: 300px;
height: 300px;
background-color: blue;
}
.center {
background-color: blueviolet;
margin: 0 310px;
height: 300px;
}
</style>
</head>
<body>
<div class="header"></div>
<div class="wrapper">
<div class="left"></div>
<div class="right"></div>
<div class="center"></div>
</div>
<div class="footer"></div>
</body>
</html>
2. 绝对定位方式:
实现关键点: 左右绝对定位 中间用 margin 撑开
优点:容易理解和上手
缺点:浏览器宽度较小会出现重叠
代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>绝对定位实现三栏布局</title>
<style>
.header {
width: 100%;
height: 200px;
background-color: black;
}
.footer {
width: 100%;
height: 200px;
background-color: black;
}
/* 变化部分 */
.left {
position: absolute;
left: 0;
top: 0;
width: 300px;
height: 300px;
background-color: aqua;
}
.right {
position: absolute;
right: 0;
top: 0;
width: 300px;
height: 300px;
background-color: blue;
}
.center {
background-color: blueviolet;
margin: 0 310px;
height: 300px;
}
.wrapper {
position: relative;
}
</style>
</head>
<body>
<div class="header"></div>
<div class="wrapper">
<div class="left"></div>
<div class="right"></div>
<div class="center"></div>
</div>
<div class="footer"></div>
</body>
</html>
停,要开始讲道理了
生产改进要求
中间栏优先渲染、运行任意列高度最高
陷入沉思
中间栏优先,浮动是挂了,绝对定位还能抢救下,先看看国外提出的圣杯布局和淘宝玉伯的双飞翼布局
圣杯布局
初版
实现要点:
1.子元素都左浮动,
2.设置主体部分宽度为 100%
3.设置左边 margin-left 为-100%让其换到上一行,右边 margin-left 为负本身宽度
4.主容器设置左右 padding
5.设置三部分都为相对定位,将两部分移动到两侧留白,left 和 right 设置为-宽度
缺点:圣杯破碎 当中间块宽度小于左边块时,布局错乱
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>圣杯布局</title>
<style>
.header {
width: 100%;
height: 200px;
background-color: black;
}
.footer {
width: 100%;
height: 200px;
background-color: black;
}
/* 变化部分 */
.left {
position: relative;
left: -310px;
float: left;
margin-left: -100%;
width: 300px;
height: 300px;
background-color: aqua;
}
.right {
position: relative;
right: -310px;
float: left;
margin-left: -300px;
width: 300px;
height: 300px;
background-color: blue;
}
.center {
float: left;
background-color: blueviolet;
height: 300px;
width: 100%;
}
.wrapper {
padding: 0 320px;
}
.clearfix::after {
display: block;
content: ' ';
height: 0;
visibility: hidden;
clear: both;
}
</style>
</head>
<body>
<div class="header"></div>
<div class="wrapper clearfix">
<div class="center"></div>
<div class="left"></div>
<div class="right"></div>
</div>
<div class="footer"></div>
</body>
</html>
绝对定位版
实现要点: 把前面普通版的 main 移到主容器最前即可
缺点:高度不可控,会无法支撑起 wrapper, 宽度较小出现覆盖
双飞翼布局
实现要点:
与圣杯处理不同之处在于中间被遮挡内容的处理,在 main 中包裹一个 div 设置左右 margin 来处理
优点: 比原始圣杯布局写法要简单,解决了圣杯破碎和绝对定位高度支撑问题
缺点: 增加了一个 div,增加了渲染成本
允许任意列最高
代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>双飞翼布局</title>
<style>
.header {
width: 100%;
height: 200px;
background-color: black;
}
.footer {
width: 100%;
height: 200px;
background-color: black;
}
/* 变化部分 */
.left {
float: left;
margin-left: -100%;
width: 300px;
height: 300px;
background-color: aqua;
}
.right {
float: left;
margin-left: -300px;
width: 300px;
height: 300px;
background-color: blue;
}
.center {
float: left;
background-color: blueviolet;
height: 300px;
width: 100%;
}
.content {
margin: 0 310px;
height: 300px;
background-color: brown;
}
.wrapper {
}
.clearfix::after {
display: block;
content: ' ';
height: 0;
visibility: hidden;
clear: both;
}
</style>
</head>
<body>
<div class="header"></div>
<div class="wrapper clearfix">
<div class="center">
<div class="content">
</div>
</div>
<div class="left"></div>
<div class="right"></div>
</div>
<div class="footer"></div>
</body>
</html>
flex 版
实现要点:利用 flex 的 order 属性移动
优点: 集双飞翼的优点一身,还要简单的多
缺点:兼容性! 兼容性! 兼容性!
代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>flex终极版</title>
<style>
.header {
width: 100%;
height: 200px;
background-color: black;
}
.footer {
width: 100%;
height: 200px;
background-color: black;
}
/* 变化部分 */
.left {
order: -1;
width: 300px;
height: 300px;
background-color: aqua;
}
.right {
width: 300px;
height: 300px;
background-color: blue;
}
.center {
background-color: blueviolet;
height: 300px;
flex: 1;
}
.wrapper {
display: flex;
}
</style>
</head>
<body>
<div class="header"></div>
<div class="wrapper">
<div class="center">
</div>
<div class="left"></div>
<div class="right"></div>
</div>
<div class="footer"></div>
</body>
</html>
总结
我习惯了对一个问题的发展过程进行了解,发掘每部分解决方案的优点和缺点,当然,文章是有意编排了顺序,是想大家有了一个从不完善的版本到完善版本过渡,也不能说拿到最大的锤子,就是干,程序员要做的就是在当前状况选择一个合适的方案。
想要点小星星
学习前端已经半年有余了,css方面能够认识到张鑫旭大佬,js方面有<<你不知道的JavaScript>>这位良师,还有阮一峰大佬的ES6,让我了解到前端的宿命就是精通html、css、js三门语言,任重而道远,在读了张大大的文章后有感,平时遇到问题,自己去尝试,主动犯错,了解不一样的深度,然后把知识点通过自己的脑子转换一下,重组为自己的东西,更重要的是,我不是一个无私的利他主义者,我还是需要一些鼓励,更有动力输出文章,希望能有一颗小星星呀。
参考文章
从前端到后端,到网络原理,再到计算机组成,最后回归到汇编,小小程序员的成长之路