CSS position 属性生成器

通过图形界面切换5种CSS position取值(static、relative、absolute、fixed、sticky),实时预览top/right/bottom/left与z-index的效果,并免费生成对应的CSS代码。

使用提示

  • 切换到position: relative并设置top/left后,Box B会从原来的位置发生视觉偏移,请注意Box C(后一个元素)的位置并不会改变。
  • 切换到absolute或fixed后,Box B会完全脱离正常文档流,因此Box C会往上填补它留下的空隙。
  • z-index决定了元素重叠时的堆叠顺序,但对position: static的元素没有任何效果——在测试"设置 z-index"之前请先切换position。
  • position: sticky只在可滚动的容器内才会生效。请实际滚动预览框,观察元素在中途被固定住的效果。
  • 生成的CSS代码可以直接复制粘贴到你自己的样式表中,不妨在真实页面上确认效果是否一致。

常见问题

absolute相对于最近的"已定位祖先元素"(即position不为static的父元素)定位,如果没有这样的祖先,最终会以页面的初始包含块为基准。而fixed始终相对于浏览器视口定位,因此即使页面滚动,它也会一直停留在屏幕上的同一位置。

最常见的原因是父元素设置了overflow: hidden或overflow: auto、父元素的高度与sticky元素本身相差无几导致没有可粘附的空间,或者根本没有设置top等偏移值。此外sticky的效果只在其父容器范围内生效,因此父容器本身需要具备可滚动的区域。

relative会以该元素本应作为普通static元素时所占据的原始位置为基准,按照设置的top/right/bottom/left值做视觉上的偏移。关键在于,它原本占据的空间在布局中仍然被保留——这与会完全脱离文档流的absolute有明显区别。

z-index只对非position: static(即relative、absolute、fixed、sticky)的元素生效。此外,如果父元素同时使用了transform或opacity等样式,会创建独立的堆叠上下文,子元素的z-index就只能在该上下文内部生效,可能不会得到预期的效果。

常见做法是给想作为基准的父元素设置position: relative。即使不设置任何偏移值,仅仅添加position: relative就能使其成为"已定位元素",其内部的absolute子孙元素就会以该元素的内侧边缘为基准进行定位。
ツールくん

闲话 ― position: sticky标准化的漫长历程

CSS早期就已经拥有static、relative、absolute、fixed这4种取值,但要实现"滚动到一定位置后才固定"的表头或侧边栏,长期以来只能依靠JavaScript监听滚动事件,再手动切换为position: fixed。当时并不存在仅用CSS就能完成这一效果的方案。

position: sticky的构想早在2012年前后就已被写入CSS Positioned Layout Module Level 3规范,但实现难度较高。Safari大约在2013年率先以带浏览器前缀的形式(-webkit-sticky)实现了它,Chrome直到2017年才支持标准的sticky关键字,而包括Firefox在内的主流浏览器都能放心使用,则要等到2020年前后。

从实现原理来看,sticky"滚动到中途被固定"的行为可以理解为relative与fixed的混合体:通常按照relative的方式遵循正常文档流,一旦滚动位置到达指定的偏移量,就会表现得如同切换为fixed一样。这种切换只会在父元素的可滚动范围内发生,这也正是许多人误以为sticky"不起作用"的主要原因。

如今,固定表格表头、让目录在滚动时始终可见等场景中,sticky已成为Web设计的常用技巧。不再需要通过JavaScript监听滚动事件,这在性能和代码简洁性两方面都是实实在在的进步。