absolute与fixed定位核心区别在于参考系:absolute相对最近已定位祖先,fixed始终相对视口且滚动不动;前者适合随页面滚动的弹窗,后者适合屏幕钉住的浮层。
关键看「参考系」:absolute 相对于最近的已定位(position 为 relative、absolute 或 fixed)祖先元素;fixed 始终相对于视口(viewport),滚动时不动。
弹出层若需随页面滚动而移动(比如遮罩层下内容可滚,弹窗跟着动),选 absolute;若要钉在屏幕某处不随滚(如右下角通知、全局操作浮层),必
须用 fixed。
fixed 元素会脱离文档流,且在 iOS Safari 中可能触发输入框聚焦时键盘顶起导致定位错乱absolute 若父容器没设 position: relative,会一直往上找,最终可能相对 body 或 html,行为不可控transform 影响:父级加了 transform,fixed 会退化为相对该元素定位(Chrome/Firefox 已修复,但 Safari 旧版本仍存在)典型结构是两层:全屏 overlay(半透黑)+ 居中 modal。二者定位方式常搭配使用:
.overlay {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0, 0, 0, 0.6);
z-index: 1000;
}
.modal {
position: fixed;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
width: 90vw;
max-width: 480px;
z-index: 1001;
}
absolute 做遮罩,否则滚动时遮罩会“漏”出顶部或底部modal 用 fixed + transform 居中,比用 margin 或 top/left 配合固定宽高更健壮z-index,且 modal 必须高于 overlay,否则点不到内部按钮iOS Safari(尤其 iOS 12–15)在软键盘弹出时,fixed 元素可能被错误地“吸附”到页面顶部或消失。这不是 bug,而是浏览器为腾出输入空间做的强制重排。
focus 事件,在 input 获取焦点时,将 modal 切换为 absolute,并动态计算 top 值(基于 window.scrollY + 视口偏移)fixed 元素内放 input 或 textarea,优先用 absolute + 滚动容器包裹表单vh 单位做高度(Safari 中键盘弹出会改变 vh 计算值),改用 height: 100% 配合父容器 min-height: 100vh
z-index 只在同一个 stacking context 内有效。如果父容器有 opacity 、transform、filter 或 will-change,就会创建新 stacking context,子元素的 z-index 只在该上下文中比较。
z-index: 9999 也可能被盖住opacity: 0.99)