在css中,绝对定位是使元素的位置与文档流无关的定位方式。设置为绝对定位的元素框从文档流完全删除,并相对于其包含块定位;默认情况下,绝对定位的位置是相对于浏览器而言,配合top、right、bottom、left进行定位。
本教程操作环境:windows7系统、CSS3&&HTML5版、Dell G3电脑。
在css中,绝对定位是使元素的位置与文档流无关的定位方式。
设置为绝对定位的元素框从文档流完全删除,并相对于其包含块定位,包含块可能是文档中的另一个元素或者是初始包含块。默认情况下,绝对定位的位置是相对于浏览器而言,配合top、right、bottom、left进行定位。
元素原先在正常文档流中所占的空间会关闭,就好像该元素原来不存在一样。元素定位后生成一个块级框,而不论原来它在正常流中生成何种类型的框。
下面我们来详细了解一下绝对定位(absolute)。其实绝对定位absolute和浮动float有部分相似性;如果能理解浮动float,对理解绝对定位absolute会大有帮助。
先说absolute和float的相似处:包裹性 和 高度欺骗
包裹性
所谓一图胜千言(唯一的区别是:下图的p增加了absolute)
<p style="border:4px solid blue;"> <img src="img/25/1.jpg" /> </p> <p style="border:4px solid red; position: absolute;"> <img src="img/25/2.jpg" /> </p>
一旦给元素加上absolute或float就相当于给元素加上了display:block;。什么意思呢?比如内联元素span默认宽度是自适应的,你给其加上width是不起作用的。要想width定宽,你需要将span设成display:block。但如果你给span加上absolute或float,那span的display属性自动就变成block,就可以指定width了。因此如果看到CSS里absolute/float和display:block同时出现,那display:block就是多余的CSS代码。
高度欺骗
上例中给图片外层的p加上absolute,因此高度欺骗未能很好的体现出来,将absolute移到内部图片上,效果就出来了:
<p style="border:4px solid blue;"> <img src="img/25/1.jpg" /> </p> <p style="border:4px solid red;"> <img style="position: absolute;" src="img/25/2.jpg" /> </p>
如果你看过CSS浮动float详解会发现效果是一样的。但其背后的原理其实是有区别的,并不完全相同。加点文字就看出来了:
<p style="border:4px solid blue;"> <img src="img/25/1.jpg" /> </p> <p style="border:4px solid red;"> <img style="position: absolute;" src="img/25/2.jpg" /> 我是一个绝对定位的absolute元素 </p>
从图中明显看出文字被图片遮盖了,这点和float不同。float是欺骗父元素,让其父元素误以为其高度塌陷了,但float元素本身仍处于文档流中,文字会环绕着float元素,不会被遮蔽。
但absolute其实已经不能算是欺骗父元素了,而是出现了层级关系。如果处于正常的文档流中的父元素算是凡人的话,那absolute已经得道成仙,用现在的话说已经不在一个次元上。从父元素的视点看,设成absolute的图片已经完全消失不见了,因此从最左边开始显示文字。而absolute的层级高,所以图片遮盖了文字。
记得我刚开始接触CSS尚处于战斗力为5的渣渣时,知道了absolute可以出现层级的概念,就误以为已经彻底懂了,现在想想真是图样图森破(当然这不是件坏事,每当你觉得以前的自己渣像块豆腐渣时,就代表你进步了。反过来总说想当年自己如何如何,那说明你还在吃老本)。
有了上面的基础后,你还需要了解absolute以下特性
- 如何确定定位点
- 和relative相爱相杀
- 和z-index的关系
- 减少重绘和回流的开销
如何确定定位点
一旦absolute分层后,第一个出现的问题就是让浏览器在何处显示该元素。普通文档流里的元素,浏览器可以根据其父子兄弟元素的大小和位置,计算出该元素的位置。但分层后怎么办?基本思路如下:
第一种情况:用户只给元素指定了absolute,未指定left/top/right/bottom。此时absolute元素的左上角定位点位置就是该元素正常文档流里的位置。如上面图例中,图片熊猫是父元素的第一个孩子,因此左上角定位点就是父元素的content的左上角。
如果将图片熊猫和下面的文字顺序改一下,让其成为父元素的第二个孩子,一图胜千言:
<p style="border:4px solid red;"> 我是一个绝对定位的absolute元素 <img style="position: absolute;" src="img/25/2.jpg" /> </p>
结论重复一遍:未指定left/top/right/bottom的absolute元素,其在所处层级中的定位点就是正常文档流中该元素的定位点。
第二种情况:用户给absolute元素指定了left/right,top/bottom
先简单点,让absolute元素没有position:static以外的父元素。此时absolute所处的层是铺满全屏的,即铺满body。会根据用户指定位置的在body上进行定位。
只指定left时,元素的左上角定位点的left值会变成用户指定值。但top值仍旧是该元素在正常文档流中的top值:
<p style="border:4px solid red;"> 我是一个绝对定位的absolute元素 <img style="position: absolute;left:50px;" src="img/25/2.jpg" /> </p>
只指定right时,元素的右上角定位点的right值会变成用户指定值。但top值仍旧是该元素在正常文档流中的top值:
<p style="border:4px solid red;"> 我是一个绝对定位的absolute元素 <img style="position: absolute;right:50px;" src="img/25/2.jpg" /> </p>
只指定top时,元素的左上角定位点的top值会变成用户指定值。但left值仍旧是该元素在正常文档流中的left值:
<p style="border:4px solid red;"> 我是一个绝对定位的absolute元素 <img style="position: absolute;top:50px;" src="img/25/2.jpg" /> </p>
只指定bottom时,元素的左下角定位点的bottom值会变成用户指定值。但left值仍旧是该元素在正常文档流中的left值:
<p style="border:4px solid red;"> 我是一个绝对定位的absolute元素 <img style="position: absolute;bottom:50px;" src="img/25/2.jpg" /> </p>
通过对left/top/right/bottom的组合设置,由于没有position:static以外的父元素,此时absolute元素可以去任意它想去的地方,天空才是它的极限。
和relative相爱相杀
通常我们对relative的认识是(好吧,我承认,这是我战5渣渣时的认识。如果你是弗利萨,可以鄙视这句话):relative主要用于限制absolute
上面已经说了,如果absolute元素没有position:static以外的父元素,那将相对body定位,天空才是它的极限。而一旦父元素被设为relative,那absolute子元素将相对于其父元素定位,就好像一只脚上被绑了绳子的鸟。
比如你要实现下图iOS里APP右上角的红色圈圈
通常的做法是将APP图片所处的p设成relative,然后红色圈圈设成absolute,再设top/right即可。这样无论用户怎么改变APP图片的位置,红色圈圈永远固定在右上角,例如:
.tipIcon { background-color: #f00; color: #fff; border-radius:50%; text-align: center; position: absolute; width: 20px; height: 20px; right:-10px; //负值为自身体积的一半 top:-10px; } <p style="display: inline-block;position:relative;"> <img src="img/25/2.jpg" /> <span class="tipIcon">6</span> </p>
这样做效果是OK的,兼容性也OK。但CSS的世界里要实现一个效果可以有很多种方式,具体选用哪个方案是见仁见智的。我比较看重的标准:一个是简洁,另一个是尽量让每个属性干其本职工作。
用这两个标准看待上述实现方法,应该是有改进的空间的。首先外层p多了relative未能简洁到极致。其次relative的本职工作是让元素在相对其正常文档流位置进行偏移,但父层p并不需要任何位置偏移,之所以设成relative唯一的目的是限制absolute子元素的定位点。因此在我看来这并没有让relative干其本职工作。好比小姐的本职工作是服务业,顺便陪客户聊聊天,但纯聊天聊完一个钟,恐怕会被投诉。
(学习视频分享:css视频教程)