Higanbana

详解绝对定位和相对定位

上一篇博文中对元素的居中方式进行了总结,其中很多方法中都用到了相对定位和绝对定位,关于这两种定位方式确实是CSS中的一大难点,如果不能深入了解这两种定位方式,进行页面排版时就容易出现混乱,所以今天我对position的所有属性取值进行一个总结,重点剖析绝对定位和相对定位之间的联系和区别。

position的不同取值

不管是哪种定位,都必须有一个参照物,理清参照物我们就对这些定位方式了解了一半。

  1. static,默认值。位置设置为static的元素,它始终会处于页面流给予的位置(static 元素会忽略任何 top、bottom、left、right和z-index 声明)。
  2. inherit,规定应该从父元素继承 position 属性的值。但是任何的版本的 Internet Explorer (包括 IE8)都不支持属性值 “inherit”。
  3. fixed,生成绝对定位的元素,可定位于相对于浏览器窗口的指定坐标。元素的位置通过 “left”, “top”, “right” 以及 “bottom” 属性进行规定。不论窗口滚动与否,元素都会留在那个位置。
  4. absolute,生成绝对定位的元素,相对于距该元素最近的已定位(position不为static)的祖先元素进行定位。此元素的位置可通过 “left”、”top”、”right” 以及 “bottom” 属性来规定。
  5. relative,生成相对定位的元素,相对于该元素在文档中的初始位置进行定位。通过 “left”、”top”、”right” 以及 “bottom” 属性来设置此元素相对于自身位置的偏移。

相对定位relative

相对定位的参照物是它本身

每一个元素都可以看作一个盒子,文档流就是由这些盒子堆砌而成,而每个盒子都在这个文档流中占据了一个位置,如果我们把这个盒子设置成相对定位,那么就可以拿起这个盒子相对于它原来所占据的位置向别的地方移动,如设置left:50px就是相对于盒子原来位置向右移动了50个像素,我们用具体的例子来说明。
下面是一个所有元素都没有设置过任何定位方式的原始页面布局。

我们把box-2设置成相对定位并向右移动60像素,向下移动120像素。

 .box-2{
    background-color: #00A5FF;
    position: relative;
    left: 60px;
    top:120px;
}

得到下面的效果

  • 从上图我们可以发现box-2相对于它原来的位置向下且向右移动了,并且原来的位置留下了一片空白,但是其他的元素并没有占据它,说明元素设置相对定位后,可以相对于其在普通流中的位置偏移,原本所占的空间仍保留
  • 同时我们从图上可以看出,box-2移动之后覆盖了其他的元素,这说明当元素被设置相对定位后,将激活z-index属性,其层叠级别高于原本的文档流。此时如果给box-5也设置 position: relative,那么box-5又会覆盖box-2。

绝对定位absolute

绝对定位的参照物是相对于该元素最近的已定位的祖先元素,如果没有一个祖先元素设置定位,那么参照物是body。

绝对定位与相对定位的一大不同之处就是,当我们把一个元素设置成绝对定位,那么这个元素将会脱离文档流,漂浮在文档流上方,并且后面的元素将会填充它原来的位置。绝对定位元素根据它的参照物移动自己的位置,而参照物则需要根据它祖先元素的定位设置来确定。我们就用实例说明绝对定位的特点和需要注意的地方。
下面是一个所有元素都没有设置过任何定位方式的原始页面布局。

  1. 祖先元素都没有设置定位,元素相对于body转移位置。
    给box-2设置成position: absolute;

      .box-2{
        background-color: #00A5FF;
        position: absolute;
    }     
    

    得到下面的效果

    • 我们可以看到最后一个box存在的位置空了出来,这是因为box-2脱离文档流漂浮到文档上方,并且后面的元素填补了上去,说明元素设置绝对定位后脱离文档流,后面的元素将填补它的位置
    • 接着你可能就会发现box-3失踪了,其实它没有失踪,它是在box-2下面,就像相对定位一样,当元素被设置绝对定位后,将激活z-index属性,其层叠级别高于原本的文档流
  2. 你可能会问了,不是说祖先元素都没有定位时,元素会相对于body来改变自己的位置吗,为什么它还是飘在原来的位置,而没有飘到body顶头呢,那么请看,我把left和top属性加上会出现什么样的结果。

    .box-2{
          background-color: #00A5FF;
          position: absolute;
          left: 0;
          top:0;
      }   
    

    得到下面的效果

    • 现在可以看到它与body顶头了,因为光设置一个元素的相对定位它只会漂浮到原来位置的上空,并不会漂浮到参照物的文档流最前方,而只有设置了left、top、right、bottom这些参数的时候才能激活它相对于参照物移动的效果。
  3. 祖先元素grandpa设置定位,元素相对于grandpa转移位置。

    .grandpa{
        background-color: #55a532;
        height: 500px;
        width: 600px;
        margin: 40px;
        position: relative;
    } 
    .box-2{
        background-color: #00A5FF;
        position: absolute;
        left: 20px;
        top:20px;
    }   
    

    得到下面的效果

  4. 祖先元素father设置定位,元素相对于father转移位置。

    .father{
        background-color: #55a532;
        height: 400px;
        width: 500px;
        margin: 50px;
        position: relative;
    } 
    .box-2{
        background-color: #00A5FF;
        position: absolute;
        left: 20px;
        top:20px;
    }   
    

    得到下面的效果

  5. 父元素son以及祖先元素father、grandpa都设置定位,元素相对于son转移位置。

    .grandpa,.father,.son{
           position: relative;
    }
    .box-2{
        background-color: #00A5FF;
        position: absolute;
        left: 20px;
        top:20px;
    }   
    

    得到下面的效果

    • 当祖先元素不止一个设置了定位的时候,选择最近的一个作为参照物

小结

现在你应该就能明白为什么上一篇博文中那么多居中方式都要设置其父元素的position为relative了吧,其实虽然absolute要求的是祖先元素的定位方式是除static都可以,但是最好还是设置成相对定位,因为你只设置relative而不设置left、top等参数的话对元素自身和其他元素是没有影响的,但如果你设置成fixed,元素就有可能受到浏览器窗口的影响(如果有特殊需要当然可以使用),而你设置成inherit也没有什么意义,况且浏览器对它的支持性也不是很好,显然用来限制absolute的话用relative是最合适的。