开门见山,第一篇文章我们来说说css里面最常用的position属性
缘由一次笔者面试,被问及了下面的代码,面试官让我画出这5个div的位置,自以为对css胸有成竹的我看到正确答案的那一刻也是吃惊不少,于是回家翻阅文档,想看看relative到底是相对什么定位,absolute到底是怎么绝对定位。
看代码:

<style>
    div {
        border: 1px solid #000;
    }
    .div1{
        width:60px;
        height:120px;
        position: absolute;
        top: 0;
        left: 0;
    }
    .div2 {
        width:120px;
        height:60px;
        position: relative;
        top:30px;
        left:30px;
    }
    .div3 {
        width:120px;
        height:60px;
        position: relative;
        top:15px;
        left:15px;
    }
    .div4 {
        width:120px;
        height:60px;
        position: absolute;
        right:0;
    }
    .div5 {
        width:60px;
        height:120px;
    }
</style>
<body>
    <div class="div1">1</div>
    <div class="div2">2</div>
    <div class="div3">3</div>
    <div class="div4">4</div>
    <div class="div5">5</div>
</body>

大家有个大概的印象,先不急着说答案,我们从MDN上面的关于absolute和relative的概念说起(本文不对fixed做重点)

relative:
This keyword lays out all elements as though the element were not positioned, and then adjust the element's position, without changing layout (and thus leaving a gap for the element where it would have been had it not been positioned). The effect of position:relative on table-*-group, table-row, table-column, table-cell, and table-caption elements is undefined.

absolute:
Do not leave space for the element. Instead, position it at a specified position relative to its closest positioned ancestor if any, or otherwise relative to the initial containing block. Absolutely positioned boxes can have margins, and they do not collapse with any other margins.

笔者粗略翻译一下:

  • reletive:

这个关键字展示元素就好像没被定位过一样,在不改变布局的前提下调整元素位置(因此会在该元素本来的位置留下一个空白)。position:relative对table-*-group,table-row, table-column, table-cell, table-caption无效。

  • absolute:

不给元素保留空间,相反,元素定位的位置是相对它最近的非static定位的祖先元素来确定的。绝对定位的元素可以设置外边距,并且不会与其他边距合并。

(之所以没用MDN中文版翻译是觉得翻译的不好,虽然我翻译的也不咋地。。。)

换成我的理解:

  • relative定位之后不改变文档流位置,保留其定位之前的文档流位置
  • absolute改变文档流,并且是相对于第一个被定位过的(非static)祖先元素定位,如果没有就是根元素

相信大家对于absolute没有什么异议,但是relative我相信很大一部分人没有注意过“保留其定位之前的文档流位置”这句话,这才是重点,看代码来说明

<style>
    body,div {
        border: 1px solid #000;
    }
    .wrap {
        margin: 100px 0 0 100px;
        width: 400px;
        height: 400px;
    }
    .div1 {
        width:120px;
        height:60px;
        position: relative;
        top:30px;
        left:30px;
    }
    .div2{
        width:60px;
        height:120px;
        position: absolute;
        top: 30px;
        left: 30px;
    }        
    .div3 {
        width:120px;
        height:60px;
        position: relative;
        top:15px;
        left:15px;
    }
</style>
<body>
我是body
<div class="wrap">
    我是wrapper
    <div class="div1">1111</div>
    <div class="div2">2222</div>
    <div class="div3">3333</div>
</div>
</body>

结果见下图:

clipboard.png

好的,我们现在来分析一下:

div2不用说,由于父元素wrap没有进行定位,因此他基于html来定位(注意不是body);
重点说应用了relative的div1和div3,可以明显从图中看到div1距离wrap的left和top根本不一样啊,什么鬼啊,可是我们明明设置的都是30px啊,请大家想一下文档中说的那句话“保留其定位之前的文档流位置”,那是不是可以理解成他是基于元素给定relative之前的文档流位置定位的呢,下面我们就来检验下看看是不是成立

clipboard.png

我用ps做了一张图,红点是div1和div3原先的文档流位置,绿点是他们应用了relative之后的位置,这下是不是就对了,证明了我们之前的观点 -- relative是相对于自己的文档流位置进行定位

我在这里补充一句:可能有的同学会问“当div1进行定位之后div3的文档流位置会不会发生变化啊”,答案是不会,因为文档里面说进行relative定位之后“without changing layout”,所以div1和div3的文档流位置都不变。

看懂了上面内容的同学现在可以试着做一下我开篇的那个题目,看看到底有没有理解position这个抬头不见低头见的css属性

好了,第一篇文章就这么华丽的结束了,内容比较简单,欢迎各路大牛给出指导意见。 能看我的文章BB到这里的同学都辛苦了,毕竟知道自己文章一向不通顺,不过我会慢慢提高的,哈哈哈。

附上答案:

clipboard.png


wens
272 声望4 粉丝