定位和 z-index

你想在产品图片的右上角放一个小的"促销"徽章。你想要一个在页面滚动时保持不动的页眉。你想要一个悬浮在页面上所有其他元素上方的对话框。普通的 CSS 间距无法做到这些,因为它只能一个接一个地排列元素。定位是一套工具,让元素脱离这种普通的排列方式,坐在你指定的位置,甚至在其他元素的上方。
position 属性
每个元素都以**static 定位**开始,这只是一种说法,即"坐在你在页面流中的正常位置"。这是默认情况,大多数情况下这正是你想要的。当你希望元素远离那个正常位置时,定位才开始起作用。
第一步是 position: relative。它使用四个偏移属性将元素从其正常位置移动:top、right、bottom 和 left。关键是元素保留其原始空间。没有其他东西会移动来填补这个空隙。
.badge {
position: relative;
top: 10px; /* 从正常位置向下推 10px */
left: 20px; /* 从正常位置向右推 20px */
}这些 top 和 left 偏移在 static 元素上完全不起作用。只有在你给元素设置 position 而不是 static 后,它们才开始工作。
static 开始,意味着它坐在其正常位置。切换到 position: relative,你可以用 top、right、bottom 和 left 轻推它,同时其原始空间保持保留。这些偏移属性在元素被定位之前不起作用,所以如果 top 似乎被忽略了,检查你是否先设置了 position。 绝对定位
position: absolute 是一个更大的移动。它将元素彻底拉出正常流,所以它不再占用任何空间,它周围的元素会合并,就像它从未存在过一样。然后你用相同的 top、right、bottom 和 left 偏移来放置它。
问题是:相对于什么偏移?一个绝对定位的元素定位自己相对于它最近的**定位祖先**,意味着最近的有自己 position 的父元素(除 static 外的任何值)。这就是为什么卡片上的徽章模式总是成对出现的:你使卡片 relative 使其成为参考点,然后使徽章 absolute 使其可以坐在卡片的角落。
.card {
position: relative; /* 成为参考点 */
}
.card .badge {
position: absolute;
top: 8px; /* 从卡片顶部开始 8px */
right: 8px; /* 从卡片右边开始 8px */
}如果卡片上没有 position: relative,徽章会在页面中继续向上搜索定位的祖先,并在你未打算的某处着陆。
position: absolute 将元素拉出流,所以它不占用空间,邻近的元素会在后面合并。然后它相对于其最近设置了 position 的父元素定位。这就是为什么卡片上的徽章技巧是一对:父元素上的 relative,徽章上的 absolute,所以徽章着陆在卡片的角落,而不是某个随机的地方。 Fixed 和 sticky
position: fixed 将元素固定到屏幕本身。它像 absolute 一样离开流,但不是锚定到父元素,而是锚定到**视口**,即可见的窗口。一旦固定,即使你滚动页面,它也会保持在屏幕上的同一位置。这就是导航栏或"回到顶部"按钮如何始终保持可见的方式。
.site-header {
position: fixed;
top: 0; /* 固定到窗口的顶部 */
left: 0;
right: 0; /* 拉伸到完整宽度 */
}position: sticky 是友好的中间地带。粘性元素在页面上正常滚动,直到到达你设置的阈值,然后它会停在该位置。随着其内容向上滚动然后卡在屏幕顶部的章节标题是经典示例。
.section-title {
position: sticky;
top: 0; /* 一旦到达顶部边缘就粘住 */
}position: fixed 将元素固定到屏幕,所以当你滚动时它保持不动,这就是页眉或回到顶部按钮如何保持可见的方式。position: sticky 是中间地带:它随页面滚动,然后一旦到达像 top: 0 这样的阈值就粘住。Fixed 也会与下面的东西重叠,所以为它覆盖的内容留出一些空间。 使用 z-index 堆叠
当元素重叠时,必须有东西来决定哪个坐在上面。这就是 z-index 控制的。较高的 z-index 在较低的前面绘制,所以 z-index: 10 的下拉菜单覆盖 z-index: 1 的卡片。
有一个规则会绊倒所有人:z-index 只适用于定位的元素。如果元素仍然是 static,其 z-index 会被忽略。所以你几乎总是同时设置 position 和 z-index。
.modal {
position: fixed;
z-index: 100; /* 坐在普通页面内容之上 */
}
.modal-overlay {
position: fixed;
z-index: 99; /* 黑色背景,模态窗口后面一步 */
}你很少需要这里的大数字。一个小的、整洁的比例,如 1、10、100,比充满 9999 相互争斗的页面更容易理解。
z-index 决定哪个在前面:较高的数字赢。它只适用于定位的元素,所以普通 static 元素上的 z-index 被忽略,你同时设置 position 和 z-index。保持数字小而整洁,如 1、10、100,而不是一堆 9999。 
