绝对定位将一个元素框从文档流完全删除,并相对于其包含块定位。包含块的定义已经在之前的文章里解释过了。文档中的其他元素不受绝对定位元素的影响,就好像它不存在一样。元素定位后生成一个块级框,而不论原来它在正常流中生成何种类型的框。
1. position : absolute
绝对定位相对于包含块,根据left、right、top、bottom的值定位。前面的文章已经介绍过了包含块的概念,也列出了几个例子。这里主要讲一下绝对定位元素高度和长度的计算以及left等属性缺省时元素的呈现。对于绝对定位元素,总是存在以下公式:
'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width'+ 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block
- 如果left、right、width的值都为auto,那么设置margin-left、margin-right为0如果它们的值为auto,如果父元素的direction为ltr(rtl),那么left(right)=父元素的left (right)padding,剩下的两个值由上述公式解出。例如,
<html>
<head>
<style type="text/css">
#container {border:solid 1px;height:50px;width:200px;margin:50px;position:relative;padding:5px;}
#abs {background:red;position:absolute;margin:0 auto;}
</style>
</head>
<body>
<div id='container'>
<div id='abs'>absolute</div>
</div>
</body>
</html>
margin-left、margin-right的值为0。元素相对与包含块的border edge产生了偏移,偏移的值是父元素的left-padding和top-padding。注意和设置left、top为0的区别
#abs {background:red;position:absolute;margin:0 auto;left:0;top:0;}
- 如果left、right和width都不为auto,那么当margin-left、margin-right为auto且公式内余下值的和小于包含块的宽时,margin-left=margin-right,值由公式算出。
#abs {background:red;position:absolute;margin:0 auto;left:50px;right:50px;width:100px;}
- 如果除左右边距外余下值的和已经大于了包含块的宽度,那么设margin-left(right)为0如果direction为ltr(ltr),剩下的一个由公式计算得出(为负值)。
#abs {background:red;position:absolute;margin:auto;left:200px;right:50px;width:100px;}
- 当left、right、width不全为auto,设置margin-left、margin-right为0如果它们的值为auto。
(1)当其中两个值不为auto,余下的一个由公式计算得出。
#abs {background:red;position:absolute;margin:0 10px 0 10px;right:20px;width:100px;}
上图中left=父元素的width-right-width=80px
(2)当left、right为auto,width不为auto时,如果父元素的direction为ltr(rtl),那么left(right)=父元素的left (right)padding,由公式解出right(left)的值。
#container {border:solid 1px;height:50px;width:200px;margin:50px;position:relative;padding:5px;}
#abs {background:red;position:absolute;width:100px;}
(3)当left(right)、width为auto,right(left)不为auto时,计算出width的自适应的宽度。然后算出right(left)的值。
width自适应的值计算如下:
preferred width = 块里内容除了明确出现的换行符外不换行,所需的宽度
preferred minimum width = 块里内容在可以换行的地方(比如空格)都换行,所需的宽度
available width = 假设为auto的left(right)值为0时,width计算出的宽度
自适应的宽度=min(max(preferred minimum width, availablewidth), preferred width)
下面就展示了元素内容不同时不同的自适应效果。
#abs {background:red;position:absolute;left:20px;}
上面讨论的都是宽度相关的计算,高度相关计算是类似的,除了元素的高度取决与元素本身,并没有计算公式。另外当top、bottom的值都为auto时,总是设置top=父元素的top padding,这从第一、三张图片都可以看出。
2. position:fixed
fixed定位的元素其实就是absolute定位的一种特殊情况,只不过它的包含块是可视窗口,视觉上看就是一个元素固定在了当前窗口的某一个位置,并不会随着文档的滚动而移动。
<html>
<head>
<style type="text/css">
p { width:20px; line-height:60px;}
img#left1 { height:100px; width:100px; position:fixed; top:100px; left:100px;}
</style>
</head>
<body>
<img id='left1' src="/i/eg_cute.gif" />
<p>
line1 line2 line3 line4 line5 line6 line7 line8 line9 line10
</p>
</body>
</html>
可以看到,下拉滚动条并不会影响图片对于当前窗口的位置。