上章我们聊了和absolute的流体特性以及和absolute搭配使用的CSS属性,本章我们就来聊一聊position家族的另外两大成员——relative和fixed。
1.relative的定位(不推荐使用)
理论上relative/absolute/fixed都能对absolute的"包裹性"以及"定位"产生限制,但只有relative能使得元素保持在正常的文档流中,因此我们往往使用absoluted搭配relative使用。之前讲到,left/right/top/bottom是定位家族的特有属性,因此relative也支持定位,且relative定位有两大特性:一是相对自身定位,二是“无侵入”。为了更好的展示relative的特性,我们引入absolute元素进行对比。
测试一:left:0,top:0;
<!-- relative定位测试 -->
<div class="container">
<div class="relative">relative</div>
<div class="absolute">absolute</div>
</div>
<style>
.container{
width: 200px;
height: 200px;
background: #999999;
padding:100px;
border:5px solid red;
position: relative;
}
.relative{
width: 100px;
height: 100px;
background: green;
position: relative;
left: 0;
top: 0;
}
.absolute{
width: 100px;
height: 100px;
background: yellow;
position: absolute;
left: 0;
top: 0;
}
</style>
第一个测试,absolute元素的包含块是父元素的padding-box,因此absolute移到包含块左上角,而relative元素纹丝不动。
测试二:left:100px;top:100px;
测试二的结果表明relative元素是相对于自身发生偏移的,也就是说relative的偏移位置跟他原来所处的位置有关,也就是第一个特性——相对自身定位。
测试三:加入吃瓜群众。
relative定位前:
<!-- relative定位测试 -->
<div class="container">
<div class="">我是一个吃瓜群众</div>
<div class="relative">relative</div>
<!-- <div class="absolute">absolute</div> -->
<div class="">我是一个吃瓜群众</div>
</div>
<style>
.container{
width: 200px;
height: 200px;
background: #999999;
padding:100px;
border:5px solid red;
position: relative;
}
.relative{
width: 100px;
height: 100px;
background: green;
position: relative;
/*left: 100px;
top: 100px;*/
}
.absolute{
width: 100px;
height: 100px;
background: yellow;
position: absolute;
left: 100px;
top: 100px;
}
</style>
relative定位后
<!-- relative定位测试 -->
<div class="container">
<div class="">我是一个吃瓜群众</div>
<div class="relative">relative</div>
<!-- <div class="absolute">absolute</div> -->
<div class="">我是一个吃瓜群众</div>
</div>
<style>
.container{
width: 200px;
height: 200px;
background: #999999;
padding:100px;
border:5px solid red;
position: relative;
}
.relative{
width: 100px;
height: 100px;
background: green;
position: relative;
left: 100px;
top: 100px;
}
.absolute{
width: 100px;
height: 100px;
background: yellow;
position: absolute;
left: 100px;
top: 100px;
}
</style>
可以发现:relative元素相对于自身定位前后,吃瓜群众的位置保持不变,只有relative相对于自身发生了偏移,因此relative是一种无侵入的定位,不会影响其他元素原来的布局行为。
除此之外,relative定位还有两个点值得一提,首先是相对定位元素的left/right/top/bottom的百分比值是相对于包含块进行计算的,还有一点是当relative元素同时出现相同方向上的定位时(如left:0,right:0)不会保持absolute的拉伸特性,而是取文档流方向的一边作为唯一值,也就是只保留left和top。
在测试三中,我们看到了一个层叠现象,由于relative元素的层叠顺序是"鬼畜"级别的(我也不懂这是什么意思),因此作者不建议使用relative进行定位。因此relative几乎可以看作是absolute的附属css了。
2.无依赖固定定位(fixed)
position:fixed的固定定位元素的"包含块"是根元素(近似<html>),也就是除了根元素没人能限制fixed元素?不知你是否还记得无依赖绝对定位的特性,下面我们来测试一下,是否有无依赖固定定位。
<!-- 无依赖固定定位 -->
<div class="container">
<span>随便说两句</span>
<div class="fixed"></div>
</div>
<style type="text/css">
.container{
width: 200px;
height: 200px;
background: #999999;
padding:100px;
border:5px solid red;
}
.fixed{
width: 100px;
height: 100px;
background: green;
position: fixed;
}
</style>
经过测试,确实存在无依赖固定定位,且表现和无依赖绝对定位“相同”。那么知道了这个特性有什么用呢?个人认为,没什么软用,既然用了固定定位,就是要利用其依赖跟元素进行定位,所以无依赖固定定位也就没什么软用了。
3.利用fixed固定定位生成滚动条锁定的弹窗
通常情况下,弹窗功能需要依托浏览器进行定位,而不是某个元素,因为我们希望弹窗总能出现在屏幕的“居中”位置,要实现这个功能非常简单,只需要用到固定定位即可。
<!-- 固定定位生成弹窗 -->
<div class="fixed">
<div>我是弹窗</div>
</div>
<style>
html,body{
margin: 0;
height: 200%;
background-image: url('../小和尚.jpg');
}
.fixed{
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
background: rgba(0,0,0,0.5);
margin: auto;
}
.fixed div{
position: absolute;
right: 0;
top: 0;
left: 0;
bottom: 0;
width: 40%;
height: 30%;
background: #fff;
margin: auto;
overflow: auto;
}
</style>
我们实现了居中效果,但还有一个麻烦就是fixed元素的包含块是html,因此html的内容有滚动条的时候,在弹窗页面我们依旧可以控制html滚动条的滚动,这样的用户体验并不好。
因此如果我们需要一个滚动条固定的弹窗效果,必须让滚动条不在html上,我们可以在html下面生成一个父级容器,让父级容器来生成滚动条,这样就不会影响fixed固定定位了。如下所示
<!-- 固定定位生成不能滚动的弹窗 -->
<div class="father">
<div style="height: 200%;background: url('../小和尚.jpg');">我来生成滚动条</div>
<div class="fixed">
<div>我是弹窗</div>
</div>
</div>
<style>
html,body{
margin: 0;
height: 100%;
overflow: hidden;
}
.father{
height: 100%;
overflow: auto;
}
.fixed{
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
background: rgba(0,0,0,0.5);
margin: auto;
}
.fixed div{
position: absolute;
right: 0;
top: 0;
left: 0;
bottom: 0;
width: 40%;
height: 30%;
background: #fff;
margin: auto;
overflow: auto;
}
</style>