流体布局
左右模块各自向左右浮动,并设置中间模块的 margin 值使中间模块宽度自适应
- margin-left: 左边div宽度+边距
- margin-right: 右边div宽度+边距 缺点:主要内容无法最先加载,当页面内容较多时会影响用户体验
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.left {
float: left;
height: 200px;
width: 100px;
background-color: red;
}
.right {
width: 200px;
height: 200px;
background-color: blue;
float: right;
}
.main {
margin-left: 120px;
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>
BFC 三栏布局
BFC的表现原则,具有BFC特性的元素的子元素不会受到外部元素影响,也不会影响到外部元素。
对比上一个方法:可以把中间也变成 BFC,因为块级宽度默认是页面的100%,所以中间实现宽度自适应
例子中采用 overflow: hidden
缺点跟方法一类似,主要内容模块无法最先加载,当页面中内容较多时会影响用户体验。因此为了解决这个问题,有了后面要介绍的布局方案双飞翼布局。
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.left {
float: left;
height: 200px;
width: 100px;
margin-right: 20px;
background-color: red;
}
.right {
width: 200px;
height: 200px;
float: right;
margin-left: 20px;
background-color: blue;
}
.main {
height: 200px;
overflow: hidden;
background-color: green;
}
</style>
</head>
<body>
<div class="container">
<div class="left"></div>
<div class="right"></div>
<div class="main"></div>
</div>
</body>
</html>
双飞翼布局和圣杯布局
主体内容可以优先加载
利用的是浮动元素 margin 负值的应用
- 当static (非浮动、非定位)元素的margin-top/margin-left被赋予负值时,元素将被拉进指定的方向。
- -100%是与float流中前一元素的宽度做比较
我们通过下列过程来理解:
- 先加载中间主体内容,让它向左浮动起来,宽度设置为100%
- 让left向左浮动,设置中间主体的margin-right或者左边内容的margin-left为-100%,让left出现在左侧
- 让right向左浮动,设置右边内容的margin-right:-right-width,让他以右线为基准向左移动
- 但是此时,left和right覆盖在main的上面,存在遮挡问题
- 圣杯和双飞翼分别采用不同方式解决这个问题
<!DOCTYPE html>
<html lang="en">
<head>
<style>
*{
box-sizing: border-box;
}
.main {
float: left;
height: 500px;
background: blue;
width:100%;
}
.left {
width: 400px;
height: 500px;
background: lightpink;
}
.right {
width: 300px;
height: 500px;
background: lightgreen;
}
.left {
float: left;
margin-left: -100%;
}
.right {
float: left;
margin-right: -300px;
}
</style>
</head>
<body>
<div class="container">
<div class="main">我这里有好多好多的文本,但是本质上我是占整个页面的,后面的float流通过margin负值放在我的两侧,实质上是放在我的上面了,遮住我的部分</div>
<div class="left"></div>
<div class="right"></div>
</div>
</body>
</html>
圣杯布局
- 在main、left、right外面加一个包裹,设置外边距(预留给左右)
- 然后延续上面float得到一个类似上面的main被遮住的布局,但是布局外面有预留空白
- 对left、right进行相对定位,把他们移到预留的空白上
position: relative;
left: -120px;
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.container {
margin-left: 120px;
margin-right: 220px;
}
.main {
float: left;
width: 100%;
height: 300px;
background-color: red;
}
.left {
float: left;
width: 100px;
height: 300px;
margin-left: -100%;
position: relative;
left: -120px;
background-color: blue;
}
.right {
float: left;
width: 200px;
height: 300px;
margin-left: -200px;
position: relative;
right: -220px;
background-color: green;
}
</style>
</head>
<body>
<div class="container">
<div class="main"></div>
<div class="left"></div>
<div class="right"></div>
</div>
</body>
</html>
双飞翼
相比圣杯的思路就是,缩小main的内容范围
- 给 中间的main 加一个父元素main_f,main加上左右宽度的margin
- main_f与左右一起float
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.main_f {
float: left;
width: 100%;
}
.main {
height: 200px;
margin-left: 110px;
margin-right: 210px;
background-color: green;
}
.left {
float: left;
height: 200px;
width: 100px;
margin-left: -100%;
background-color: red;
}
.right {
float: left;
width: 200px;
height: 200px;
margin-left: -200px;
background-color: blue;
}
</style>
</head>
<body>
<div class="main_f">
<div class="main"></div>
</div>
<div class="left"></div>
<div class="right"></div>
</body>
</html>
Flex 布局
简单实用,未来的趋势,需要考虑浏览器的兼容性。
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.container {
display: flex;
}
.main {
flex-grow: 1;
height: 300px;
background-color: red;
}
.left {
order: -1;
flex: 0 1 200px;
margin-right: 20px;
height: 300px;
background-color: blue;
}
.right {
flex: 0 1 100px;
margin-left: 20px;
height: 300px;
background-color: green;
}
</style>
</head>
<body>
<div class="container">
<div class="main"></div>
<div class="left"></div>
<div class="right"></div>
</div>
</body>
</html>
Table 布局
缺点:无法设置栏间距
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.container {
display: table;
width: 100%;
}
.left, .main, .right {
display: table-cell;
}
.left {
width: 200px;
height: 300px;
background-color: red;
}
.main {
background-color: blue;
}
.right {
width: 100px;
height: 300px;
background-color: green;
}
</style>
</head>
<body>
<div class="container">
<div class="left"></div>
<div class="main"></div>
<div class="right"></div>
</div>
</body>
</html>
绝对定位布局
简单实用,并且主要内容可以优先加载。
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.container {
position: relative;
}
.main {
height: 400px;
margin: 0 120px;
background-color: green;
}
.left {
position: absolute;
width: 100px;
height: 300px;
left: 0;
top: 0;
background-color: red;
}
.right {
position: absolute;
width: 100px;
height: 300px;
background-color: blue;
right: 0;
top: 0;
}
</style>
</head>
<body>
<div class="container">
<div class="main"></div>
<div class="left"></div>
<div class="right"></div>
</div>
</body>
</html>