css两边固定中间自适应布局

三栏布局是一种常见的网页布局方案,最常见的需求就是两边固定,中间自适应效果,而这种布局有很多种不同的实现方案,在不同的需求和兼容性要求下适用性各不相同,下面来看一下常见的几种实现方式和它们的特点。

普通浮动布局

流体布局非常简单,就是利用元素浮动的特性来实现布局,实现起来其实并不难

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<style>
.container>div{
height: 200px;
}
.left {
float: left;
width: 300px;
background: red;
}

.right {
float: right;
width: 300px;
background: blue;
}

.center {
overflow: hidden;
background: yellow;
}
</style>
<div class="container">
<div class="left"></div>
<div class="right"></div>
<div class="center">
<h1>浮动布局</h1>
</div>
</div>


这种布局主要是控制元素浮动来实现的,要注意的一点就是中间元素要创建BFC(关于BFC的相关内容后面文章会分析),否则一旦高度变化就会无法正常工作。这种布局的特点就是浮动对旧浏览器兼容性好,缺点就是主体内容需要放到最后加载,当页面元素较多时候可能会影响体验,于是有了下面两种非常经典的改进方案。

圣杯布局

圣杯布局并不是因为长得像杯子,在西方,圣杯是表达“渴求之物”的意思,题外话,下面回来看它的实现。首先我们的目的是要实现中间部分先加载,所以html结构大体上是确定的,接下来一步一步来看圣杯布局的形成。

1
2
3
4
5
6
7
<div class="container">
<div class="center">
<h1>圣杯布局</h1>
</div>
<div class="left"></div>
<div class="right"></div>
</div>

1.给元素添加左浮动效果,代码和效果如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.container>div {
height: 200px;
}

.center {
float: left;
width: 100%;
background: yellow;
}

.left {
float: left;
width: 300px;
background: red;
}

.right {
float: left;
width: 300px;
background: blue;
}


此时肯定是不符合预期的,所以要进行下一步调整。

2.这一步是重点,为左右元素设置-margin值,其中需要设置左边元素左边距为负的中间盒子的宽度,也就是.left {margin-left:-100%;},需要设置右边元素左边距为负的自己的宽度,也就是.right {margin-left:-300px;},此时效果如图

看上去似乎实现了,不过中间元素此时是被压在下面的,所以还需要进一步处理。

3.要想把左右元素放在中间元素两边,就需要让两边有边距,所以首先要给父元素加一个内边距,即添加.container {padding: 0 300px;}显示效果如下。此时两边已经产生边距,不过两边元素还是在上中间元素面显示。

4.最后一步,给两边的元素加相对定位,然后把它们定位到两边空位处,即可实现最终效果,最终全部代码和显示效果如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<style>
.container {
padding: 0 300px;
}

.container>div {
height: 200px;
}

.center {
float: left;
width: 100%;
background: yellow;
}

.left {
float: left;
width: 300px;
background: red;
margin-left: -100%;
position: relative;
left: -300px;
}

.right {
float: left;
width: 300px;
background: blue;
margin-left: -300px;
position: relative;
right: -300px;
}
</style>

<div class="container">
<div class="center">
<h1>圣杯布局</h1>
</div>
<div class="left"></div>
<div class="right"></div>
</div>


这样就实现了圣杯布局,圣杯布局保持了与普通浮动布局同样的兼容性,最大的优点是可以实现中间部分优先加载,缺点就是处理复杂,而且当中间元素小于两侧元素时候会出现变形,响应效果相对差一点。

双飞翼布局

除了圣杯布局,还有另一种和它原理类似的解决方案,同样可以处理浮动布局的加载问题,这种实现方案来自淘宝的UED,叫做双飞翼布局。

双飞翼布局的html结构和圣杯布局有一点小差别,就是中间元素外面多了一层容器,代码如下

1
2
3
4
5
6
7
8
9
<div class="container">
<div class="center-container">
<div class="center">
<h1>双飞翼布局</h1>
</div>
</div>
<div class="left"></div>
<div class="right"></div>
</div>

前两步的样式设置和和圣杯布局是相同的,元素左浮动,两侧-margin,最终产生了和上面相同的元素被遮盖的情况。

接下来,也是双飞翼布局的特点所在,由于实际中间元素是放在一个容器里面的,我们可以给内部元素设置外边距,这样就可以让出两边的位置,两边元素也无需重定位即可完成布局,完整代码和显示效果如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<style>
.container div {
height: 200px;
}

.center-container {
float: left;
width: 100%;
height: 100px;
background: yellow;
}

