CSS position 属性生成器

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

把 position 的五个取值摆在一起比

`position` 是决定元素落在何处的属性,取 `static`、`relative`、`absolute`、`fixed`、`sticky` 五个值。本工具让您在这几者之间切换,当场确认 `top`/`right`/`bottom`/`left` 与 `z-index` 如何使劲,并生成 CSS。

**用 `absolute` 摆放的元素飞到意料之外的地方,缘由几乎总是同一个:它是相对「最近的、`position` 不为 `static` 的祖先」来定位的。** 若一个这样的祖先也没有,元素便退而以整页为准。**忘了给父元素加 `position: relative`**,几乎便是每一桩此类事故的全部真相。**`sticky` 另有一个众所周知的陷阱:祖先中任何一处带着 `overflow: hidden` 或 `overflow: auto`,黏附便不起作用。** 而 `z-index` 因被圈在名为「层叠上下文」的嵌套单元之内,**身处较低上下文中的元素,取值再大也升不到另一个之上。**

使用方法

  1. 切换 position 的取值 依次试过这五个,各自以何为准的分别便显出来了。
  2. 挪动偏移量 **请确认:取值为 `static` 时,`top` 之流一概不起作用。**
  3. 改动 z-index 可以看出层叠的次序如何变动。
  4. 复制生成的 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代码可以直接复制粘贴到你自己的样式表中,不妨在真实页面上确认效果是否一致。

这些场景会用到

把标题黏在视窗顶端

**有了 `sticky`,页面滚动时标题依然留在原处。**

把徽标或图标叠在角上

父元素 `relative`、子元素 `absolute`,是最基本的搭配。

放一个固定的按钮

`fixed` 以视窗为准来定位,故页面再怎么滚动它也不动。

查究层叠的毛病

**某个元素藏到了另一个之下时,头一个该疑的便是层叠上下文。**

position 的术语

static
初始值。**在它之下,`top` 之流的偏移量与 `z-index` 一概不起作用。**
relative
把元素**从它本该在的位置**挪开。它动了,可原处的空间仍为它留着。
absolute
**相对最近的、`position` 不为 `static` 的祖先来定位。** 若无此祖先,便以整页为准。
fixed
相对视窗来定位,故页面滚得再远,元素也留在原处。
sticky
先安于寻常的位置,及至所给的偏移量便黏住。**祖先上的 `overflow` 会使它失灵。**
层叠上下文
层叠次序得以定夺的嵌套单元。**其内的 `z-index` 无法与外部的元素直接相比。**

常见问题

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监听滚动事件,这在性能和代码简洁性两方面都是实实在在的进步。