position

104 阅读3分钟

一、position 属性值核心区别

定位基准是否脱离文档流是否保留占位典型应用
static默认值,按文档流正常排列无特殊定位需求的元素
relative元素本身在文档流中的原始位置作为绝对定位子元素的容器
absolute最近的已定位祖先元素(非 static)悬浮提示框、弹出层
fixed浏览器窗口(viewport)固定导航栏、右下角返回按钮
sticky滚动时"吸附"在某个位置部分(滚动到临界点后)滚动时固定的表头、侧边栏标签

二、绝对定位(absolute)的定位规则

  1. 定位基准

    • 若父元素中存在 position: relative/absolute/fixed/sticky,则相对于该父元素定位。
    • 若无,则相对于 初始包含块(通常是 <html> 元素)定位。
  2. 示例

    <div style="position: relative; height: 100px;">
      <div style="position: absolute; top: 20px; left: 30px;">
        绝对定位元素
      </div>
    </div>
    
    • 子元素相对于父元素的左上角偏移 20px(上)和 30px(左)。

三、fixed 与 sticky 的区别

  1. fixed

    • 完全脱离文档流,固定在视口(viewport)的某个位置,滚动时不移动。
    • 示例:
      .fixed-nav {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
      }
      
  2. sticky

    • 初始时按文档流正常排列,滚动到某个临界点后固定在视口。
    • 必须指定 topbottomleftright 中的至少一个值。
    • 示例:
      .sticky-header {
        position: sticky;
        top: 0;
        background: white;
      }
      

四、z-index 与层叠上下文

  1. z-index 的作用

    • 控制元素在 z 轴(垂直于屏幕)上的堆叠顺序,值越大越靠前。
    • 仅对 positionrelativeabsolutefixedsticky 的元素有效。
  2. 层叠上下文(Stacking Context)

    • 每个层叠上下文有独立的 z-index 体系,父级层叠上下文的 z-index 决定子元素的最大层级。
    • 创建层叠上下文的常见方式:
      • 元素的 positionabsolutefixed,且 z-index 不为 auto
      • 元素的 opacity 小于 1。
      • 元素的 transform 不为 none
  3. 面试陷阱

    • 问题:两个同级元素,一个 z-index: 1000,另一个 z-index: 1,哪个在上面?
      • :不一定!若 z-index: 1 的元素位于更高层级的层叠上下文中,则它可能覆盖 z-index: 1000 的元素。

五、实战场景与技巧

  1. 实现模态框(Modal)

    .modal-overlay {
      position: fixed;  /* 覆盖整个视口 */
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(0,0,0,0.5);
      z-index: 1000;    /* 确保在最上层 */
    }
    .modal-content {
      position: absolute; /* 相对于 overlay 定位 */
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%); /* 居中技巧 */
    }
    
  2. 实现文字环绕图片效果

    .image {
      position: relative;
      float: left;  /* 浮动使文字环绕 */
      margin-right: 20px;
    }
    
  3. sticky 吸附效果的兼容性处理

    • 在不支持 position: sticky 的浏览器中,使用 JavaScript 模拟:
      window.addEventListener('scroll', () => {
        const element = document.querySelector('.sticky-element');
        if (window.scrollY > 100) {
          element.classList.add('fixed'); // 添加 fixed 样式
        } else {
          element.classList.remove('fixed');
        }
      });
      

六、问题

1. 问:如何实现一个元素在父元素中水平垂直居中?

  • .parent {
      position: relative;
    }
    .child {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%); /* 推荐方法 */
    }
    
    或使用 Flexbox/Grid(若父元素支持)。

2. 问:position: sticky 的工作原理是什么?

    • 元素初始时按文档流排列,滚动到指定位置(如 top: 0)时固定在视口。
    • 必须有父容器限制其滚动范围,否则会随页面无限滚动。

3. 问:如何解决绝对定位元素覆盖其他内容的问题?

    • 调整 z-index,确保合理的层叠顺序。
    • 使用层叠上下文隔离元素,避免全局 z-index 混乱。
    • 考虑使用 transform 替代部分绝对定位需求,因为 transform 会创建新的层叠上下文。