通过上节课的学习, 知道相对定位并没有脱离文档流.
前面我们介绍过, 可以有三种方式脱离文档流: 浮动, 绝对定位, 固定定位
绝对定位的元素会脱离文档流, 与文档流无关. 文档流中的其他元素就像绝对定位的元素不存在一样.
一. 绝对定位的默认参考位置
给元素设置绝对定位只需要把position
属性的值改为absolute
即可.
position : absolute;
调整绝对定位的元素的位置也是 4 个属性: left, top, right, bottom
.
<style>
*{
padding : 0;
margin : 0;
}
.one{
width : 200px;
height : 100px;
background-color : pink;
position: absolute;
left: 150px;
top: 20px;
}
.two{
width : 300px;
height : 150px;
background-color : gray;
}
</style>
<div class="one"></div>
<div class="two"></div>
说明:
第一个
<div>
绝对定位之后, 会脱离文档流, 第二个<div>
自然就冲了上去.left
和top
是它的偏移量.
那么问题来了: left, top, bottom, right
是相对于哪个位置的偏移量呢?
默认情况下, 绝对定位是浏览器的可视区域的边缘.
<style>
*{
padding : 0;
margin : 0;
}
html,body{
width: 3000px;
height: 3000px;
background-color: linen;
}
.one{
width : 200px;
height : 100px;
background-color : pink;
position: absolute;
left: 100px;
top: 100px;
}
.two{
width : 300px;
height : 150px;
background-color : gray;
position: absolute;
right: 100px;
bottom: 100px;
}
</style>
<div class="one"></div>
<div class="two"></div>
说明:
我们把
html
和body
的宽高设置的很大, 从第二个<div>
我们就可以判断出来他们其实是参考的浏览器(也叫用户代理)的边缘.这个地方很多人都认为是参考
body
元素的边缘, 其实是不对的.如果是参考的
body
元素的边缘, 那么第二个元素在你滚动页面之前按道理是看不到的, 所以我才认为是参考的浏览器的边缘.
所以你才能理解下的行为:
<style>
*{
padding : 0;
margin : 0;
}
.one{
width : 400px;
height : 200px;
background-color : pink;
margin: 200px;
}
.two{
width : 100px;
height : 150px;
background-color : gray;
position: absolute;
left: 0;
top: 0;
}
</style>
<div class="one">
<div class="two"></div>
</div>
说明:
我们把父元素
<div>
通过margin
给换了位置, 然后你会发现子元素<div>
并没有受此影响.原因就是父元素对绝对定位的子元素已经没有控制力, 这个时候父元素还在文档流中, 而子元素已经脱离了文档流.
像这种老子控制不了儿子的情况比较恐怖, 得解决.
二. 给绝对定位的元素指定一个参考父辈元素
想解决老子控制不了儿子的情况, 我们需要先知道为啥老子控制不了儿子?
绝对定位的元素, 再计算怎么移的时候, 他需要参考"参考元素"的边缘.
怎么找的参考元素呢?
先看他爹有没有定位(相对定位, 绝对定位, 固定定位都可以), 如果有定位, 就参考他爹来计算了.
如果他爹没有定位, 就看他爷爷有没有定位, 如果有定位, 就参考他爷爷来计算了.
如果他爷爷也没有, 就继续向上找....
如果找到他的最上的祖宗(HTML
)仍然没有找到定位的元素, 那么对不起, 就参照浏览器边缘的吧(就是前面说的默认参考位置)
这里有个最佳实践, 就是: 如果某个元素想绝对定位, 那么就应该直接给他爹来个相对定位, 当然前提是他爹以前没有定位.
简称"子绝父相"
这样做的好处:
给一个元素添加相对定位, 不会对文档流中其他元素造成任何影响
绝对定位的儿子的定位值必须参考这个相对定位的爹, 爹控制儿子容易的多.且方便.
上面的例子中, 给父元素添加一个相对定位, 就变成下面的样子,正是吾之所愿亦.
说明:
left,top,...
这四个属性的值完全可以是负值, 这样子元素就可以脱离了父元素的区域.使用绝对定位非常适合实现遮罩效果(用一个元素盖住另外一个).
绝对定位在小范围的区域的布局使用广泛.
三. 绝对定位需要注意的地方
3.1 参考父元素的padding
问题
绝对定位是参考的"参考父元素"的边框的内边缘或者说是padding
的外边缘, 也就是说参考父元素的padding
对他毫无影响.
有一点需要注意:
如果给一个元素绝对定位之后, 没有添加任何的定位值(没有left ...
), 那么这个时候这些属性的默认值是auto
, 并不是 0
!!!
auto
到底怎么计算, 比较复杂, 不用管.
只需要记住他原来在哪, 现在还在哪就可以了.
3.1 绝对定位元素margin
对绝对定位的元素来说, 他的margin
仍然是有效的.
3.2 绝对定位在父元素盒子中的水平居中
在文档流中, 一个块级元素在父容器中居中使用margin : 0 auto;
很容易搞定, 但是决定定位的元素这个方法失效了.
我们需要用定位属性去完成
设置: left : 父容器宽度/2 - 自己的宽度/2
如果垂直方向居中, 那就换成top
3.4 不给定位元素设置宽和高
大部分情况我们都会给元素设置宽和高, 但是对绝对定位的元素, 设置宽和高则不一定必要. 然后, 让四个定位值把绝对定位的元素给"拉开".
比如: 我想让一个定位的元素居于右下角, 并且占据父容器的 1/4 面积.
<style>
.one{
width : 900px;
height : 500px;
background-color : lightgray;
position: relative;
margin: 100px;
}
.two{
background-color: pink;
position: absolute;
left: 50%;
top: 50%;
bottom: 0;
right: 0;
}
</style>
<div class="one">
<div class="two"></div>
</div>
3.5 z-index
如果多个固定定位的元素重叠在了一个块, 那么他们是怎么排序的呢?
默认情况下是按照HTML
中元素的属性排列, 谁在后面谁在就在上面.
我们可以通过z-index : 整数;
来调整他们的顺序. 值越大就越在上面.
默认值是 0