首页 > 代码库 > 关于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的理解