position 属性
我们在项目中经常会使用过相对/绝对定位,相信前端的朋友们对“子绝父相”这句话也不会陌生,指在布局中,父元素使用相对定位,子元素使用绝对定位,我们可以操作子元素的 top bottom left right 相对于父元素布局
那么,position 属性除了我们常用的 absolute 和 relative 还有其他取值吗?
position 属性一共有 5 个取值:static、absolute、relative、fixed、sticky
static
默认值。指定元素使用正常的布局行为,此时我们为其设置 top 和 left 等属性无效
可以观察到,示例中我们为子元素设置了 static,top 和 left 属性均没有生效
relative
relative 对应的定位方式我们称之为相对定位,元素在文档中的正常位置偏移给定的值,不影响其他元素的偏移,和 absolute 不同的是,relative 不会脱离文档流
示例中给盒子 2号设置为相对定位,可以观察到,相对定位元素不会影响其他元素的偏移
相对定位元素会随着滚动条滚动而滚动
absolute
absolute 对应的定位方式我们称之为绝对定位,元素脱离文档流,我们可以指定元素相对于最近的非 static 定位祖先元素的偏移,进而确定元素位置,如果不存在非 statice 定位的祖先元素,则相对于初始包含块定位。
示例中我们设置子元素为绝对定位,设置其 top 和 left 属性,相对于父元素定位均生效
值得一提的是,绝对定位元素也会随着页面滚动一起滚动
绝对定位的元素可以设置外边距(margins),且不会与其他边距合并
这样我们可以联想到使用绝对定位解决margin塌陷,因为元素设置为绝对定位时已经从文档流中移除,不再受其他元素影响,包括margin塌陷
同时,需要注意,绝对定位解决margin塌陷带来的副作用:可能导致元素重叠影响布局
fixed
fixed 对应的定位方式我们称之为固定定位
元素会被移出正常文档流,并不为元素预留空间,通过指定元素相对于屏幕视口(viewport)的位置来指定元素位置。元素的位置在屏幕滚动时不会改变
该定位方式常用于创建在滚动屏幕时仍固定在相同位置的元素
如知乎的点赞和分享功能,无论我们怎么滑动滚动条,元素都不会随着滚动,而是被固定在相同位置
我们 F12验证下,也确实是使用的 fixed 定位,元素被定位在离页面顶部106px,离右侧 calc(50vw - 495px)的位置
fixed
属性会创建新的层叠上下文,如何验证呢?
创建新的层叠上下文的元素有一个特性:可以控制子元素的层叠顺序,即咋这个元素内部,子元素的层叠顺序是独立于外部的,我们可以基于这点验证下 fixed 定位是否创建了新的层叠上下文
在这个例子中,
fixed
定位的元素会始终显示在正常流元素之上,尽管它的z-index
比正常流元素的z-index
小。这是因为fixed
定位的元素创建了一个新的层叠上下文,其内部的层叠顺序与外部是独立的
如果我们改变fixed
定位元素的z-index
值,会发现它并不会改变元素在页面上的显示顺序。因为fixed
定位元素的z-index
值只会影响其内部元素的层叠顺序,而不会影响与其同级的元素。也就验证了fixed
定位元素创建了一个新的层叠上下文
sticky
sticky 对应的定位方式我们称之为粘性定位
元素根据正常文档流进行定位,然后相对它的最近滚动祖先(nearest scrolling ancestor)和 containing block(最近块级祖先 nearest block-level ancestor),包括 table-related 元素,基于
top
、right
、bottom
和left
的值进行偏移。偏移值不会影响任何其他元素的位置。 该值总是创建一个新的层叠上下文(stacking context)。注意,一个 sticky 元素会“固定”在离它最近的一个拥有“滚动机制”的祖先上(当该祖先的overflow
是hidden
、scroll
、auto
或overlay
时),即便这个祖先不是最近的真实可滚动祖先。这有效地抑制了任何“sticky”行为(详情见 Github issue on W3C CSSWG)。——来自MDN
粘性定位可以被认为是相对定位和固定定位的混合。元素在跨越特定阈值前为相对定位,之后为固定定位。例如:
CNN(www.cnn.com/)
F12可以发现,顶部导航栏分类菜单使用了sticky属性,当往下滚动距离小于一定阈值时,元素为相对定位
我们接着往下滑动一定距离,导航栏不会消失,元素为固定定位,产生一个吸顶的效果,这样不用滑动到顶部我们就可以直接切换tab
sticky应用场景包括但不限于:滚动页面时固定标题、门户网站固定导航栏、侧边栏广告固定在可视范围
子绝父相
Pinterest(www.pinterest.com/)
Pinterest 使用了子绝父相定位来创建瀑布流布局。瀑布流布局中的每个瀑布流块都是绝对定位的子元素,而包含它们的容器则是相对定位的父元素。
子元素使用的相对定位,这样使得子元素的 top、left 等值都是相对最近一层父元素而起作用
我们修改下子元素的 left 值看看效果
写在最后
我们学习了 position 属性的5个值,分别是:static、absolute、relative、fixed、sticky
同时基于每一种定位方式,给出了示例及其实例应用场景,通过开发者工具,我们可以很容易发现元素的定位方式
希望以后在实际运用中能够快速想到不同场景下适用的定位方式,避免一直碰运气的去尝试
“我们可以不用,但不能不会”