浅谈CSS position中的relative和absolute
前言
CSS 中的 position
属性指定了元素的定位类型,其有五个可选值,分别是static
、relative
、absolute
、fixed
和 sticky
。分别对应了静态定位、相对定位、绝对定位、固定定位和粘性定位。
这里我们主要探讨平时最常用的 relative
定位和 absolute
定位。网络上有很多相关的讲解,但还是通过自己的理解写一篇学习笔记会让自己的印象更深刻。因此,下面我将从自己的理解角度简单谈一谈,如果错误,请大家批评指正。(我也会把我参考的一些资料列在最后,大家可以自行查看)
absolute 和 relative
下面,我将从定义、定位基准、脱离文档流和内容宽度几个角度进行介绍。
定义
absolute
:绝对定位,脱离文档流。即相对于最近且不是 static 定位的父元素进行定位。position
更多考虑的是父级和子级间的关系,即相对于父元素的定位,不受父元素内其他子元素的影响。
relative
:相对定位,不脱离文档流。即保留自己原本位置,并相对于该位置进行定位。relative
更多考虑的是同级元素间的关系,即考虑同级元素的定位后,得到自己的原本位置,并基于该位置进行相对的移动。
定位基准和文档流
absolute
absolute
在定位时会脱离文档流,不保留自己原本位置,而是相对于其最近且定位不是 static 的父元素进行定位。如果没有这种父元素,则基于 body
定位。
举个例子,我们共有五个<div>
,最外面一层的 mydiv
是其余四个 div 的父元素,即容器。代码如下:
1 | <style> |
1 | <div class='mydiv'> |
效果如下:
我们将第二个 div 设置为 absolute
定位,并设置相应的偏移属性值 top
和 left
。可以看到,第二个 div 的偏移是基于其最近的父元素mydiv
的位置,并且它的原位置没有保留,而是被第三个 div 补上了。
relative
relative
在定位时不脱离文档流,会保留自己原本位置,并相对于该位置进行定位。
我们对上面的代码进行一定的修改,即把第二个 div 设置为 relative
定位。代码如下:
1 | <style> |
效果如下:
我们将第二个 div 设置为 relative
定位,并设置相应的偏移属性值 top
和 left
。可以看到,第二个 div 的偏移是基于它原本位置的,并且它的原位置进行了保留,从而覆盖到了一部分第三个 div。
此外,absolute
定位的元素如果没有指定长度时,其长度为内容长度。而 relative
定位的元素则会和父元素相同。
– 小Tips👇 –
此外,relative
定位的元素还需要考虑到其父元素的内容。如给 div2 添加一个父元素 container2
,并在其中添加文字内容。
1 | <style> |
1 | <div class='mydiv'> |
我们先看看 container2 中没有文字的效果是怎样的,如下:
现在,我们给 container2 中添加文字,效果如下:
由上面的对比我们可以发现,div2 作为container2 的子元素,原本会出现在 container2 的文字下面。因此,top:20px
的偏移是基于它的原本位置的,而不是父元素!故其相比于container2中没有文字的时候,稍微偏下一点,因为同级元素文字会占据一行高度。
而absolute
定位则不会被同级元素影响,因为它是完全基于最近的非static的父元素的位置进行定位的。
内容宽度
absolute
定位的元素宽度会根据内容变化,不受父元素影响,也不会影响父元素。relative
定位的元素宽度会和父元素同步。如果没有设置 relative 元素的宽度,则会跟其父元素宽度一致.
absolute
absolute
定位的元素如果没有设置宽度,则会根据其内容进行自适应变化。效果如下:
relative
relative
定位的元素如果没有设置宽度,则会和父元素一致。这里的父元素为 mydiv
,宽度为 100%
,效果如下:
absolute 父元素和 relative 子元素结合
但是要注意,如果父元素是 absolute
定位的元素并没有设置宽度,此时 relative
定位的子元素的宽度会将父元素撑开。而且,父元素被撑开的宽度是根据其内容的宽度撑开的,和relative移动的位置无关。
我们将上面的 style 样式修改一下,给每个 div 都设置一定的宽度,并验证撑开的效果。代码设置如下:
1 | <style> |
1 | <div class='myDiv'> |
效果如下:
从上面效果可以得出结论:因为 absolute
的父元素的宽度如果没有预先设定的话,则是根据内容来定义的。所以 relative
元素的宽度会撑开absolute
父元素。
注意!!!👇
不过上面的例子有一点比较特殊,即按照 absolute
定位的原理来说,Container2
应当基于 myDiv
的左上角开始定位,即应该覆盖第一个 div。然而例子中 Container2
留在了原位,并且把上移的 div3
覆盖了。
原因是 如果没有设置 top
、left
、right
和 bottom
时,absolute
则不会移动,与原文档流位置一致。
top 和 left 偏移
absolute
absolute
定位可以根据top
、left
、bottom
和 right
来决定元素相对于定位基准的偏移。
top
表示元素上边框与定位基准的顶部的距离,bottom
表示元素下边框与基准底部的距离。如果两者同时存在,只有 top 起作用;如果两者都未指定,则其顶部与原文档流位置一致(就是上面注意点提到的),即垂直位置保持不变。
left
表示元素左边框与定位基准左边的距离,right
表示元素右边框与基准右边的距离。两者同时存在时,只有 left 起作用;如果两者都未指定,则其左边将与原文档流位置一致,即水平保持位置不变。
relative
absolute
定位只可以根据top
、left
来决定元素相对于父元素的偏移。bottom
和 right
不起效。
很感谢你能看到这里!谢谢~
参考资料: (衷心感谢参考资料中各博主的帮助)