.center {
margin: 0 300px;
}

.left {
background: red;
float: left;
width: 300px;
margin-left: -100%;
}

.right {
background: blue;
float: left;
width: 300px;
margin-left: -300px;
}
</style>

<div class="container">
<div class="center-container">
<div class="center">
<h1>双飞翼布局</h1>
</div>
</div>
<div class="left"></div>
<div class="right"></div>
</div>

双飞翼布局相比圣杯布局更简洁,多使用了一个div,不过简洁性和响应能力上要比圣杯布局好。

圣杯布局和双飞翼布局都是在浮动布局时代的比较经典的布局方式,对旧的浏览器有很好的兼容性。不过事实上,现代浏览器已经大量普及,需要适配旧浏览器的场景已经开始变少,加上移动端开发越来越盛行,于是有了比较新的布局方式。

flex布局

flex是css3提供的一种新的布局方式,这种布局的产生就是为了实现自适应布局,它是随着移动互联网时代产生而引进的,我们来看一下使用flex来实现三栏布局的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<style>
.container {
display: flex;
}

.container>div {
height: 200px;
}

.left {
width: 300px;
background: red;
}

.center {
flex: 1;
background: yellow;
}

.right {
width: 300px;
background: blue;
}
</style>
<div class="container">
<div class="left"></div>
<div class="center">
<h1>flexbox</h1>
</div>
<div class="right"></div>
</div>


就是这样简单,把外层容器显示属性设置成flex,里面只要自适应部分flex设置为1,就可以实现自适应效果了。使用flex布局的代码特别简洁,也是实现自适应布局的最佳方案,唯一的问题就是旧浏览器不兼容这一布局方式。不过其实如上面所说,其实现在需要适配旧浏览器的场景越来越少了,尤其是移动开发,flex可以完全放心使用。

table布局

table布局其实我们已经很熟悉了,就是表格布局,那么表格布局是这样实现三栏自适应的效果呢?其实不难理解,就是把三列都看做是表格,控制表格的显示情况即可,实现如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<style>
.container {
width: 100%;
display: table;
height: 200px;
}

.container>div {
display: table-cell;
}

.left {
width: 300px;
background: red;
}

.center {
background: yellow;
}

.right {
width: 300px;
background: blue;
}
</style>
<div class="container">
<div class="left"></div>
<div class="center">
<h1>表格布局</h1>
</div>
<div class="right"></div>
</div>


把外层容器设置成table,里面设置为table-cell,就可以很容易地实现布局需求。这种布局方式兼容性还特别好,因为表格是兼容旧浏览器的,虽然遭受很多诟病,但是真的可以解决问题。当然这种布局有缺点,缺点就是不灵活,边框设置、高度设置等等都有很大受限。

绝对定位布局

这种布局方式很明显了,利用绝对定位,实现起来非常容易

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<style>
.container>div {
position: absolute;
height: 200px;
}

.left {
left: 0;
width: 300px;
background: red;
}

.center {
left: 300px;
right: 300px;
background: yellow;
}

.right {
right: 0;
width: 300px;
background: blue;
}
</style>
<div class="container">
<div class="left"></div>
<div class="center">
<h1>绝对定位布局</h1>
</div>
<div class="right"></div>
</div>


绝对定位布局,很容易,效率也很高,不过实际开发中很少使用,原因也很简单,绝对定位的元素是脱离文档流的,可维护性会受限。

网格布局

最后再来看一个比较新的东西,网格布局,这个布局是新的css标准下的特性,在响应式布局大行其道的移动互联网时代,bootstrap之类的是对栅格化布局框架非常流行,而网格布局,就是对栅格布局的标准化实现,下面是用网格布局实现代码和效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<style>
.container {
display: grid;
width: 100%;
grid-template-rows: 200px;
grid-template-columns: 300px auto 300px;
}

.left {
background: red;
}

.center {
background: yellow;
}

.right {
background: blue;
}
</style>
<div class="container">
<div class="left"></div>
<div class="center">
<h1>网格布局</h1>
</div>
<div class="right"></div>
</div>


可以很明显地看出来,这种布局方式特别清晰,把整个页面设置成网格,设置网格内元素占的行和列,可以很容易实现想要的自适应效果。这种布局方式产生的时间相对较短,最大的问题是浏览器兼容性,不过新技术至少是要了解的。


以上就是对两边固定,中间自适应的布局的多种方式实现,实际使用时候,首先要考虑浏览器兼容情况,然后根据具体的业务中对元素宽高的要求限制,选择一种合适的布局方式来解决问题。

-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!