首页 > 代码库 > 关于position定位及z-index的理解
关于position定位及z-index的理解
position属性规定元素的定位类型,顾名思义,它是用来描述元素使用什么方式,如何来定义位置的属性。position的值有 5个:absolute(绝对定位),fixed(固定定位),relative(相对定位),static(默认值),inherit(继承)。我们所 要理解的只是前4种,对于inherit,任何的版本的 Internet Explorer (包括 IE8)都不支持,而且基本使用很少。
在讲定位前首先我们需要理解文档流的概念。页面内的所有标签元素以及显示的内容,默认都是在文档流中,也即是说,所有的内容都在一层上,如下图:
但是在某种情况下,内容是可以脱离文档流存在的,这时内容就浮在了文档之上,成为两层甚至更多层,如下图:
当脱离文档流内容较多,并且相互重叠的时候,就有可能发生本想完全显示的内容被其他内容遮挡的结果,这时我们就需要人为指定哪个层在上面,哪个在下面,z-index属性就是干这个用的。
预热结束接下来进入正题。
导致内容脱离文档流的行为有两种,一种是浮动(float),另一种是定位(absolute,fixed)。这篇主要讲定位,因此只针对position讲解。
首先理解下这4种定位类型的区别。
static类型(默认) 我们可以理解为无定位,在文档流内。
relative类型(相对定位) 所谓的相对定位是指相对自己定位,这种定位不脱离文档流。无论如何移动,只是相对于自己原始的位置,是看起来在那,而实际上还在文档流内。可以参考下图:
absolute类型(绝对定位) 使 用这种定位的元素,其位置是跟据其父元素或祖先元素定位的。具体为拥有相对或绝对定位或固定定位属性的祖先元素,如果祖先元素中无一个拥有定位属性,则参 照整个浏览器可视区域的整个文档定位(并非body而是html,下面会进行验证)。与相对定位不同,使用绝对定位的元素是脱离文档流的。参考下图:
fixed类型(固定定位) 这种定位是将元素固定在屏幕可视区域的某个位置,不随滚动条拖拽而改变位置。
开始实例讲解。
html:
<div id="box1">
<div id="box2"><p>我是子元素</p></div>
<p>我是父元素</p>
</div>
css:
#box1 {
width: 200px;
height: 100px;
margin: 50px 0 0 100px;
background: #cd1f8d;
}
#box1 p {height: 400px;}
#box2 {
width: 100px;
height: 50px;
background: #1faacd;
top: 10px;
left:10px;
}
父元素static(默认)
1. 子元素static(默认)
#box1 { position: static; }
#box2 { position: static; }
当元素没有设置position属性时,其默认值是static,这时元素不脱离文档流,在文档流中占有一定空间。拖拽滚动条时,子元素的位置随父元素的滚动条位置的变化而变化。
2. 子元素relative(相对定位)
#box1 { position: static; }
#box2 { position: relative; }
当父元素为static,子元素为relative时,其视觉效果是相对于自身原始位置所做偏移,但是其位置并并没有改变。
3.子元素absolute(绝对定位)
#box1 { position: static; }
#box2 { position: absolute; }
当父元素为static,子元素为absolute时,子元素就已经脱离了父元素的文档流,相当于浮起来一层,不再占据原来的位置,子元素后面的元素会向上移动占据这块位置。拖拽滚动条,子元素不会跟随变化。
4.子元素fixed(固定定位)
#box1 { position: static; }
#box2 { position: fixed; }
当父元素为static,子元素为fixed时,子元素同样脱离文档流,不随滚动条变化而变化。
父元素relative(相对定位)
1. 子元素static(默认)
#box1 { position: relative; }
#box2 { position: static; }
当父元素为relative,子元素为static时,效果同父元素static(默认)中的1。
2. 子元素relative(相对定位)
#box1 { position: relative; }
#box2 { position: relative; }
当父元素为relative,子元素为relative时,效果同父元素static(默认)中的2。
3.子元素absolute(绝对定位)
#box1 { position: relative; }
#box2 { position: absolute; }
当父元素为relative,子元素为absolute时,可以看到,子元素脱离文档流,不占据原来的位置,浮在了其他元素上面。但是其位置却与父元素static(默认)中的3不同,而是相对于父元素的位置而定位,具体参考点就是父元素的左上角0 0坐标那个点。子元素的位置随滚动条变化而变化。
4.子元素fixed(固定定位)
#box1 { position: relative; }
#box2 { position: fixed; }
当父元素为relative,子元素为fixed时,效果同父元素static(默认)中的4。
父元素absolute(绝对定位)
1. 子元素static(默认)
#box1 { position: absolute; }
#box2 { position: static; }
当父元素为absolute,子元素为static时,效果同父元素static(默认)中的1。
2. 子元素relative(相对定位)
#box1 { position: absolute; }
#box2 { position: relative; }
当父元素为absolute,子元素为relative时,效果同父元素static(默认)中的2。
3.子元素absolute(绝对定位)
#box1 { position: absolute; }
#box2 { position: absolute; }
当父元素为absolute,子元素为absolute时,效果同父元素relative(相对定位)中的3。
4.子元素fixed(固定定位)
#box1 { position: absolute; }
#box2 { position: fixed; }
当父元素为absolute,子元素为fixed时,效果同父元素static(默认)中的4。
父元素fixed(固定定位)
1. 子元素static(默认)
#box1 { position: fixed; }
#box2 { position: static; }
当父元素为fixed,子元素为static时,效果同父元素static(默认)中的1。
2. 子元素relative(相对定位)
#box1 { position: fixed; }
#box2 { position: relative; }
当父元素为fixed,子元素为relative时,效果同父元素static(默认)中的2。
3.子元素absolute(绝对定位)
#box1 { position: fixed; }
#box2 { position: absolute; }
当父元素为fixed,子元素为absolute时,效果同父元素relative(相对定位)中的3。
4.子元素fixed(固定定位)
#box1 { position: fixed; }
#box2 { position: fixed; }
当父元素为fixed,子元素为fixed时,效果同父元素static(默认)中的4。
结论:
1. 无论父元素使用何种定位,子元素使用static,显示效果相同。
2. 无论父元素使用何种定位,子元素使用relative,显示效果相同。
3. 无论父元素使用何种定位,子元素使用fixed,显示效果相同,且定位参照浏览器可视区域(并非html也非body)
4. 子元素使用absolute,父元素为relative或absolute或fixed时,显示效果相同,子元素参考父元素的00坐标进行定位。如果父元素为static或者未设置时,子元素将以离它最近的拥有relative或absolute或fixed属性的祖先元素为参考进行定位。如果其祖先元素均没有找到,则参照显示器可视区域的整个页面文档进行定位(再次强调是html而非body)。
验证结论3
使用fixed定位的元素,其定位参照浏览器可视区域。
示例
css:
html {
height: 150px;
overflow: hidden;
position: relative;
}
body {
overflow: auto;
width: 350px;
height: 100%;
position: relative;
}
#demo {
width: 50px;
height: 50px;
background: #cd1f8d;
position: fixed;
top: 50px;
left: 50px;
}
html:
<div id="demo"></div>
<div style="height: 3000px;"></div>
效果:
由此可见,当一个元素使用了fixed定位后,无论其祖先元素中定位属性如何设置,都不会影响到这个元素,并且应用fixed的元素定位不参照任何标签,包括html和body,其位置参照浏览器可见区域进行定位。
验证结论4
使用absolute定位的元素,如果其祖先元素中均未设置relative或absolute或fixed属性,则其定位参照整个文档,即html标签,若祖先元素中有设置relative或absolute或fixed属性的元素,则参照此元素,如果有多个,则参照离它最近的那个,默认body是没有定位属性的,即static。
示例1
css:
html {
height: 150px;
overflow: hidden;
}
body {
overflow: auto;
width: 350px;
height: 100%;
}
#demo {
width: 50px;
height: 50px;
background: #cd1f8d;
position: absolute;
top: 50px;
left: 50px;
}
html:
<div id="demo"></div>
<div style="height: 3000px;"></div>
示例1效果:
示例2
css:
html {
height: 150px;
overflow: hidden;
}
body {
overflow: auto;
width: 350px;
height: 100%;
position: relative;
}
#demo {
width: 50px;
height: 50px;
background: #cd1f8d;
position: absolute;
top: 50px;
left: 50px;
}
html:
<div id="demo"></div>
<div style="height: 3000px;"></div>
示例2效果:
关于绝对定位的实用技巧:
元素自动居中显示
使用absolute模拟fixed定位,兼容ie6,及ie7 8 9和火狐谷歌等浏览器
更复杂的定位——使用z-index
一个元素,如果设置了relative或absolute或fixed,那么,top,right,bottom,left值就会起效,通过调整这些值,我们就可以让两个或者更多元素相互间叠在一起,甚至完全重叠。
示例
css:
#box1 {
width: 200px;
height: 100px;
position: relative;
background: #3b8ede;
display: inline-block;
top: 20px;
left: 50px;
}
#box2 {
width: 200px;
height: 100px;
position: relative;
background: #81bc00;
display: inline-block;
top: 50px;
left: 30px;
}
html:
<div id="box1"></div>
<div id="box2"></div>
示例效果:
默认均未设置z-index的情况下,无论box1和box2设置relative,absolute还是fixed,效果都是box2在box1上面,如果我们把html中的box1和box2的位置上下互换的话,box1会在box2上面,因此,进行定位的元素在html中越靠后,层级越高。
当我们把box1和box2的z-index值都设为0时,效果不变,依然是box2在box1之上,由此,我们得知,z-index设置层级相同的元素,在html中位置越靠后的元素,层级越高。当我们把box1的z-index值设为0,box2不设置z-index值时,效果依然如此,根据刚得到的结论得知,元素默认z-index值为0(css文档中已经说明,这个是用实例验证)。如果我们让box1的z-index值大于box2的z-index值(z-index可取负数),那么box1就会跑到box2上面。
示例效果:
那么是不是z-index值最高的元素就一定在最上面,z-index值最的元素就一定在最下面?答案是否定的,父元素的z-index值比子元素的z-index值高,即使子元素的z-index值取负值,子元素依然会在父元素之上。
示例
css:
#box1 {
width: 200px;
height: 200px;
background: #3b8ede;
position: absolute;
display: inline-block;
left: 50px;
top: 30px;
z-index: 1;
}
#box1 p {
width: 100px;
height: 100px;
background: #81bc00;
left: 100px;
position: absolute;
z-index: 4;
}
#box2 {
width: 200px;
height: 200px;
background: #f4436d;
position: absolute;
display: inline-block;
left: 200px;
top: 80px;
z-index: 1;
}
#box2 p {
width: 100px;
height: 100px;
background: #ffc845;
position: absolute;
z-index: -1;
}
html:
<div id="box1">
<p></p>
</div>
<div id="box2">
<p></p>
</div>
示例效果:
如果按照z-index值越高,层级越高,z-index值越低,层级越低的想法来看,绿色(#box1 p)z-index值最高应该在最上面,蓝色(#box1)与红色(#box2)相同,但在html中靠后,所以红色(#box2)在蓝色(#box1)上面,黄色(#box2 p)在最下面,但是事实显然并非如此。
那么我们该如何判断哪个元素层级高哪个元素层级低呢?
我们可以把进行定位的元素想象成一个抽屉,其子元素无论定位与否都在它内部,只不过是在抽屉内部的上面中间或下面。
如此一来,我们就可以先比较蓝色(#box1)与红色(#box2),两者z-index值相同,红色(#box2)在html中靠后,所以红色(#box2)在蓝色(#box1)上面,根据子元素必然在父元素上面的原理,绿色(#box1 p)在蓝色(#box1)上面,黄色(#box2 p)在红色(#box2)上面,根据上面的抽屉原理,一个抽屉内的东西,就算放在最上面,也不可能会比它上面那个抽屉的最下面的东西还高。因此,红色(#box2)在绿色(#box1 p)上面(即使它的z-index值最高),黄色(#box2 p)在最上面(即使它的z-index值最低,并且还是负值)。
篇幅已经够长了,本来想针对relative,absolute,fixed各种组合做几个示例,但是效果差不多,也就没做,只要弄懂上面的原理,基本就足够了,再复杂的层级关系,也可以一步步分解成最简单的,套用上面的原理即可理清。
如果有疏漏或者不正确的地方,希望能跟我说下。呵呵~~
关于position定位及z-index的理解