CSS定位Position如何实现效果?
摘要:CSS中的属性Position有时能帮助我们实现一些特殊的布局需求,但是它为什么能达成特殊效果的原因很容易被人忽略,通过对文档深入学习我们可以了解他们实现的逻辑,更好的帮助我们理解布局。
前言
之前在《CSS之浮动》中,我当时是想一起说说定位的,因为我在很多地方看到有把float和position放在一起讲的,说它们的一些属性值可以使元素脱离文档流,但是没想到在准备内容的时候,发现浮动的内容有点多,就先把浮动的内容单独整了一篇。本文就继续来说说定位吧。
基本信息
Name:
position
Value:
static | relative | absolute | sticky | fixed
Initial:
static
Applies to:
all elements except table-column-group and table-column
Inherited:
no
Percentages:
N/A
Computed value:
specified keyword
Canonical order:
per grammar
Animation type:
discrete
尽管在规范文档中我们能看到Position可设置的值有5个,但一般我们不太会去手动设置static,static代表按照普通文档流布局,默认情况下position的值为static。所以我们现在主要关注后面几个值,relative、absolute、sticky和fixed,他们都是按照某个参照物来定位,区别就在于参照物的不同。因此这四个值都会使选中元素的定位算法不同于正常文档流的布局计算;其中sticky是CSS3新增的内容。
relative
从文档中的描述可以看出,relative这个属性值,表示选中的元素将根据原本自身在普通流中的位置来计算定位,是一个相对于自身的偏移。虽然这个元素的位置发生了偏移,但这只是视觉效果并不会改变其他盒子的尺寸或位置,也就是说假设给一个DIV设置了relative,它后面的盒子在计算位置的时候并不会考虑这个DIV产生的偏移。也就是不管这个DIV是不是设置了relative,都不会影响它后面盒子的位置计算。比如我们来看这个例子:
.nav {
position: relative;
/*top: -50px;*/
width: 500px;
height: 300px;
background: orange;
}
.section {
width: 500px;
height: 300px;
background: aquamarine;
}
<div class="nav"></div>
<div class="section"></div>
const rect = document.querySelector('.section').getBoundingClientRect();
console.log(rect.top);
在脚本中log出来的值,不管是否给.nav设置了top: -50px;,还是不设置postion这个属性时,结果都是一样的。因此可以看出,虽然设置了position: relative;之后当前元素的定位可以改变,但这个元素原本的几何属性还是会影响文档流其他元素的布局计算。
absolute
absolute属性值会使元素被移出正常的文档流,因此这个元素对同级和祖先元素的尺寸和位置不会产生影响,这就和relative不一样了。并且当盒子设置了absolute,它的定位和尺寸将根据它的包含块来计算。因此盒子的位置和尺寸可以通过top、right、bottom和left属性来指定,这些值是相对于包含块的:
the box is positioned and sized solely in reference to its absolute positioning containing block
包含块
那么哪个是绝对定位元素的包含块呢?假设有以下代码:
<div class="container">
<div class="title">我是标题1</div>
<div class="content">我是内容我是内容我是内容。天街小雨润如酥,草色遥看近却无,最是一年春好处,绝胜烟柳满皇都。</div>
</div>
单看HTML的话,我们会觉得.title这个元素的包含块是.container这个盒子建立的,但是如果设置了以下CSS,我们会看到页面效果和预期的并不一致。
