CSS-关于定位,你所需要知道的一切

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhq2005095/article/details/62284377

CSS中的定位在实际开发中经常用到,一些比较刺手的布局,很多时候通过定位这个杀手锏就能够解决。但是对于定位中的细节都模模糊糊的,为了搞明白其中的细节,特意搜索了相关的资料,总结了一下,防止时间久了就忘记了。

1. position的属性值

  • static:默认值。没有定位,元素出现在正常的流中。
  • relative:相对定位。1. 不论其父元素和相邻元素的position是什么,均相对于自身原来的位置来偏移。2. 不会脱离文档流,其原来的位置依然保留着,不会被文档中其他的元素占用。3. 原来是行内元素,设置相对定位后,依然是行内元素。4. 设置了相对定位的块级元素,如果没有设置宽度,其宽度依然是拉伸至父元素宽度的100%。
  • absolute:绝对定位。1. 相对于最近的一个position不为static的父元素来定位,如果没有,则相对于html来定位,注意:此处网上很多资料说是相对于body来定位,下文会进行验证。2. 设置了绝对定位的行内元素,会转化为块级元素,可以设置宽高。3. 设置了绝对定位的块级元素,如果没有设置固定宽度,则其宽度不会自动拉伸至父元素的100%,而是由内容和内边距的宽度来决定的。
  • fixed:固定定位。相对于浏览器的窗口来定位。1. 设置了固定定位的行内元素,会转化为块级元素,可以设置宽高。2. 设置了固定定位的块级元素,如果没有设置固定宽度,则其宽度不会自动拉伸至父元素的100%,而是由内容和内边距的宽度来决定的。
  • 外边距(margins)不会在绝对定位的元素上合并
  • 绝对定位的元素无视了float 这个属性
  • 绝对定位的偏移量不包含父元素的border,但是包含padding

2. 相对定位

相对定位的元素,不管父元素或者相邻的元素的position的状态如何,均相对于自身的位置来定位。且不会改变元素的display属性,以及不会改变块级元素宽度默认拉伸至父元素的100%的特性。

2.1 父元素position属性对相对定位的元素的定位影响

HTML

<div class="outer">
    <div class="left">left</div>
    <div class="center">center</div>
    <div class="right">right</div>
</div>

CSS

<style type="text/css">
    body {
        font-size: 30px;
        font-weight: bold;
    }
    .outer {
        background: red;
        margin: 30px;
        width: 400px;
        height: 400px;
        /*position: relative;*/
        /*position: fixed;*/
        position: absolute;
    }
    .left {
        background: blue;
        height: 100px;
        width: 100px;
    }
    .center {
        background: green;
        width: 100px;
        height: 100px;
        position: relative;
        top: 0;
        left: 0;
    }
    .right {
        background: yellow;
        width: 100px;
        height: 100px;
    }
</style>

首先将父元素div.outer的定位分别都设置成了absolute,fixed,relative,相对定位的元素div.center的位置top和left均设置为0。如图所示:
这里写图片描述
由图可以看出来,无论父元素的position的属性如何,相对定位的元素的位置均没有变化。

2.2 相邻position属性对相对定位的元素的定位影响

HTML

<div class="outer">
    <div class="left">left</div>
    <div class="center">center</div>
    <div class="right">right</div>
</div>

CSS

<style type="text/css">
    body {
        font-size: 30px;
        font-weight: bold;
    }
    .outer {
        background: red;
        margin: 30px;
        width: 400px;
        height: 400px;
    }
    .left {
        background: blue;
        height: 100px;
        width: 100px;
        /*position: fixed;*/
        position: absolute;
        left: 0;
        top: 0;
    }
    .center {
        background: green;
        width: 100px;
        height: 100px;
        position: relative;
        top: 0;
        left: 0;
    }
    .right {
        background: yellow;
        width: 100px;
        height: 100px;
    }
</style>

