首页>前端教程>CSS教程

CSS第十七课:绝对定位(position:absolute)详解

从小我们学习物理,就知道一句话:“运动是相对的”。

或者有人生阅历丰富的人以一种长者的口吻告诉你,“没有什么是绝对的”。

那么,绝对定位是否可以说并不是真正的绝对呢。

同上,先来看看W3C官方文档怎么说。

设置为绝对定位的元素框从文档流完全删除,并相对于其包含块定位,包含块可能是文档中的另一个元素或者是初始包含块。元素原先在正常文档流中所占的空间会关闭,就好像该元素原来不存在一样。元素定位后生成一个块级框,而不论原来它在正常流中生成何种类型的框。

也可以先把W3C的官方文档看一遍,官方文档的好处是字字珠玑,坏处是不被嚼烂,好多人看不懂。(说的有点恶心(⊙o⊙)^_^)

CSS绝对定位

一、设置绝对定位

一旦设置为绝对定位,这小子就像脱了线的风筝,可以飞到九霄云外,不受任何人掌控。地面上的所有人都当此人得道升仙,根本看不到他了。

所以,我们可以说绝对定位是真正的无牵无挂,完全脱离文档流了,所以在文档流中完全看不见它曾经的影子。

1、只设置了绝对定位,但是还没有设置偏移量。这是很多人忽略的地方。

<div id="main" class="clearfix">
    <div class="box bg1">1</div>
    <div class="box bg2">2</div>
    <div class="box bg3">3</div>
</div>
div{
	box-sizing:border-box;}
.clearfix:after{
	content:"";
	display:block;
	clear:both;}
#main{
	width:340px;
	margin:20px auto;
	padding:5px;
	background-color:#ccc;}
.box{
	width:100px;
	height:100px;
	padding:10px;
	float:left;
	margin:5px;
	}
.ab{
	position:absolute;
	}
.pr{
	position:relative;}
