本文主要对 CSS 布局中常见的经典问题进行简单说明 涉及到常见的两栏,三栏布局
二列布局的特征是侧栏固定宽度,主栏自适应宽度。三列布局的特征是两侧两列固定宽度,中间列自适应宽度。而二列布局可以看做去掉一个侧栏的三列布局,其布局的思想有异曲同工之妙。
两栏布局
-
float+margin
-
position+margin
两栏(左右)布局常见于博客、后台管理系统,左侧为导航,右侧做内容显示。
<div class="body">
<div class="left"></div>
<div class="right"></div>
</div>
float+margin
将左侧元素固定宽度并设置左浮动,右侧元素左外边距并预留出左侧元素的宽度。
.body{
width: 1000px;
height:100px;
margin: 0 auto;
}
.left{
width: 100px;
height:100px;
float: left;
background:red;
}
.right{
margin-left: 100px;
height:100px;
background:blue;
}
效果如下,不同宽度的自适应
position+margin
左侧元素用绝对定位固定在左边,右侧元素预留左外边距。注意,在父元素(此处为body)上需要设置相对定位(position:relative;),否则高度会不一致
.body{
max-width: 800px;
margin: 0 auto;
position:relative;
}
.left{
position: absolute;
top: 0;
left: 0;
width: 100px;
height:100px;
background:red;
}
.right{
margin-left: 100px;
height:100px;
background:blue;
}
下图是其父元素没有设置相对定位的效果
三栏布局
-
float+margin
-
定位+margin
-
flex布局
-
table布局
<body>
<div class="body">
<div class="left">左侧</div>
<div class="right">右侧</div>
<div class="center">中间</div>
</div>
</body>
1.float+margin
.body{
height:100px;
margin: 0 auto;
overflow:hidden;
}
.left{
width: 100px;
height:100px;
float: left;
background:red;
}
.center{
width: 100%;
height:100px;
margin-left:100px;
margin-right:100px;
background:blue;
}
.right{
float:right;
width:100px;
height:100px;
background:green;
}
缺点是:1. 当宽度小于左右两边宽度之和时,右侧栏会被挤下去;2. html的结构异常(右侧需写在前面)
2.position+margin
<div class="body">
<div class="left">左侧</div>
<div class="center">中间</div>
<div class="right">右侧</div>
</div>
.body{
position:relative;
}
.left{
background: red;
width: 100px;
height: 100px;
position: absolute;
top: 0;
left: 0;
}
.center{
height: 100px;
margin: 0 100px;
background: yellow;
}
.right{
height: 100px;
width: 100px;
position: absolute;
top: 0;
right: 0;
background: green;
}
有点:html结构正常。
缺点时:不够灵活,
4.flex布局
<div class="wrapper">
<div class="left">左侧</div>
<div class="center">中间</div>
<div class="right">右侧</div>
</div>
.wrapper{
display:flex;
}
.left{
background: red;
width: 20%;
height: 100px;
}
.center{
width:60%;
height: 100px;
background: yellow;
}
.right{
width: 20%;
height:100px;
background: green;
}
优点:传统的布局方法基于盒状模型,依赖display属性 +position属性 +float属性,逻辑相对复杂,对于实现一些特殊效果,例如垂直居中,尤其复杂繁琐。而flex布局中的flex容器可以根据实际可用空间动态调整子元素的宽高比和顺序,使元素能够尽可能地利用可用空间,同时也能通过缩小来避免超出。flex布局提供了一套简便、完整、响应式的布局方案
缺点:兼容性
5、table布局
说到表格布局,相信大家首先想到的是<table>
标签,其实,在CSS2中还提供了一种表格布局:display: table
,
<div class="wrapper">
<div class="left">左侧</div>
<div class="center">中间</div>
<div class="right">右侧</div>
</div>
.wrapper{
display:table;
}
.left{
display:table-cell;
background: red;
width: 100px;
height: 100px;
}
.center{
display:table-cell;
width: 200px;
height: 100px;
background: yellow;
}
.right{
display:table-cell;
width: 100px;
height:100px;
background: green;
}
圣杯布局
- 先写middle(中间),然后是left(左侧)和right(右侧),因为需要先渲染middle;
- 中间盒子的宽度设置为
width: 100%;
独占一行; - 使用负边距(均是
margin-left
)把左右两边的盒子都拉上去和中间盒子同一行;.left {margin-left:-100%;}
使它上移一行,同时right向左移占据left原先位置;.right {margin-left:-右边盒子宽度px;}
使它上移并靠右。
- 父盒子设置左右的 padding 来为左右盒子留位置;
- 对左右盒子使用相对布局来占据 padding 的空白,避免中间盒子的内容被左右盒子覆盖;
<div class="content">
<div class="middle"></div>
<div class="left"></div>
<div class="right"></div>
</div>
.content {
padding: 0 100px;
}
.middle {
position:relative;
width: 100%;
float: left;
height: 80px;
background: red;
}
.left {
position:relative;
width: 100px;
float: left;
left:-100px;
height: 80px;
margin-left: -100%;
background: blue;
}
.right {
position:relative;
width: 100px;
float: left;
right:-100px;
height: 80px;
margin-left: -100px;
background: yellow
}
双飞翼布局
- 中间盒子的宽度设置为
width: 100%;
独占一行; - 使用负边距(均是
margin-left
)把左右两边的盒子都拉上去和中间盒子同一行; - 在中间盒子里面再添加一个 div,然后对这个 div 设置
margin-left
和margin-right
来为左右盒子留位置
<div class="content">
<div class="middle">
<div class="inner-middle">中间内容</div>
</div>
<div class="left"></div>
<div class="right"></div>
</div>
.content {
overflow: hidden;
}
.middle {
width: 100%;
float: left;
}
.inner-middle{
width:100%;
height: 80px;
margin:0 100px;
background: red;
}
.left {
width: 100px;
float: left;
height: 80px;
margin-left: -100%;
background: blue;
}
.right {
width: 100px;
float: left;
height: 80px;
margin-left: -100px;
background: yellow;
}
圣杯和双飞翼异同
圣杯布局和双飞翼布局解决的问题是一样的,都是两边定宽,中间自适应,中间栏要优先渲染。
- 两种方法基本思路都相同:首先让中间盒子 100% 宽度占满同一高度的空间,在左右两个盒子被挤出中间盒子所在区域时,使用 margin-left 的负值将左右两个盒子拉回与中间盒子同一高度的空间。接下来进行一些调整避免中间盒子的内容被左右盒子遮挡。
- 主要区别在于 如何使中间盒子的内容不被左右盒子遮挡:
- 圣杯布局的方法:设置父盒子的 padding 值为左右盒子留出空位,再利用相对布局对左右盒子调整位置占据 padding 出来的空位;
- 双飞翼布局的方法:在中间盒子里再增加一个子盒子,直接设置这个子盒子的 margin 值来留空,而不需要调整左右盒子。
简单说起来就是双飞翼布局比圣杯布局多创建了一个 div,但不用相对布局了,少设置几个属性。
如有错误,欢迎指正!