把相邻的元素div.left设置成绝对定位,left和top都设置为0,这样div.left就脱离了文档流,此时div.center依然是相对定位,left和top都设置为0。效果如图
这里写图片描述
由图可以看出来,div.left已经移动到浏览器的左上角了,不受div.outer的外层div的限制了。center.div虽然设置了left和top为0,但是并没有跟随div.left到浏览器的左上角,这说明相对定位的元素,不受相邻元素的position的属性的影响。此外,试验过div.left的position设置成relative,但是center.div依然是相对于自身定位。

2.3 相对定位对元素display属性的影响

HTML

<div class="outer">
    <span class="left">left</span>
    <div class="center">center</div>
    <div class="right">right</div>
</div>

CSS

<style type="text/css">
    body {
        font-size: 30px;
        font-weight: bold;
    }
    .outer {
        background: red;
        margin: 30px;
        width: 400px;
        height: 400px;
    }
    .left {
        background: blue;
        height: 100px;
        width: 100px;
        position: relative;
        top: 0;
        left: 0;
    }
    .center {
        background: green;
        width: 100px;
        height: 100px;
        position: relative;
        top: 0;
        left: 0;
    }
    .right {
        background: yellow;
        width: 100px;
        height: 100px;
    }
</style>

将left元素改为行内元素span,给其设置宽和高,div.center元素的宽度改为不设置。效果如图
这里写图片描述

由图可见,span.left设置了宽和高不起作用,由内容撑开,依然是行内元素,而div.center则在宽度方向上自动拉伸,依然是块级元素。由此可以看出,相对定位的元素,其display属性没有改变。

3. 绝对定位

绝对定位的元素会呈现跟相对定位的元素很多不一样的特性。最大的不同是,绝对定位,是相对于其父元素来定位的,父元素的position属性对元素的绝对定位的位置有决定性的影响。只要是父元素的position不为static,则绝对定位的元素相对于其最近的父元素来定位,如果最近的父元素的position为static,则逐级向上查找,直到找到position不为static的父元素,如果所有父元素的position均为static,则相对于html来定的,而不是相对于body。且绝对定位会改变行内元素的display属性,将变为块级元素,同时会将块级元素的宽度从自动拉伸变为适应内容。绝对定位的元素,对其设置float是无效的。绝对定位的偏移量是相对于父元素的border的内边缘,即不包括border在内,而包含padding。

3.1 父元素的position属性对于绝对定位的影响

HTML

<div class="outer">
    <div class="left">left</div>
</div>

CSS

<style type="text/css">
    body {
        font-size: 30px;
        font-weight: bold;
    }
    .outer {
        background: red;
        margin: 30px;
        width: 400px;
        height: 400px;
        /*position: relative;*/
        /*position: fixed;*/
        position: absolute;
        left: 0;
        top: 0;
    }
    .left {
        background: blue;
        height: 100px;
        width: 100px;
        position: absolute;
        left: 10px;
        top: 10px;
    }
</style>

将父元素div.outer设置为absolute,relative,fixed,则div.left设置为绝对定位,则此时子元素是相对于父元素来绝对定位的。如图所示。
这里写图片描述

如果将父元素div.outer不设置定位,默认为static,则此时div.left设置为绝对定位后,脱离了父元素的限制,移动到浏览器的左上角了,相对于html绝对定位了。如图所示。
这里写图片描述

3.2 绝对定位究竟是相对于与body还是html

当父元素的position属性均为static时,网上很多资料说是相对于body来绝对定位的的。在w3school上面,有这么一段话:绝对定位是“相对于”最近的已定位祖先元素,如果不存在已定位的祖先元素,那么“相对于”最初的包含块。根据用户代理的不同,最初的包含块可能是画布或 HTML 元素。不管怎样,还是需要亲自动手去试验一下,心里才踏实。

HTML

<div class="outer">
    <div class="left">left</div>
</div>

CSS

<style type="text/css">
    *{
        margin: 0;
        padding: 0;
    }
    html {
        background: #fff;
    }
    body {
        font-size: 30px;
        font-weight: bold;
        background: pink;
        margin: 30px;
    }
    .outer {
        background: red;
        margin: 30px;
        width: 400px;
        height: 400px;
    }
    .left {
        background: blue;
        height: 100px;
        width: 100px;
        position: absolute;
        left: 0;
        top: 0;
    }
