详解三栏布局

三栏布局在前端开发中特别常见,即两端固定中间自适应。
下面就来介绍一下常用的三栏布局开发方式。

例如:高度固定为200px,两边固定为200px,中间自适应,效果如图:
效果图

(1)Float方法

原理

  • 元素浮动后,脱离文档流。
  • 左右栏分别浮动在窗口两边,中间块(处于文档流中)受左右浮动影响被卡在中间无法继续向左右伸展已达到自适应,最后按需设置中间块的margin值来改变快间间隙即可。
  • 基于纯float实现的三栏布局需要将中间的内容放在HTML结构的最后,DOM结构为左-右-中,否则右侧会沉在中间内容的下侧 .

缺点

  • 由于DOM结构限制左-右-中,主要内容无法最先加载
  • 高度中间高度超出且没有margin的情况下会出问题(文字环绕):解决方案为创建BFC
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
<!DOCTYPE html>
<html lang="en">
<head>
    <style>
	.left {
	    float: left;
	    height: 200px;
	    width: 200px;
	    background-color: red;
	}
	.right {
	    width: 200px;
	    height: 200px;
	    background-color: blue;
	    float: right;
	}
	.main {
	    margin-left: 220px;
	    margin-right: 220px;
	    height: 200px;
	    background-color: green;
	}
    </style>
</head>
<body>
    <div class="container">
        <div class="left"></div>
        <div class="right"></div>
        <div class="main"></div>
    </div>
</body>
</html>

(2)绝对定位 position:absolute

原理:

  • 绝对定位的元素脱离文档流,相对于最近的已经定位的祖先元素进行定位。无需考虑HTML中结构的顺序

优点:

  • 方便快捷,主要内容可以优先加载。

缺点:

  • 由于容器脱离了文档流,导致子元素必须脱离文档流
  • 高度未知的情况下会出问题
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
<!DOCTYPE html>
<html lang="en">
<head>
    <style>
	.main {
	    height: 200px;
	    margin: 0 220px;
	    background-color: green;
	}
	.left {
	    position: absolute;
	    width: 200px;
	    height: 200px;
	    left: 0;
	    background-color: red;
	}
	.right {
	    position: absolute;
	    width: 200px;
	    height: 200px;
	    background-color: blue;
        right: 0;
	}
    </style>
</head>
<body>
    <div class="container">
    <div class="main"></div>
	<div class="left"></div>
	<div class="right"></div>
    </div>
</body>
</html>

(3)Flex布局

在讲flex布局之前我们先要了解一下flex布局的一些重要参数

(1)flex-grow:属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大

1
2
3
.item {
  flex-grow: <number>; /* default 0 */
}

 

如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。
flex-gorw

(2)flex-shrink:属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。

1
2
3
.item {
  flex-shrink: <number>; /* default 1 */
}

 

如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小(比例可通过属性数值调节)。
如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。

负值对该属性无效。

flex-shrink

(3)flex-basis:属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。

1
2
3
.item {
  flex-basis: <length> | auto; /* default auto */
}

 

它可以设为跟widthheight属性一样的值(比如350px),则项目将占据固定空间

(4)flex:flex属性是flex-growflex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。

1
2
3
.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

 

该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)

建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。

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
32
33
34
<!DOCTYPE html>
<html lang="en">
<head>
    <style>
	.container {
        display: flex;
	}
	.main {
        flex: 1;
		margin: 0 20px;
	    height: 200px;
	    background-color: green;
	}
	.left {
	    width: 200px;
	    height: 200px;
	    background-color: red;
	}
	.right {
	    width: 200px;
	    height: 200px;
	    background-color: blue;
	}
    </style>
</head>

<body>
    <div class="container">   <!-- flex布局的DOM顺序要按照 左-中-右 排-->
    <div class="left">  </div>
    <div class="main">  </div>
    <div class="right"> </div>
    </div>
</body>
</html>

 

(4)Table布局

优点:

  • 兼容性很好

