css网页布局之浮动流
块级元素靠右实现方式: https://juejin.cn/post/6985480302030225415
# 网页布局
css网页布局: 指的是浏览器这款工具是如何对网页中的元素进行排版的
布局有三种方式:
1> 标准流
2> 浮动流
3> 定位流
# 标准流/文档流
<!--
标准流的排版方式,又称为:文档流/普通流
所谓的文档流,指的是元素排版布局过程中,元素会自动从左往右,从上往下的流式排列
在标准流中有两种排版方式,一种是垂直排版,一种是水平排版
1> 垂直排版 如果元素是块级元素,那么就会垂直排版
2> 水平排版 如果元素是行内元素或行内块级元素,那么就会水平排版
-->
2
3
4
5
6
7
8
# 浮动流
浮动流是一种 "半脱离文档流" 的布局方式.
# 脱离文档流
Q: 若给标签/盒子设置 float属性, 元素 左浮动或右浮动.浮动的元素脱离标准流意味着什么?
A:
1> 不再受块级or行内标签的限制(块级 行内是标准流中的概念),可以设置width和height.
2> **若在标准流的垂直方向有两个盒子, 如果前面一个元素浮动走了,而后面一个元素没有浮动.垂直方向上的盒子会向上占据浮动起来的盒子原先在标准流中的位置,而浮动的盒子会在其上方显示.. **
3> 元素浮动后, 它只能水平排版. 设置左对齐或者右对齐, 没有居中对齐, 也就是没有center这个取值.
即 margin:0 auto;
失效
Ps: 让两个块级元素显示到一行. [方式一]修改元素的显示方式为inline-block; [方式二]用浮动的方式..(简单些)
# 半脱离文档流
这个是正解!!很关键.. 是浮动流的 精髓 ..
浮动怎么回事,按照下面这个标准来,上文的结论是契合下方的定律的.
**浮动元素浮动之后的位置取决于它在浮动之前的标准流中的位置,跟标准流还是有一定的关系 **
(打个比方: 浮动流就是在标准流上面覆盖的一层透明薄膜,元素浮动之后就会被从标准流中扔到浮动流这个薄膜上,它在这个薄膜上的位置还是以前在标准流的位置, 会找同方向的浮动元素进行贴靠.)
比如说浮动的元素在浮动之前处于标准流的第二行,那么他浮动之后也是处于浮动流的第二行,不会去找其他行的浮动元素去贴靠. 贴靠的标准如下:
1> 同一个方向上谁先浮动,谁在前面
2> 不同方向上左浮动找左浮动,右浮动找右浮动
即浮动的框可以向左或者向右移动,直到它的外边缘碰到父盒子的边缘或另一个浮动盒子的边缘为止.
举个栗子深刻理解下!上文绿色标注的文字.
<注意哦!绿色和蓝色盒子都浮动时, 绿色盒子是距离蓝盒子右侧150px!!!>
也不难理解,都浮动会有个先后顺序,中途会改变后浮动盒子在标准流的位置,然后后浮动的盒子再浮动..
而margin-left是指的盒子与盒子之间左侧的距离...
<!--
最左侧是处于标准流,在垂直方向排列的三个盒子..其中绿色盒子`margin-left:150px;`
情况一: 只有绿盒子添加css属性`float:left;`
绿色盒子相对于它在标准流的位置浮动了起来,红盒子顶了上去.
情况二: 只有蓝盒子添加css属性`float:left;`
蓝盒子相对于它在标准流的位置浮动了起来,绿盒子和蓝盒子顶了上去.
情况二: 绿色盒子和蓝色盒子都浮动起来啦..
(肯定是有个先后浮动的顺序的,看标签树的结构 我想表达的是中途会顶上去,改变在标准流中的位置然后再浮动)
注意哦!绿色盒子是距离蓝盒子右侧150px!!!
PS: 浮动起来的盒子,是不管在标准流中的时候是块状行内什么类型的元素,都可以设置宽度和高度..
(有点类似于inline-block那味)
-->
<head>
<style>
.box1 {
width: 100px;
height: 100px;
background-color: cadetblue;
float: left;
}
.box2 {
width: 100px;
height: 100px;
background-color: darkseagreen;
margin-left: 150px;
float: left;
}
.box3 {
width: 300px;
height: 300px;
background-color: indianred;
}
</style>
</head>
<body>
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
</body>
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
45
46
47
# 浮动元素贴靠问题
若父元素的宽度足够显示所有元素时,浮动的元素就会并列显示
情况1: 当父元素的宽度不足以容纳水平排列的三个浮动元素时, ‘浮动元素’ 会向下移动,直到有足够的空间.
情况2: 若浮动元素的高度不同,那么当它向下移动时,可能会被其它浮动元素"卡住"..
三个框都向左浮动:
# 浮动元素字围现象
应用场景: 一般用于做图文混排..
举个栗子:
body里只有img标签和p标签两个兄弟标签..(p标签的内容是关于此图片的文字介绍)
设置css样式, 让img盒子左浮动,那么介绍的文字会围绕在图片周围.. 再举个栗子:
标准流中垂直方向有很多个盒子, 让第一个盒子左浮动,其余盒子设置css属性display: inline-block;
那么这些变成 “行内块级” 的盒子会围绕在第一个浮动的盒子周围..
# 浮动流排版练习
在企业开发中,如何对网页进行布局?
1> 垂直方向的布局用标准流布局,水平方向用浮动流布局
2> 从上至下布局
3> 从外向内布局
4> 水平方向可以先划分为一左一右,先对左边布局,再对右边布局
# 练习一
练习一: 实现下方的效果图.
初步分析: 垂直方向有三个盒子,每个盒子里分别有2 2 0个子盒子;先写好html标签布局,再为其加上css样式..
<!--
准备工作:清空浏览器默认的内外边距,方便布局..
(div.header>(div.logo+div.nav))+(div.content>(div.aside+div.article))+div.footer
先给三个大盒子加样式: 宽 高 背景颜色 内边距 盒子水平居中(margin:auto;)
再分别给大盒子中的小盒子加样式: 宽 高 背景颜色 浮动
注意:
大盒子与大盒子之间是有间距的 用margin解决
大盒子设置内边距后,保持盒子大小不变 box-sizing:border-box;
子盒子垂直方向居中(子盒子是父盒子的内容),设置其高度有讲究 `子盒子高度 = 父盒子高-父盒子上下内边距`
父盒子中的子盒子水平方向上的布局用浮动.
[进阶]响应式布局"根据页面的拖动进行等比例的放大缩小",盒子的宽高不能写死,应该使用百分比例的方式.
注意:
标准流中的块级盒子,不设宽度,默认就是父元素的宽度(占它爹宽度的百分之百).
如何让盒子的height:100%起作用?需要给这个元素的所有父元素的高度设定一个有效值.
三个大盒子中的子盒子,让其垂直方向居中,设置子盒子的`height:100%;`即可
因为子盒子是父盒子的内容..父盒子设置有padding和box-sizing,就不需要我们自己计算啦!
-->
<head>
<style>
* {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
}
body {
background-color: lightgray;
}
.header, .content, .footer {
margin: auto;
/*padding: 15px;*/
padding: 1%;
box-sizing: border-box;
}
.header {
/*height: 100px;*/
/*width: 960px;*/
height: 10%;
width: 80%;
background-color: red;
}
.logo {
/*height: 70px; */ /* 垂直方向 居中显示70=100-15*2 */
/*width: 300px;*/
height: 100%; /* box-sizing: border-box;会帮忙计算! */
width: 20%;
background-color: pink;
float: left; /* 水平方向布局用浮动 */
}
.nav {
/*height: 70px;*/
/*width: 600px;*/
height: 100%;
width: 70%;
background-color: yellow;
float: right;
}
.content {
/*margin-top: 10px;*/
/*margin-bottom: 10px;*/
margin-top: 1%;
margin-bottom: 1%;
/*height: 500px;*/
/*width: 960px;*/
height: 78%;
width: 80%;
background-color: green;
}
.aside {
/*height: 470px; */ /* 470=500-15*2 */
/*width: 300px;*/
height: 100%;
width: 20%;
background-color: purple;
float: left;
}
.article {
/*height: 470px;*/
/*width: 600px;*/
height: 100%;
width: 70%;
background-color: lightblue;
float: right;
}
.footer {
/*height: 100px;*/
/*width: 960px;*/
height: 10%;
width: 80%;
background-color: blue;
}
</style>
</head>
<body>
<div class="header">
<div class="logo"></div>
<div class="nav"></div>
</div>
<div class="content">
<div class="aside"></div>
<div class="article"></div>
</div>
<div class="footer"></div>
</body>
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# 练习二
练习二: 实现下方的效果图.
大体思路:按照html标签布局的级别(看缩进),一步步一个级别一个级别的设置css样式.
过程中可以给盒子加边框进行辅助调试. 注意两点:
1> 水平方向的布局用浮动
2> 当margin/padding取形式为 百分比 的值时
无论是left/right,还是top/bottom,都是以 父元素的width 为参照的!
所以代码中几个盒子的高度加上边距看似加起来是100%,实则不是 待解决.
<!--
div.header + (div.content>(div.aside+(div.article>((div.articleTop>(div.articleTopLeft>(div.new1+div.new2))+div.articleTopRight)+div.articleBottom)))) + div.footer
-->
<head>
<style>
* {
padding: 0;
margin: 0;
}
body, html {
height: 100%;
}
body > div {
margin: auto;
}
/* 三个大盒子 */
.header {
width: 80%;
height: 10%;
background-color: pink;
}
.content {
width: 80%;
height: 78%;
margin-top: 1%;
margin-bottom: 1%;
}
.footer {
width: 80%;
height: 10%;
background-color: red;
}
/* 中间内容分为了左右两部分 */
.content .aside {
height: 100%;
width: 30%;
background-color: yellow;
float: left;
}
.content .article {
height: 100%;
width: 66%;
float: right;
}
/* 中右又分为了上下两部分 */
.article .articleTop {
width: 100%;
height: 85%;
margin-bottom: 5%;
}
.article .articleBottom {
width: 100%;
height: 10%;
background-color: saddlebrown;
}
/* 中右上部分又分为了左右两部分 */
.articleTop .articleTopLeft {
width: 60%;
height: 100%;
float: left;
}
.articleTop .articleTopRight {
width: 38%;
height: 100%;
background-color: darkgoldenrod;
float: right;
}
/* 继续细分 */
.articleTopLeft .new1 {
width: 100%;
height: 48%;
background-color: blueviolet;
margin-bottom: 4%;
}
.articleTopLeft .new2 {
width: 100%;
height: 48%;
background-color: blueviolet;
}
</style>
</head>
<body>
<div class="header"></div>
<div class="content">
<div class="aside"></div>
<div class="article">
<div class="articleTop">
<div class="articleTopLeft">
<div class="new1"></div>
<div class="new2"></div>
</div>
<div class="articleTopRight"></div>
</div>
<div class="articleBottom"></div>
</div>
</div>
<div class="footer"></div>
</body>
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# 清除浮动
# 父级塌陷
在标准流中, 内容的高度是 '可以' 撑起父元素高度的; 在浮动流中, 浮动的元素是 '不可以' 撑起父元素的高度的. 当子元素都浮动起来后, 父元素的内容高度height变为0, 父元素就好像塌陷了一样, 因而称为父级塌陷.
box2浮动,box1塌陷,box3挤了上去..**!我们需要解决父级塌陷带来的布局影响! **
解决啥?简单来说,就下方这个情景而言,不让box3挤上去..
<!--
box2浮动起来后不在标准流中啦,而它的父级盒子box1还在标准流中
儿子走了,没人给父亲撑起,box1就塌陷诺,box3挤了上去. ( ̄O ̄;)
-->
<head>
<style>
.box1 {
width: 500px;
border: 1px solid green;
}
.box2 {
width: 200px;
height: 100px;
background-color: lightblue;
float: left; /* 父级塌陷 */
}
.box3{
width: 300px;
height: 200px;
background-color: lightsalmon;
}
</style>
</head>
<body>
<div class="box1">
<div class="box2"></div>
</div>
<div class="box3"></div>
</body>
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
# 解决方案之height
为浮动的那些子元素的父亲设置一个高度. -- 此方案比较 愚蠢(´▽`) .
在企业开发中,这样限定固定高度会使页面操作不灵活,不推荐!
看这里! 在上面的"浮动流排版练习 "中,为啥没出现父级塌陷的问题?因为都设置了高度.. so I am a fool.(⁎⁍̴̛ᴗ⁍̴̛⁎)
# 解决方案之clear
clear : none | left | right | both ○「取值」 none -- 默认值. 允许两边都可以有浮动对象 left -- 不允许左边有浮动对象 right -- 不允许右边有浮动对象 both -- 不允许左右有浮动对象
1
2
3
4
5
6
给box3添加css属性, clear: both;
其余代码不变
.box3{
width: 300px;
height: 200px;
background-color: lightsalmon;
/* 一旦这行的左右两边有浮动盒子,就切换到下一行,以此来解决父级塌陷带来的布局问题 */
clear: both;
}
2
3
4
5
6
7
这种方式有弊端:
当我们给某个元素添加clear属性之后, 那么这个元素的 margin-top属性 不好用|还可能会失效..
<head>
<style>
.box1 {
width: 500px;
/* border: 1px solid green; */
}
.box2 {
width: 200px;
height: 100px;
background-color: lightblue;
/* 浮动起来还是要受限于在标准流的位置,要看在哪一行的 */
float: left;
}
.box3 {
width: 300px;
height: 200px;
background-color: lightsalmon;
clear: both;
/*
margin-top是标准流中的属性,(此盒子上方的那个盒子将此盒子往下顶指定的距离)
box3盒子上方那个盒子是box1
[若盒子box1即没有高度也没有边框]
那么此margin-top就是相对于父盒子body元素来说的了.
这就涉及到了margin-top塌陷的问题:(回顾一下)
两个嵌套的盒子,内层盒子设置的margin-top后会将外层盒子一起顶下来.
Ps:准确点来说,盒子嵌套,某子盒子设置margin-top,它的上方盒子是其父盒子,
那么就会出现margin-top塌陷问题..不会出现我们期待的子盒子距离父盒子指定的距离..,
而会出现margin-top的属性在父盒子上生效..
解决的方式之一就是给父盒子加边框..(给父盒子设置宽高背景颜色这些属性是解决不了的)
这里父盒子是body,子盒子是box2.. 按理说,body会被一起顶下来,但body元素很特殊,不会被顶下来.
因而margin-top失效,哪怕设置10000px也没用.
当然可以给body设置边框解决margin塌陷问题,但往往不会给body设置边框..
[大前提:若盒子box1没有高度设的有边框]
本来box3是紧贴box1下边框的,因为clear:both;被迫移到了99px开外,身处box2盒子下方.
为啥是99px?因为浮动的box2是贴着box1的上边框浮动的,'box1的边框我们设置的1px'.
box2高100px.100px减去下边框的1px..所以margin-top设置>99px才会有效果..
总结:它爹没边框,设置再大也没用;有边框,需要计算..太麻烦.
*/
margin-top: 99px;
}
</style>
</head>
<body>
<div class="box1">
<div class="box2"></div>
</div>
<div class="box3"></div>
</body>
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
45
46
47
48
49
50
51
52
53
54
# 解决方案之隔墙法
△ 外墙法
step1: 在两个盒子中间添加一个额外的块级元素
step2: 给这个额外添加的块级元素设置clear:both;
属性
[注意]
1> 外墙法它可以让第二个盒子使用margin-top属性
2> 外墙法不可以让第一个盒子使用margin-bottom属性
我们通常用墙的高度作margin的替代品
在企业开发中可以为墙添加一个class="h20",然后设置其高度为20px,间接实现外间距,搜狐网站大量使用了外墙法.
<!--
添加css样式
.wall {
clear: both;
height: 20px; /* 相当于盒子box3设置margin-top:20px; */
}
-->
<body>
<div class="box1">
<div class="box2"></div>
</div>
<div class="wall h20"></div> <!-- 外墙 -->
<div class="box3"></div>
</body>
2
3
4
5
6
7
8
9
10
11
12
13
14
△ 内墙法
step1: 在第一个盒子中的最后添加一个额外的块级元素 (第一个盒子是可能塌陷的盒子)
step2: 给这个额外添加的块级元素设置clear:both;
属性
[注意]
1> 内墙法它可以让第二个盒子使用margin-top属性
2> 内墙法可以让第一个盒子使用margin-bottom属性
<!--
添加css样式
.wall {
clear: both;
/*
相当于盒子box3设置margin-top:20px;
相当于盒子box1设置margin-bottom:20px;
*/
height: 20px;
}
-->
<body>
<div class="box1">
<div class="box2"></div>
<!-- box2浮动了,内墙说别动我,我就在原地待着.因而box1依旧被撑着. -->
<div class="wall h20"></div> <!-- 内墙 -->
</div>
<div class="box3"></div>
</body>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
△ 内墙法与外墙法的区别
1> 外墙法不可以撑起第一个盒子的高度, 而内墙可以
2> 在企业开发中清除浮动, 内墙法与外墙法都不常用
在前端开发中推崇结构与样式分离, 而隔墙法需要添加大量的没有意义的空标签div
# 解决方案之伪元素
本质原理与内墙法一样, 但通过css的伪元素选择器实现符合前端开发思想.
通常使用这种方式清除浮动...[回顾]
伪元素选择器的作用就是给指定标签的内容前面添加一个子元素
或者给指定标签的内容后面添加一个子元素
<head>
<style>
/* 兼容ie6,否则伪类选择器只能在谷歌浏览器中生效 */
.clearfix {
*zoom:1;
}
/*
前后分别加一个不占空间(因而不会影响布局)的table元素,
before的作用是子元素设置margin-top时父元素不会一起被顶下来
after的作用是清除浮动
必须要写的是下面这三句话
content: "";
display: table;
clear: both;
*/
.clearfix:before,.clearfix:after {
content: "";
display: table;
}
.clearfix:after {
clear: both; /* 清除左右两边浮动 */
}
</style>
</head>
<body>
<div class="box1 clearfix"> <!-- 添加一个类 clearfix -->
<div class="box2"></div>
</div>
<div class="box3"></div>
</body>
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
# 解决方案之overflow
给可能塌陷的父盒子box1添加css属性, overflow: hidden;
overflow:hidden
它除了清除浮动; 还可以将超出标签范围的内容裁剪掉;以及解决margin-top塌陷问题..