跳到主要内容

position

面试速答(30 秒版 TL;DR)

  • position 决定元素是否脱离普通文档流、偏移量相对谁计算,以及和 z-index 如何配合。
  • 5 个常见值要分清:
    • static:默认值,留在文档流,偏移属性无效
    • relative:不脱流,占位还在,但可以相对自己原位置偏移
    • absolute:脱流,相对最近的非 static 祖先定位
    • fixed:通常相对视口定位,滚动时位置不随页面内容走
    • sticky:达到阈值前像 relative,达到阈值后像“局部固定”
  • 面试高频坑:absolute 为什么飞走、sticky 为什么不生效、fixed 为什么像失效、relative 为什么偏移了还占位

心智模型

理解 position,就盯住两个问题:

  1. 这个元素还在不在普通文档流里?
  2. 它的 top/right/bottom/left 到底相对谁算?

只要这两个问题想清楚,position 题基本不会乱。


一、5 个取值分别怎么答

1)static

  • 默认值
  • 元素正常参与文档流
  • top/right/bottom/left/z-index 基本不生效

2)relative

  • 元素仍然占据原来的位置
  • 视觉上可以偏移
  • 最常见用途是给绝对定位子元素提供定位参考
.card {
position: relative;
}

3)absolute

  • 元素脱离文档流
  • 不再占原位置
  • 相对最近的非 static 祖先定位;如果找不到,通常相对初始包含块定位
.badge {
position: absolute;
top: 8px;
right: 8px;
}

4)fixed

  • 元素脱离文档流
  • 通常相对视口定位
  • 常用于吸顶导航、悬浮按钮、全屏遮罩

5)sticky

  • 一种“粘性定位”
  • 没到阈值前像 relative
  • 到阈值后像 fixed
  • 但它只在自己的滚动容器范围内生效

二、定位参考系怎么理解

absolute 最经典的一句话是:

找最近的非 static 祖先当参考系。

所以工程里经常给父元素写:

.parent {
position: relative;
}

这样子元素的绝对定位就不会“飞到页面角落”。

fixed 常见的默认参考系是视口,但如果祖先有 transformfilterperspective 等属性,很多浏览器里它会表现得更像“相对该祖先固定”,这就是常见的“fixed 失效”根源。


三、典型场景怎么落地

1)角标 / 徽标

.card {
position: relative;
}

.badge {
position: absolute;
top: 8px;
right: 8px;
}

2)全屏弹层

.mask {
position: fixed;
inset: 0;
}

3)吸顶目录

.toc {
position: sticky;
top: 72px;
}

四、典型题 & 标准答法

Q1:relativeabsolute 的区别?

答法:

  • relative 不脱流,还保留原位置;偏移后只是视觉位置变化。
  • absolute 脱流,不再占原位置;偏移是相对定位祖先算的。

Q2:为什么 absolute 的元素会跑到页面角落?

答法:

  • 因为它没有找到最近的非 static 祖先。
  • 这时通常会相对初始包含块定位,所以看起来像飞到了页面边角。
  • 常见解决方式是给父容器加 position: relative

Q3:为什么 sticky 不生效?

答法:

  • 没设置 top / bottom 阈值
  • 祖先改变了滚动容器
  • 容器高度不够,根本没有触发滚动条件
  • 被父级裁剪或层级覆盖

Q4:fixed 一定相对视口吗?

答法:

  • 日常可以这么理解,但更严谨地说,在某些祖先存在 transform 等属性时,fixed 的表现会受该祖先影响。

常见追问

1)positionz-index 的关系?

  • 一般要进入定位或相关层叠上下文讨论,z-index 才有意义
  • 但现代 CSS 里,Flex/Grid item 也可能在未显式定位时参与 z-index 比较,所以不要背成过于绝对的死规则

2)inset: 0 是什么?

它是 top/right/bottom/left: 0 的简写,常用于绝对定位或固定定位铺满父容器/视口。

3)stickyfixed 有什么本质区别?

  • fixed 主要相对视口
  • sticky 受滚动容器和阈值控制,只在局部范围内粘住

易错点/坑

  • 以为 relative 偏移后不会占位,其实它原来的位置还在。
  • 给子元素写了 absolute,却没给父元素建立定位参考系。
  • sticky 只写了 position: sticky,忘了写 top
  • 页面里祖先加了 transform,导致 fixed 表现异常却找不到原因。

速记要点(可背诵)

  • static 正常流,relative 不脱流,absolute/fixed 脱流,sticky 是阈值触发的粘性定位。
  • absolute 看最近非 static 祖先。
  • sticky 失效先查阈值、滚动容器、容器高度。