缺点:

  • 无法设置栏边距,左中右模块间无间隔
  • 对SEO不够友好
  • 当一个格高度增加,其余的格也会被动增加高度
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
<!DOCTYPE html>
<html lang="en">
<head>
    <style>
        .container {
	    display: table;
	    width: 100%;
        }
        .left, .main, .right {
	    display: table-cell;
        }
        .left {
	    width: 200px;
	    height: 200px;
	    background-color: red;
        }
        .main {
	    background-color: green;
        }
        .right {
	    width: 200px;
	    height: 200px;
	    background-color: blue;
        }
    </style>
</head>
<body>
    <div class="container">
	<div class="left"></div>
	<div class="main"></div>
	<div class="right"></div>
    </div>
</body>
</html>

(5)grid布局

优点:

  • 简单方便

缺点:

  • 兼容性不强。高度未知的情况下会出问题。
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
<html lang="en">
<head>
    <style>
        .container {
	    display: grid;
	    width: 100%;
	    grid-template-rows: 200px;
	    grid-template-columns: 200px auto 200px;
        }
        .left {
	    background-color: red;
        }
        .main {
		margin: 0 20px;
	    background-color: green;
        }
        .right {
	    background-color: blue;
        }
    </style>
</head>
<body>
    <div class="container">
	<div class="left"></div>
	<div class="main"></div>
	<div class="right"></div>
    </div>
</body>
</html>

(6)圣杯布局

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
42
<!DOCTYPE html>
<html lang="en">
<head>
    <style>
	.container {  
	    margin-left: 220px;       /* 为左右栏腾出空间 */
	    margin-right: 220px;
	}
	.main {
	    float: left;
	    width: 100%;
	    height: 200px;
	    background-color: green;
	}
	.left {
	    float: left;
	    width: 200px;
	    height: 200px;
	    margin-left: -100%;
	    position: relative;
	    left: -220px;
	    background-color: red;
	}
	.right {
	    float: left;
	    width: 200px;
	    height: 200px;
	    margin-left: -200px;
	    position: relative;
	    right: -220px;
	    background-color: blue;
	}
    </style>
</head>
<body>
    <div class="container">
	<div class="main"></div>
	<div class="left"></div>
	<div class="right"></div>
    </div>
</body>
</html>

(0)DOM结构为中-左-右.container设置margin-leftmargin-right为左右栏腾出空间。

(1)中间部分需要根据浏览器宽度自适应,所以要用width:100%,这里设三栏均向左浮动,因为中间100%,左层和右层没有位置上去


(2)将左栏设置为margin-left:-100%后,发现left上去了。这是因为左栏已经在最左边了,向左移动时,由于左侧没空间了,只能往上挪。而向左挪100%就相当于移动了一个main的距离,相当于向上移。


(3)按第二步的方法,将右栏向左移动一个身位(即margin:-200px),这时右栏来到了上方的最右边。


(4)但由于左右栏遮挡住了中间部分,于是采用相对定位方法,各自相对于自己把自己挪出去,得到最终结果。

(7)双飞翼布局

圣杯布局实际看起来是复杂的后期维护性也不是很高,在淘宝UED的探讨下,出来了一种新的布局方式就是双飞翼布局,增加多一个div就可以不用相对布局了,只用到了浮动和负边距。和圣杯布局差异的地方已经被注释。

优点:

  • 结构简单,易维护

缺点:

  • 三栏之间难以插入空挡
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
42
43
44
<!DOCTYPE html>
<html lang="en">
<head>
    <style>
	.container {
	 /* margin-left: 220px;
	    margin-right: 220px; */
	}
	.main {
	    float: left;
	    width: 100%;
	    height: 200px;
	    background-color: green;
	}
	.left {
	    float: left;
	    width: 200px;
	    height: 200px;
	    margin-left: -100%;
        /*  position: relative;
	    left: -220px;         */
	    background-color: red;
	}
	.right {
	    float: left;
	    width: 200px;
	    height: 200px;
	    margin-left: -200px;
	/*  position: relative;
	    right: -220px;         */
	    background-color: blue;
	}
    </style>
</head>
<body>
    <div class="container">
	<div class="main">
		<div class="inner"></div>    <!-- 新增inner -->
	</div>
	<div class="left"></div>
	<div class="right"></div>
    </div>
</body>
</html>

 

转自http://kmknkk.xin/2018/03/02/CSS%E4%B8%89%E6%A0%8F%E5%B8%83%E5%B1%80/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值