面试官问:你有多少种方式实现三栏布局?
一、什么是三栏布局
三栏布局即左右元素固定宽度,中间元素自适应。代表布局有圣杯布局和双飞翼布局,当然还有其他方式可以实现,下面是详细介绍。
二、实现方式
1.自身浮动
元素顺序:中间盒子必须放在最后,左右元素任意排列
原理:左边元素左浮动 右边元素右浮动
缺点:当浏览器宽度不足以容纳三个元素时,中间元素不消失,最右侧的元素会被挤到第二排。浮动对后续元素影响较大(使用时一定要清除浮动)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
*{
margin: 0;
padding: 0;
}
.main{
height: 600px;
width: 100%;
}
.left{
width: 160px;
height: 100px;
background-color: #000;
float: left;
}
.right{
width: 480px;
height: 100px;
background-color: red;
float: right;
}
.middle{
width: 100%;
height: 100px;
background-color: blue;
}
</style>
</head>
<body>
<div class="main">
<div class="left"></div>
<div class="right"></div>
<div class="middle"></div>
</div>
</body>
</html>
2.绝对定位
元素顺序:任意摆放即可
原理:将左右两边使用absolute定位,中间元素使用margin预留左右元素的宽度
缺点:当浏览器页面不足以容纳三个元素时,中间元素会宽度减小(最小到0),右侧元素会覆盖到左侧元素上。两侧高度无法支撑总高度
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
*{
margin: 0;
padding: 0;
}
.main{
height: 600px;
width: 100%;
position: relative;
margin: 0;
}
.left{
width: 260px;
height: 100px;
background-color: #000;
position: absolute;
top: 0;
left: 0;
}
.right{
width: 280px;
height: 100px;
background-color: red;
position: absolute;
top: 0;
right: 0;
}
.middle{
height: 100px;
background-color: blue;
margin: 0 280px 0 260px;
}
</style>
</head>
<body>
<div class="main">
<div class="left"></div>
<div class="right"></div>
<div class="middle"></div>
</div>
</body>
</html>
3.函数计算
元素顺序:无要求
原理:使用calc函数,计算父元素的宽度减去左右元素的宽度
缺点:存在兼容性问题,需要IE9+才可以正常使用。元素采用了浮动,对后续元素有影响
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.container{
overflow: hidden;
}
.left,.right{
float: left;
height: 100px;
width: 100px;
background:red;
}
.center{
float: left;
height: 100px;
width:calc(100% - 200px);
background:yellow;
}
</style>
</head>
<body>
<div class="container">
<div class="left">left</div>
<div class="center">center</div>
<div class="right">right</div>
</div>
</body>
</html>
4.表格布局
元素顺序:中间元素必须在两个div之间
原理:父元素设置display:table,子元素设置display:table-cell
缺点:兼容性IE8+,不利于SEO
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>表格布局</title>
<style>
*{
margin:0;
padding:0;
}
.main{
width:100%;
display:table;
}
.main> div{
height:200px;
display:table-cell;
}
.left{
width:100px;
background-color: black;
}
.middle{
background-color:red;
}
.right{
width: 200px;
background-color: blue;
}
</style>
</head>
<body>
<div class="main">
<div class="left"></div>
<div class="middle"></div>
<div class="right"></div>
</div>
</body>
</html>
5.圣杯布局(重点,面试常问)
元素顺序:中间元素位于开头,左右元素无要求
原理:父元素使用padding预留左右元素的位置,三个元素浮动,左元素使用margin负值和相对定位调整位置,右元素用margin负值调整位置
缺点:中间部分宽度小于左侧时,布局混乱
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.main {
height: 600px;
padding: 0 100px;/* 左右元素的宽度决定 */
}
.middle {
width: 100%;
height: 100px;
background-color: blue;
float: left;
}
.left{
width: 100px;
height: 100px;
background-color: #000;
margin-left: -100%;
position: relative;
float: left;
right: 100px;/* 自身宽度 */
}
.right {
width: 100px;
height: 100px;
background-color: red;
margin-right: -100px;/* 自身宽度 */
float: left;
}
</style>
</head>
<body>
<div class="main">
<div class="middle">main</div>
<div class="left">left</div>
<dvi class="right">right</div>
</div>
</body>
</html>
6.双飞翼布局(重点,面试常问)
元素顺序:中间元素位于开头,左右元素无要求
原理:在中间元素内部创建子元素,子元素设置margin(值是左右元素的宽),用来预留左右元素的位置。左中右元素都设置浮动,左右元素设置margin负值
缺点:增加了DOM节点,加大了渲染树生成的计算量
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>双飞翼布局</title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.col{
float: left;
}
#main {
width: 100%;
height: 200px;
background-color: #ccc;
}
#main-wrap {
margin: 0 190px;/*这是圣杯和双飞翼最明显的区别,在main内部使用的是margin,而圣杯是直接在container部分使用padding*/
}
#left{
width: 190px;
height: 200px;
margin-left: -100%;
background-color: #0000FF;
}
#right {
width: 190px;
height: 200px;
margin-left: -190px;
background-color: #0000FF;
}
</style>
</head>
<body>
<div id="container">
<div id="main" class="col">
<div id="main-wrap"> #main </div>
</div>
<div id="left" class="col">#left</div>
<div id="right" class="col">#right</div>
</div>
</body>
</html>
7.flex布局(重点,面试常问)
元素顺序:无要求
原理:父元素设置flex,中心元素设置flex:1
缺点:flex有兼容性问题,IE11+支持较好
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
#box{
width:100%;
height:100px;
display:flex;
}
#left,#right{
width:200px;
height:100px;
background-color:blue;
}
#center{
flex:1;
height:100px;
background-color:#f00;
}
</style>
</head>
<body>
<div id="box">
<div id="left">left</div>
<div id="center">center</div>
<div id="right">right</div>
</div>
</body>
</html>
8.网格布局
元素顺序:中间元素必须在两个div之间
原理:父元素设置display:grid,使用grid-template-rows定义行高,使用grid-template-columns定义列宽即可
缺点:兼容性IE10+
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>表格布局</title>
<style>
*{
margin:0;
padding:0;
}
.main{
width:100%;
display:grid;
grid-template-rows: 100px;
grid-template-columns: 300px auto 300px;
}
.left{
background-color: black;
}
.middle{
background-color:red;
}
.right{
background-color: blue;
}
</style>
</head>
<body>
<div class="main">
<div class="left"></div>
<div class="middle"></div>
<div class="right"></div>
</div>
</body>
</html>
三、总结
上面一共列举了8中方式去实现三栏布局,也列出了他们各自的缺点,效果图我就不放了,cv代码自己运行一下就可以了。博主个人觉得,如果在不考虑兼容性的情况下,肯定选择后四种是比较好的,当然还可能有其他实现方法,欢迎大家评论、留言
ps:面试可能会问你如果中间元素需要优先加载,最好是选择方式5、6、7。因为他们的中间元素都是在左右元素的前面的