position属性真是萌新杀手T_T,参照谁定位?谁又脱离了文档流?理解了好长时间才摸清了一些门路。现在就对CSS position属性及HTML中有关定位的知识做一次梳理和总结。
一、从position属性的四个值说起
1.static默认定位(或者说没有定位)
position: static;
static是position属性的默认值,代表“没有定位”,即元素出现在正常的文档流中。如果规定了某元素的position为static,那么该元素下的top, bottom, left, right,z-index样式声明都会被忽略(人家都说了不喜欢你了,你还送这些奇奇怪怪的东西给人家干嘛?)。
2.absolute绝对定位
position: absolute;
绝对定位怎么定位?绝对定位有什么特性?
- 绝对定位的元素会相对于static定位以外的第一个父元素进行定位
- 绝对定位的元素会脱离文档流
绝对定位到底是怎么确定位置的呢?拿下面的代码举例:
<html>
<head>
<style>
body {
margin: 100px;
height: 200px;
color: white;
border: 1px solid #ccc;
}
p {
background: red;
}
div#div1 {
width: 300px;
}
p#p1 {
position: absolute;
top: 10px;
left: 10px;
}
div#div2 {
width: 300px;
position: relative;
}
p#p2 {
position: absolute;
top: 10px;
left: 10px;
}
</style>
</head>
<body>
<div id="div1">
<p id="p1">绝对定位P1</p>
</div>
<div id="div2">
<p id="p2">绝对定位P2</p>
</div>
</body>
</html>
执行结果:
分析:按照刚刚的思维——绝对定位的元素会相对于static定位以外的第一个父元素进行定位。
对于#p1,它的第一个父元素是#div1,而#div1并没有指定position样式,也就是说#div1的position为默认值static,不满足要求,所以继续往上找,找到第二个父元素body,但body也没有被指定position样式,所以依然不是满足要求的参照元素,继续往上找。找到第三个父元素html,虽然html也没有被指定position,但它已经是这个文档的祖宗了,所以#p1就以html为参照元素进行定位。
对于#p2,它的第一个父元素是#div2,#div2指定了position: relative,即“static定位以外的父元素”,所以#p2就以#div2为参照元素进行定位。
事实上,如果将上例#div2的position更改为absolute或fixed,#p1依然会参照#div2进行定位,因为#div2的position不为static.
P.S. 为什么明明top和left都是10px,两个p却看起来离上面更远一些?p元素默认margin的关系。
绝对定位的元素会脱离文档流,拿下面的代码举例:
<style>
body {
margin: 100px;
color: white;
font-size: 12px;
border: 1px solid #ccc;
}
section {
position: relative;
}
div {
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
opacity: 0.7;
}
div.absolute {
background: red;
position: absolute;
top: 20px;
left: 20px;
}
div.normal {
background: blue;
}
</style>
<section>
<div class="absolute">绝对定位DIV</div>
<div class="normal">默认定位DIV</div>
</section>
执行结果:
图中明显能够看出div.absolute脱离文档流的事实。div是块元素,应该占据整行,而上图中div.normal占据了原先div.absolute在文档流中的位置。另外,body的高度也仅被div.normal撑开,压根没有考虑div.absolute的感受。所以,绝对定位的元素会脱离文档流。
3.relative相对定位
position: relative;
相对定位怎么定位?相对定位有什么特性?
- 相对定位的元素相对于它本身正常的位置进行定位(也就是说,自己参考原始的自己进行定位)
- 相对定位的元素不会脱离文档流
拿下面的代码举例:
<style>
body {
margin: 100px;
color: white;
font-size: 12px;
border: 1px solid #ccc;
}
div {
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
opacity: 0.7;
}
div.relative {
background: orange;
position: relative;
top: 10px;
left: 10px;
}
div.normal {
background: blue;
}
</style>
<section>
<div class="relative">相对定位DIV</div>
<div class="normal">默认定位DIV</div>
</section>
执行结果:
可以清楚的看到div.relative是根据其原始位置(body的0,0)进行top、left偏移。另外,div.normal并没有顶在div.relative的位置上,body撑开的高度是两个div的高度和,所以相对定位的元素不会脱离文档流。
4.fixed固定定位
position: fixed;
固定定位怎么定位?固定定位有什么特性?
- 固定定位的元素总是相对于浏览器窗口进行定位
- 固定定位的元素会脱离文档流
非常简单,不举例了。
二、与定位相关的几个样式
与定位相关的样式有top、left、bottom、right和z-index,这些属性都能够帮助确定元素位置。
- top:元素顶部和参考元素顶部的距离,可以为负数
- left:元素左侧和参考元素左侧的距离, 可以为负数
- bottom:元素下端和参考元素下端的距离, 可以为负数
- z-index:元素的Z轴高度(z-index高的元素会遮挡住z-index低的元素)
三、绝对定位 和 固定定位 的另一个特点
不论元素本身是块元素还是行元素,一旦使用绝对定位或固定定位,那么它就会变成块元素。而使用相对定位则不会改变这一点。举个例子:
<style>
body {
margin: 100px;
height: 200px;
color: white;
border: 1px solid #ccc;
position: relative;
}
span {
width:100px;
height: 100px;
font-size: 12px;
text-align: center;
opacity: 0.7;
}
span.absolute {
background: red;
line-height: 100px;
position: absolute;
top: 0;
right: 0;
}
span.fixed {
background: green;
line-height: 100px;
position: fixed;
top: 0;
left: 0;
}
span.relative {
background: orange;
position: relative;
top: 30px;
left: 30px;
}
span.normal {
background: blue;
}
</style>
<body>
<span class="absolute">绝对定位SPAN</span>
<span class="fixed">固定定位SPAN</span>
<span class="relative">相对定位SPAN</span>
<span class="normal">默认定位SPAN</span>
</body>
执行结果:
老牌行元素span竟然在没有display的情况下竟然可以指定width和height了,这说明在绝对定位和固定定位情况下,元素会变成块元素。
四、总结
- position可取四个值:static(默认定位) | absolute(绝对定位) | relative(相对定位) | fixed(固定定位);
- 绝对定位的参考元素为第一个position不为static的父元素,若没有这样的父元素则参考元素为html元素;
- 相对定位的参考元素为正常位置的自己;
- 固定定位的参考元素为浏览器窗口;
- 绝对定位和固定定位的元素脱离文档流,默认定位和相对定位的元素不脱离文档流;
- 一旦元素使用绝对定位和固定定位,它将会变为块元素。