浮动和定位详解
CSS浮动定位
普通流定位
定义元素框相对于其正常位置应该出现的位置
浮动定位
浮动特性
-
将元素排除在普通流之外
-
元素将不在页面中占据空间
-
将浮动元素放置在包含框的左边或者右边
-
浮动元素依旧位于包含框之内
-
浮动的框可以向左或者向右移动,直到他的外边缘碰到包含框或另一个浮动框的边框为止
-
浮动元素的外边缘不会超过其父元素的内边缘
-
浮动元素不会互相重叠
-
浮动元素不会上下浮动
-
行内元素浮动后会变为块级元素
-
语法:float:none/left/right;
实例讲解
-
当框1向左浮动时,它脱离文档流并且向左移动,直到它的左边框碰到包含框的左边缘
-
包含框中有三个元素,如果把框1向右浮动,则它脱离文档流并且向右移动,直到它的右边框碰到包含框的右边框
-
如果把三个框都向左移动,那么框1向左浮动直到遇到包含框,另外两个框向左浮动直到碰到前一个浮动框,三个框在同一行显示
-
如果包含框太窄,那么其他浮动块会自动向下移动,直到有足够的空间(左图),如果浮动元素的高度不同,那么当他们向下移动时可能被其他浮动元素卡住(右图)
清除浮动
清除浮动是在使用了浮动之后必不可少的,为了网站布局的效果,清除浮动也变得非常麻烦。
属性:clear
值:left、right、both
清除浮动的常用方式:
- 结尾处加空div标签 clear:both (或在下一个元素上加clear:both;)
- 浮动元素的父级div定义 伪元素::after
- 浮动元素的父级div定义 overflow:hidden
- 浮动元素的父元素定高
position
position 的四个值 static、relative、absolute、fixed
绝对定位:absolute 和 fixed 统称为绝对定位
相对定位:relative
默认值:static
实例
没使用定位和浮动时的代码样式
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
<style>
.box1{
height:100px;
background-color:red;
}
.box2{
height:100px;
background-color:green;
}
.box3{
height:100px;
background-color:blue;
}
.box4{
height:100px;
background-color:yellow;
}
.box5{
height:100px;
background-color:cyan;
}
</style>
</head>
<body>
<div class="box1">box1box1box1box1box1</div>
<div class="box2">box2box2box2box2box2</div>
<div class="box3">box3box3box3box3box3</div>
<div class="box4">box4box4box4box4box4box4box4box4box4box4box4box4</div>
<div class="box5">box5box5box5box5box5</div>
</body>
</html>
效果
相对定位:relative
relative:相对于原来位置移动,元素设置此属性之后仍然处在文档流中,不影响其他元素的布局
给上面示例的第二个box设置relative:
代码
.box2{
height:100px;
background-color:green;
position:relative;
top:50px;
left:50px;
}
效果
可以看出元素相对于原来位置偏移,宽高都没变,撑大了容器。
绝对定位:absolute
absolute:元素会脱离文档流,如果设置偏移量,会影响其他元素的位置定位
将上面示例的第二个box改回去并给第五个box设置absolute:
元素在没有定义宽度的情况下,宽度由元素里面的内容决定,效果和用float方法一样
代码
.box5{
height:100px;
background-color:cyan;
position:absolute;
}
效果
absolute定位原理剖析:
父元素没有设置相对定位或绝对定位
在父元素没有设置相对定位或绝对定位的情况下,元素相对于根元素定位(即html元素)(是父元素没有)。
现在给box5偏移值来验证:
代码
.box5{
height:100px;
background-color:cyan;
position:absolute;
top:50px;
left:50px;
}
效果
父元素设置了相对定位或绝对定位
父元素设置了相对定位或绝对定位,元素会相对于离自己最近的设置了相对或绝对定位的父元素进行定位(或者说离自己最近的不是static的父元素进行定位,因为元素默认是static)。
补充:网上有人解释为元素会相对于第一个不是static的父元素定位,我觉得这很容易让人产生误解。以上是我自己的定义。
现在给body元素一个绝对定位(body元素设置为了absolute,整个容器的宽度由最长div决定,宽度变小了):
代码
<body style="position:absolute">
<div class="box1">box1box1box1box1box1</div>
<div class="box2">box2box2box2box2box2</div>
<div class="box3">box3box3box3box3box3</div>
<div class="box4">box4box4box4box4box4</div>
<div class="box5">box5box5box5box5box5</div>
</body>
效果
此时的box5现在相对于body元素定位
我把上面相对于html元素定位和相对于body定位的两张图放在一起,对比可以看到下面的图,相对于body定位的box5距离文字box1要远一点。所以在没有父元素设置相对定位或绝对定位的情况下,设置了absolute的元素会相对于html根元素定位。
再来验证这句话:父元素设置了相对定位或绝对定位,元素会相对于离自己最近的设置了相对或绝对定位的父元素进行定位
现在给box们套三个父容器,如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
<style>
.box1{
height:100px;
background-color:red;
}
.box2{
height:100px;
background-color:green;
}
.box3{
height:100px;
background-color:blue;
}
.box4{
height:100px;
background-color:yellow;
}
.box5{
height:100px;
background-color:cyan;
position:absolute;
top:50px;
left:50px;
}
.rongqi1{
height:900px;
position:absolute;
background-color:#006699;
}
.rongqi2{
height:700px;
position:relative;
background-color:#00b6f6;
top:50px;
}
.rongqi3{
height:500px;
position:relative;
top:50px;
background-color:#FF00FF;
}
</style>
</head>
<body style="position:absolute;">
<div class="rongqi1">
最外层容器
<div class="rongqi2">
第二层容器
<div class="rongqi3">
<div class="box1">box1box1box1box1box1</div>
<div class="box2">box2box2box2box2box2</div>
<div class="box3">box3box3box3box3box3</div>
<div class="box4">box4box4box4box4box4box4box4box4box4box4box4box4</div>
<div class="box5">box5box5box5box5box5</div>
我是第三层容器,我被box们盖住了,露出一点点
</div>
</div>
</div>
</body>
</html>
效果
现在的样子,现在的box5并不是所说的相对于第一个不是static的元素定位(按这句话的说法,现在我的box5应该相对于最外层容器1偏移才对),而是相对于离自己最近的一层的设置了相对或绝对定位的父元素定位:
现在把第二个容器和第三个容器的position注释掉(没有position,设置top、left、bottom、right值都没有效),代码如下:
.rongqi2{
height:700px;
background-color:#00b6f6;
top:50px;
}
.rongqi3{
height:500px;
top:50px;
background-color:#FF00FF;
}
现在box5的外层设置了相对或绝对的父元素只有最外层容器1,所以box5现在相对于最外层容器1定位。(明显box5移动了)
现在只注释掉第三个容器的position
原理也是一样,现在相对于第二个容器定位(top:50px,离自己最近的设置了相对或绝对定位的父元素):
.rongqi2{
height:700px;
position:relative;
background-color:#00b6f6;
top:50px;
}
.rongqi3{
height:500px;
//position:relative;
top:50px;
background-color:#FF00FF;
}
效果
上面第二个和第三个容器都设置的是相对定位,现在改成绝对定位
.rongqi1{
height:900px;
position:absolute;
background-color:#006699;
}
.rongqi2{
height:700px;
position:absolute;
background-color:#00b6f6;
top:50px;
}
.rongqi3{
height:500px;
position:absolute;
top:50px;
background-color:#FF00FF;
}
原理和把第二、第三个容器设置为relative一样,只是设置为absolute了之后,第三个容器包含着内容一起脱离了文档,所以没有撑开外面两层容器的宽度
现在的效果:
外面再添一个容器,来验证上面第一、第二没有被撑开的效果
宽度受到上一层的父容器的宽度限制,现在拉宽第一层的容器的宽度,第二层和第三层随之变宽,效果如下:
.rongqi1{
width:400px;
height:900px;
position:absolute;
background-color:#006699;
}
效果
但是如果容器里面有长的div,容器仍然可以被撑开,效果如下:
补充:
box2设置为absolute定位之后,脱离文档流,box3向上移,左边被box2遮盖了。
在上面的基础上,box3设置absolute,box3脱离文档流(就好像box3浮起来了一样,浮在了box2上面),box4往上移,box3盖住box2,和部分box4.
同理如果box4设置了绝对定位,就会浮起来盖住box3和box2。
下面是完整的代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
<style>
.box1{
height:100px;
background-color:red;
}
.box2{
height:100px;
background-color:green;
position:absolute;
}
.box3{
height:100px;
background-color:blue;
position:absolute;
}
.box4{
height:100px;
background-color:yellow;
}
.box5{
height:100px;
background-color:cyan;
position:absolute;
top:50px;
left:50px;
}
.rongqi1{
width:400px;
height:900px;
position:absolute;
background-color:#006699;
}
.rongqi2{
height:700px;
position:absolute;
background-color:#00b6f6;
top:50px;
}
.rongqi3{
height:500px;
//position:absolute;
top:50px;
background-color:#FF00FF;
}
</style>
</head>
<body>
<div class="rongqi1">
最外层容器
<div class="rongqi2">
第二层容器
<div style="background-color:#00FA9A">
我是第三层容器,我是新添加的容器
我是第三层容器,我是新添加的容器我是第三层容器,我是新添加的容器
<div style="background-color:#9370DB;width:700px">
我里是新新添加的容,我把第三层容器撑开了
<div class="rongqi3">
我是第四层容器
<div class="box1">box1box1box1box1box1</div>
<div class="box2">box2box2box2box2box2</div>
<div class="box3">box3box3box3box3box3</div>
<div class="box4">box4box4box4box4box4box4box4box4box4box4box4box4</div>
<div class="box5">box5box5box5box5box5</div>
我是第四层容器,我被box们盖住了,露出一点点
</div>
</div>
</div>
</div>
</div>
</body>
</html>
总结
-
relative:定位是相对于自身位置定位(设置偏移量的时候,会相对于自身所在的位置偏移)。设置了relative的元素仍然处在文档流中,元素的宽高不变,设置偏移量也不会影响其他元素的位置。最外层容器设置为relative定位,在没有设置宽度的情况下,宽度是整个浏览器的宽度。
-
absolute:定位是相对于离元素最近的设置了绝对或相对定位的父元素决定的,如果没有父元素设置绝对或相对定位,则元素相对于根元素即html元素定位。设置了absolute的元素脱了了文档流,元素在没有设置宽度的情况下,宽度由元素里面的内容决定。脱离后原来的位置相当于是空的,下面的元素会来占据位置。
z-index
直接借用上面的例子,如下图可以看出box3因为浮在box2上面把box遮住了,这个时候我们给box2设置一个比box3 的z-index值的值的话,box2就会把box3遮盖住
代码
.box2{
height:100px;
background-color:green;
position:absolute;
z-index:9;
}
效果
box2把box3遮盖住了
display
根据CSS规范的规定,每一个网页元素都有一个display属性,用于确定该元素的类型,每一个元素都有默认的display属性值,比如div元素,它的默认display属性值为“block”,称为块元素,而span元素的默认display属性值为“inline”,称为“行内”元素。
块元素与行元素是可以转换的,也就是说display的属性值可以由我们来改变
display常见属性值
- none:隐藏对象
- inline:指定对象为内联元素
- block:指定对象为块元素
- inline-block:指定对象为内联块元素
- table-cell:指定对象作为表格单元格
- flex:弹性盒
下一篇: css-布局