.bg1{
	background-color:#1EBB1E;}
.bg2{
	background-color:#F35293;}
.bg3{
	background-color:#0CC;}

只为box设置了浮动的时候,排列的很漂亮。

浮动排列.jpg

然后为第一个box设置了绝对定位。

<div class="box bg1 ab">1</div>

绝对定位没有偏移值.jpg

发现第二个box不在了,其实很好理解,第一个box有了z-index的翅膀,飞到了天上,不再留恋凡间,曾经的房子也不要了,第二个box赶紧抢占。问题是,这个时候第一个box没有设置left/top/right/bottom等值,它根本就没有任何的偏移,还在老地方的上空漂浮着,所以,第二个box被压着了。

取消第一个box的绝对定位,让第二个div设置为绝对定位,发现它受到浮动的影响,跑到了左边去,压住了第一个box。

绝对定位测试.jpg

如果没有浮动呢?

绝对定位测试1.jpg

发现第二个box的确就在自己的位置上方,压住了抢占房子的第三个box,为什么能看见一点点第三个box,因为每个box都有5px的外边距,在普通文档流里,垂直的外边距会发生外边距合并,而绝对定位后,外边距就不会合并了。所以1、3box之间是5px,1、2之间是10px。具体可以了解“外边距合并”。

为什么没有设置偏移的绝对定位和相对定位一样,还是在老地方呆着呢,差别在于,相对定位的房子没有被占据,绝对定位的房子被占了。

这就是有没有脱离文档流的差别。

其实,这个时候的left和top不是为0,而是为默认值auto。

也就是说,如果想让一个对象变成绝对定位脱离文档流,如果位置不变的话,其实不需要设置偏移值,也不需要为父元素设置什么相对定位限制它。它本来就在原来的位置上。

2、设置偏移值

.pianyi1{
	top:0;
	left:0;}
<div id="main" class="clearfix">
    <div class="box bg1 ab pianyi1">1</div>
    <div class="box bg2">2</div>
    <div class="box bg3">3</div>
</div>

为第一个绝对定位对象设置了偏移值,left和top为0。

绝对定位设置偏移值.jpg

发现在没有任何父元素管控它的时候,它一飞就飞到了世界的边缘,直接和浏览器接轨。因为box有5px的margin值,所以并没有挨着浏览器。

W3C官方这样说明的:

绝对定位的元素的位置相对于最近的已定位祖先元素,如果元素没有已定位的祖先元素,那么它的位置相对于最初的包含块。

注释:根据用户代理的不同,最初的包含块可能是画布或 HTML 元素。

这里的box的父元素没有定位元素,所以它只能去找最初的包含块,最初的老祖先,这里就只能是HTML了,也就是浏览器。

3、实现浏览器居中显示

和fixed固定定位一样,可以采用负margin值实现,也可以采用margin:auto实现。

.pianyi1{
	top:50%;
	left:50%;
	margin-top:-50px;
	margin-left:-50px;
	}

或者:

.pianyi1{
	top:0;
	left:0;
	right:0;
	bottom:0;
	margin:auto;	
	}

都可以实现让绝对定位对象在浏览器中居中显示。

绝对定位在浏览器中居中显示.jpg

查看案例效果

和固定定位的差别是,固定定位是不随着滚动条滚动,而绝对定位只在当前屏居中,滚动条一滚动,绝对定位对象也得乖乖的跟着滚动。

二、祖先元素有定位

孙猴子再厉害,也跳不出如来佛的手掌心,所以,绝对定位再厉害,也有人能控制它。

官方文档说的是“相对于最近的已定位祖先元素”,也就是说只要是定位元素,还是父辈祖先级别的,不是兄弟姐妹同辈的,也不是儿子孙子后辈的,而且要离自己最近的,都可以限制绝对定位吗?

1、祖先元素是绝对定位

<div id="main" class="clearfix ab">
    <div class="box bg1 ab pianyi1">1</div>
    <div class="box bg2 ">2</div>
    <div class="box bg3 ">3</div>
</div>

让main这个父辈元素做了绝对定位,有了很多新发现。

父辈为绝对定位.jpg

发现main这个div失去了相对于浏览器居中对齐的能力。

也就是margin:20px auto这条代码的auto的能力消失了,上下20px的外边距还在。第一个box现在是相对于main这个父元素居中了,而不是相对于浏览器居中了。看来父元素的确限制住了绝对定位的子元素。当然,第一个box也把第三个box压住了。

再把main的固定宽度去掉,发现此时这个div不再具备block块状对象独占整个通栏的能力,它的宽度只有内部元素的宽度了。第一个box依然相对于父元素居中显示。

用的谷歌浏览器的审查元素命令,可以看到如图所示:

绝对定位变成了inlin-block对象.jpg

通过这个现象可以看出,一个元素设置了绝对定位后,改变了它的形态。

W3C官方说法是“元素绝对定位后生成一个块级框,而不论原来它在正常流中生成何种类型的框。”

我觉得这里的“块级框”让我有误解,准确的说应该是“行内-块级框”,也就是变成了inline-block对象。

可见用绝对定位来限制绝对定位很危险呀,因为元素的框类型发生改变,这个布局一下子乱套,不用不用。

注意:如果父元素是绝对定位,子元素也是绝对定位,则子元素相对于父元素的左上角对齐,定位也是相对于左上角,不是相对于浏览器。如果是祖先元素有绝对定位,根据就近原则定位。也就是说,绝对定位也能限制绝对定位。

2、祖先元素是固定定位

测试效果和祖先元素是绝对定位一模一样,但是滚动条滚动,你们都不动,是什么意思,我的网页那么长,这还怎么混,不用不用了。可见,父元素是固定定位,子元素不管啥定位,统统继承固定不动的能力。而且,固定定位也是改变了元素的框类型,也是变成了inline-block类型的。

注意:三个定位中,只有相对定位还保持了独占一行的块状对象能力,绝对和固定定位都改变了框类型,宽度和内容保持一致了。

3、非我莫属的相对定位

为什么相对定位明明可以借着z-index的翅膀一飞冲天,却依然在凡间留下自己的原身,我想它的责任就在于控制这个不可一世的绝对定位吧。

<div id="main" class="clearfix pr">
    <div class="box bg1 ab pianyi1">1</div>
    <div class="box bg2 ">2</div>
    <div class="box bg3 ">3</div>
</div>

让main这个div做了相对定位,发现一切都很好,布局一点没变,但是第二个box的确被控制住了,在main这个div中居中显示,压住了第三个box。

相对定位的绝对定位.jpg

再把main这个div的固定宽度取消,发现它依然具备block块状独占整个一栏的能力。

相对定位不改变自身框类型.jpg

终于理解了相对定位的厉害之处。移动和爬楼梯都是次要的能力,控制住绝对定位才是最厉害的,而且,不管定位前后,它都不变身。

所以,我们才理解了W3C官方文档说的,“设置为相对定位的元素框会偏移某个距离。元素仍然保持其未定位前的形状,它原本所占的空间仍保留。”

三、相对定位能控制固定定位吗?

既然相对定位这么牛,那么固定定位呢?能改变固定定位的参考物是浏览器的事实吗?

在main里面的最后面添加一个返回顶部的div测试一下。

<div id="main" class="clearfix">
    <div class="box bg1">1</div>
    <div class="box bg2">2</div>
    <div class="box bg3">3</div>
    <div id="back"><a href="#">返回顶部</a></div>
</div>

当box不浮动,back这个div设置为固定定位,但是不设置任何偏移值的时候,它的表现跟绝对定位一样。呆在自己的原地,漂浮在空中。

#back{
	position:fixed;
	width:26px;
	height:100px;
	padding:20px 5px;
	background-color:#ddd;}

固定定位.jpg

如果box浮动,它也会受到浮动的影响,但是它因为是天上的,所以会压住下面的box。

固定定位受浮动影响.jpg

但是一旦设置了偏移值呢?

#back{
	position:fixed;
	right:0px;/*距右边为0*/
	bottom:50px;/*距底部50px*/
	width:26px;
	height:100px;
	padding:20px 5px;
	background-color:#ddd;}

固定定位参考物是浏览器.jpg

乖乖投靠浏览器了。

那把main这个父元素设置为相对定位呢?添加了pr这个相对定位的class。

<div id="main" class="clearfix pr">
    <div class="box bg1">1</div>
    <div class="box bg2">2</div>
    <div class="box bg3">3</div>
    <div id="back"><a href="#">返回顶部</a></div>
</div>

发现,一丝毫的反应都没有!

也就是说,固定定位是个特别顽固的家伙,不管相对定位如何招揽,它都要跟着浏览器混。

那难道没有办法让它紧贴着main这个div吗?如果宽屏够宽,这个“返回到顶部”岂不是离我很远?

还是有办法的。

网易的返回到顶部就是用的这个方法,可以自行去查看。

先让固定定位元素相对于浏览器水平居中,然后再设置它的margin-left的值为main这个大容器的宽度的一半就可以了。

#back{
	position:fixed;
	left:50%;/*水平方向居中显示*/
	bottom:50px;
	margin-left:170px;/*左外边距为main的宽度340px的一半,让固定定位对象往右移动170px。*/
	width:26px;
	height:100px;
	padding:20px 5px;
	background-color:#ddd;}

查看效果

如果你有耐心看完整个文章,并且还弄懂了,那我也深感欣慰了。

不留言那就点个赞呗!

点赞


14
保存到:

相关文章

Top