重写于 2018-02-25,大部分参考于 https://zhuanlan.zhihu.com/p/25070186?refer=learncoding
1. 流体布局
简单来说就是 -- 两边浮动,中间设置 margin
html
<div class="wrap">
<div class="left"></div>
<div class="right"></div>
<div class="main"></div>
</div>
css
* {
margin: 0;
padding: 0;
}
.left, .right, .main {
height: 300px;
}
.left {
200px;
float: left;
background-color: #089e8a;
}
.right {
float: right;
200px;
background-color: #19f;
}
.main {
margin-left: 250px;
margin-right: 250px;
background-color: #080;
}
2. BFC布局
什么是BFC?
我的答案参考于:http://www.php.cn/div-tutorial-371936.html
BFC区域,不会与浮动元素重叠。
- BFC定义:(Block Formatting Contexts)块级格式上下文,是一个独立渲染的区域。
它是一个独立的盒子。独立盒子内部的布局不受外部的影响,也不影响外部。是不是和
absolute
的哲学有点相似!
- BFC解决了什么问题?看一下这个例子(同一个BFC中会出现):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
* {
margin: 0;padding: 0;
}
.p1 {
background-color: #FCE38A;
200px;
height: 100px;
margin-bottom: 50px;
}
.p2 {
background-color: #EAFFD0;
200px;
height: 100px;
margin-top: 50px;
}
.p3 {
background-color: #95E1D3;
200px;
height: 100px;
}
</style>
</head>
<body>
<p class="p1"></p>
<p class="p2"></p>
<p class="p3"></p>
</body>
</html>
1.没有设置margin
值的时候,大家是这样的。
2.在 p1 和 p2 分别设置了 50px 的 margin 之后,是这样的。
3.在这里出现了外边距合并的现象,并没有出现 100px 的距离。这就是BFC要解决的问题。
-
BCF规则
- 内部的box会在垂直方向,从顶部开始一个接着一个地放置(上面的例子可以看出)
- 同一个BFC中,在两个相邻的块级元素中,垂直margin会发生折叠
- 每个元素的margin box的左边, 与包含块border box的左边相接,对于从左往右的格式化,否则相反),即使存在浮动也是如此
- BFC的区域不会与float box重叠
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然
- 计算BFC的高度时,浮动元素也参与计算
-
如何触发BFC?前缀是
根元素
- float属性不为none(如:left | right)
- overflow的值不为visible(如:hidden | auto | scroll)
- display属性值为inline-block | flex | inline-flex | table-cell | table-caption
- position为absolute或fixed
-
应用BFC,解决
margin
重叠问题(上例中 body 元素就是一个BFC)- 根据规则:同一个BFC中,在两个相邻的块级元素中,垂直margin会发生折叠
所以我们给
p1
设置display:inline-block
,让其不为block
此时由于p1元素通过display:inline-block
触发了BFC,此时的p1就是一个独立的BFC了,根据规则BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然
清除浮动亦可使用BFC原理,具体还请看外链:http://www.php.cn/div-tutorial-371936.html
总结:BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,同样的,外面的元素也不会影响到容器里面的子元素。
BFC布局方式的三列
css
* {
margin: 0;
padding: 0;
}
.left {
float: left;
height: 200px;
200px;
margin-right: 50px;
background-color: #fce38a;
}
.right {
float: right;
height: 200px;
200px;
margin-left: 50px;
background-color: #eaffd0;
}
.main {
height: 200px;
overflow: hidden;
background-color: #95e1d3;
}
html
<div class="container">
<div class="left"></div>
<div class="right"></div>
<div class="main"></div>
</div>
3. 双飞翼布局
特点是:主内容优先加载。 原理是:浮动元素 margin 负值的应用。
css
* {
margin: 0;
padding: 0;
}
.content {
float: left;
100%;
}
.main {
height: 200px;
margin-left: 250px;
margin-right: 250px;
background-color: #95e1d3;
}
.left {
float: left;
margin-left: -100%;
200px;
height: 200px;
background-color: #fce38a;
}
.right{
float: left;
margin-left: -200px;
200px;
height: 200px;
background-color: #eaffd0;
}
html
<div class="content">
<div class="main"></div>
</div>
<div class="left"></div>
<div class="right"></div>
4. 圣杯布局
圣杯布局和双飞翼布局很像。。可以说是 双飞翼 改!! html结构简单了,css复杂些
当我把 中间层 的 margin
去掉后,我发现(个人发现,仅做参考或者不看):
圣杯用
padding
,双飞翼用margin
- 双飞翼布局的 中间占了全屏。 但是两边被遮挡了。 仿佛是两个翅膀 挡住了 中间。
- 圣杯布局的 中间占了全屏。 把两边也一起这该住了。 仿佛是两个侧边将 中间 顶到了最上层。
css
* {
margin: 0;
padding: 0;
}
.container {
padding: 0 250px;
}
.main {
float: left;
100%;
height: 200px;
background-color: #95e1d3;
}
.left {
position: relative;
left: -250px;
margin-left: -100%;
float: left;
200px;
height: 200px;
background-color: #fce38a;
}
.right {
position: relative;
float: left;
200px;
height: 200px;
background-color: #eaffd0;
margin-left: -200px;
left: 250px;
}
html
<div class="container">
<div class="main"></div>
<div class="left"></div>
<div class="right"></div>
</div>
5. Flex 布局
时代在变化!!浏览器兼容,看见我就怂。
先看实现吧,优雅简单。
css
* {
margin: 0;
padding: 0;
}
.container {
display: flex;
}
.main {
flex-grow: 1;
height: 300px;
background-color: #95e1d3;
}
.left {
order: -1;
flex: 0 1 200px;
margin-right: 50px;
height: 300px;
background-color: #fce38a;
}
.right {
flex: 0 1 200px;
margin-left: 50px;
height: 300px;
background-color: #eaffd0;
}
html
<div class="container">
<div class="main"></div>
<div class="left"></div>
<div class="right"></div>
</div>