</style>

给html和body分别设置背景色,html为白色,body为粉色,同时给body设置了margin,让body左上侧与html分离开来。这时候再给div.left设置绝对定位,同时设置left和top为0。观察此时的div.left元素的位置,如果紧贴浏览器的左上角,则说明相对的是html,如果左上角跟body的左上角重合,则说明是相对于body。实际效果如下图所示。
这里写图片描述

由图可以看出,div.left移动到了浏览器的左上角,而并没有与body的左上角重合,所以看得出来,如果父元素没有定位,则绝对定位是相对于html的。

3.3 相邻元素的position属性对于绝对定位的影响

HTML

<div class="outer">
    <div class="left">left</div>
    <div class="center">center</div>
    <div class="right">right</div>
</div>

CSS

<style type="text/css">
    body {
        font-size: 30px;
        font-weight: bold;
    }
    .outer {
        background: red;
        margin: 30px;
        width: 400px;
        height: 400px;
    }
    .left {
        background: blue;
        height: 100px;
        width: 100px;
        position: relative;
        left: 60px;
        top: 0;
    }
    .center {
        background: green;
        width: 100px;
        height: 100px;
        position: absolute;
        bottom: 0;
        left: 0;
    }
    .right {
        background: yellow;
        width: 100px;
        height: 100px;
    }
</style>

将div.left设置成相对定位,并且处于对比效果设置其left和top,div.center设置成绝对定位,实际效果如图所示:
这里写图片描述

由图可见,div.center移动到了浏览器的左上角,并没有跟随div.left元素而移动。由此可见,相邻元素的position属性对于绝对定位的元素没有影响。

3.4 绝对定位对float属性的影响

绝对定位的元素有很多其他的特性,比较有意思,而且是在使用的时候,需要注意的。首先是绝对定位的元素,如果设置了float的话,则float无效。
HTML

<div class="outer">
    <div class="left">left</div>
</div>

CSS

<style type="text/css">
    body {
        font-size: 30px;
        font-weight: bold;
    }
    .outer {
        background: red;
        margin: 30px;
        width: 200px;
        height: 200px;
    }
    .left {
        background: blue;
        height: 100px;
        width: 100px;
        float: right;
    }
</style>

如果只是设置了浮动,则如图所示:
这里写图片描述

如果同时给div.left设置了绝对定位,则向右浮动失效了。如图所示。

.left {
    background: blue;
    height: 100px;
    width: 100px;
    float: right;
    position: absolute;
    left: 0;
    top: 0;
}

这里写图片描述

3.5 绝对定位的偏移位置包不包括父元素的border ?

HTML

<div class="outer">
    <div class="left">left</div>
</div>

CSS

<style type="text/css">
    body {
        font-size: 30px;
        font-weight: bold;
    }
    .outer {
        background: red;
        margin: 30px;
        width: 200px;
        height: 200px;
        position: relative;
        border: 30px solid yellow;
    }
    .left {
        background: blue;
        height: 100px;
        width: 100px;
        float: right;
        position: absolute;
        top: 0;
        left: 0;
    }
</style>

将父元素div.outer设置成相对定位,同时border的宽度为10px,黄色,以及设置了padding。子元素div.left设置成绝对定位,top和left为0,观察子元素的位置与border的位置关系。如图所示:
这里写图片描述
由图可见,子元素的定位的起点是在border的内侧,但是覆盖住了父元素div.outer的padding。所以,绝对定位的起点不包含父元素的border,但是包括padding。

3.6 绝对定位的元素的margin不合并

浮动和绝对定位不与任何元素产生 margin 折叠。
原因:浮动元素和绝对定位元素不与其他盒子产生外边距折叠是因为元素会脱离当前的文档流,违反了两个margin是邻接的条件,同时,又因为浮动和绝对定位会使元素为它的内容创建新的BFC,因此该元素和子元素所处的BFC是不相同的,因此也不会产生margin的折叠。

参考资料

关于 CSS 定位,你需要知道的5件事
总结一下CSS中的定位 Position 属性

展开阅读全文

没有更多推荐了,返回首页