网页布局三种方式(3)

53 阅读9分钟

CSS 定位是网页布局的核心方式之一,包含 static、relative、absolute、fixed、sticky 五种类型。static 为默认值,元素遵循正常文档流;relative 相对自身偏移且不脱离流;absolute 脱离流并相对最近非 static 祖先定位;fixed 脱离流且相对视口固定,不随滚动变化;sticky 结合前两者特性,滚动到阈值后固定。它们各有适配场景,共同支撑起灵活的网页交互布局

定位(Position)

概念:

在网页布局的三大核心方式中(普通流、浮动、定位),定位(Position)是最灵活也最需要谨慎使用的一种。它允许元素脱离正常文档流,按照开发者指定的规则精准摆放,特别适合实现悬浮菜单、弹窗、滚动跟随等交互效果。

定位的核心概念

定位的实现依赖于 position 属性,通过设置该属性的值,元素会进入 "定位模式",并可通过 top/bottom/left/right 四个属性调整位置。

定位的关键特性

  • 脱离文档流:除 staticrelative 外,其他定位方式会使元素脱离正常布局流,不占据原位置
  • 参考系:不同定位方式的位置计算基准不同(下文详解)
  • 层级控制:可通过 z-index 调整定位元素的堆叠顺序

五种定位类型及区别

定位类型说明参考系是否脱离文档流
static默认值,无特殊定位,遵循普通流
relative相对自身原位置偏移,不影响其他元素自身原位置
absolute绝对定位,相对于最近的非 static 祖先元素偏移static 祖先元素
fixed固定定位,相对于浏览器视口偏移,不随滚动变化浏览器视口
sticky粘性定位,滚动到指定位置后固定,结合了 relativefixed 的特性最近滚动祖先 + 自身否(固定后类似脱离)

1. static(默认定位)

核心特性:

元素遵循正常文档流,top/left 等偏移属性无效,是所有元素的默认定位方式。

  • 元素按正常顺序排列在文档流中,前后文本会环绕其上下
  • 即使设置 top/left,元素位置也不会发生偏移
  • 不脱离文档流,会占据正常布局空间
图示解释:

默认定位.png

代码示例:
<div class="static-demo">
  <p>普通文本内容(用于参照文档流)</p>
  <div class="static-box">static 定位元素</div>
  <p>后续文本(验证是否影响文档流)</p>
</div>

<style>
.static-demo {
  width: 500px;
  padding: 20px;
  border: 1px solid #ccc;
}

.static-box {
  width: 150px;
  height: 80px;
  background: #ff4444;
  color: white;
  text-align: center;
  line-height: 80px;
  
  /* static 是默认值,可省略 */
  position: static;
  
  /* 尝试设置偏移,无效果 */
  top: 20px;
  left: 30px;
}
</style>

2.relative(相对定位)

核心特性:

相对于自身原位置偏移,不脱离文档流,原位置仍被保留。

  • 元素从原位置(文档流中的默认位置)向右下方偏移
  • 原位置仍保留空白(下方文本未向上移动),证明未脱离文档流
  • 常用于微调元素位置或作为 absolute 定位的参考容器
图示解释:

相对定位.png

代码示例:
<div class="relative-demo">
  <p>上方参照文本</p>
  <div class="relative-box">relative 定位元素</div>
  <p>下方参照文本(观察与上方元素的间距)</p>
</div>

<style>
.relative-demo {
  width: 500px;
  padding: 20px;
  border: 1px solid #ccc;
  margin-top: 20px;
}

.relative-box {
  width: 150px;
  height: 80px;
  background: #00C851;
  color: white;
  text-align: center;
  line-height: 80px;
  
  position: relative;
  /* 相对于自身原位置偏移 */
  top: 20px;  /* 向下偏移20px */
  left: 40px; /* 向右偏移40px */
}
</style>

3. absolute(绝对定位)

核心特性:

脱离文档流,相对于最近的非 static 祖先元素定位,若没有则相对于浏览器视口

  • 元素脱离文档流,原位置不再保留(下方文本会向上移动填补空间)
  • 因父容器设置了 position: relative,故以父容器为参考系定位
  • 若删除父容器的 position: relative,元素会向上寻找非 static 祖先,最终可能相对于浏览器视口定位
图示解释:
绝对定位.png ###### 代码示例:
<div class="absolute-container">
  <p>容器内的文本内容</p>
  <div class="absolute-box">absolute 定位元素</div>
  <p>容器内的后续文本(观察是否占据空间)</p>
</div>

<style>
.absolute-container {
  width: 500px;
  height: 200px;
  padding: 20px;
  border: 1px solid #ccc;
  margin-top: 20px;
  
  /* 关键:为absolute提供参考系 */
  position: relative;
}

.absolute-box {
  width: 150px;
  height: 80px;
  background: #2196F3;
  color: white;
  text-align: center;
  line-height: 80px;
  
  position: absolute;
  /* 相对于父容器(absolute-container)定位 */
  top: 50px;   /* 距离容器顶部50px */
  right: 30px; /* 距离容器右侧30px */
}
</style>

4. fixed(固定定位)

核心特性:

脱离文档流,相对于浏览器视口定位,位置不随页面滚动变化。

  • 元素固定在浏览器右下角,滚动页面时位置始终不变
  • 脱离文档流,不影响其他元素布局
  • 常用于 "回到顶部" 按钮、固定导航栏、悬浮客服窗等组件
图示解释:

固定定位.png

代码示例:
<div class="fixed-demo">
  <h3>向下滚动页面查看效果</h3>
  <!-- 增加高度用于演示滚动 -->
  <div style="height: 1000px;"></div>
  <div class="fixed-box">回到顶部</div>
</div>

<style>
.fixed-demo {
  width: 500px;
  margin: 20px auto;
}

.fixed-box {
  width: 80px;
  height: 30px;
  background: #FFC107;
  color: #333;
  text-align: center;
  line-height: 30px;
  border-radius: 4px;
  cursor: pointer;
  
  position: fixed;
  /* 相对于浏览器视口定位 */
  bottom: 30px; /* 距离视口底部30px */
  right: 30px;  /* 距离视口右侧30px */
}
</style>

5. sticky(粘性定位)

核心特性:

结合relativefixed 的特性,未滚动到阈值时表现为 relative,滚动到阈值后表现为 fixed

  • 初始状态下,标题按 relative 规则在文档流中排列
  • 向下滚动页面,当标题距离视口顶部小于 10px 时,会固定在视口顶部(类似 fixed
  • 向上滚动到原位置时,会恢复 relative 状态,回归文档流
  • 常用于列表标题、筛选条件栏等需要 "滚动时固定" 的场景
图示解释:

粘性定位.png

代码示例:
<div class="sticky-demo">
  <h3>向下滚动页面,标题会固定</h3>
  <div class="sticky-title">这是粘性标题</div>
  <!-- 增加高度用于演示滚动 -->
  <p>内容行 1</p>
  <p>内容行 2</p>
  <p>内容行 3</p>
  <div style="height: 800px;"></div>
</div>

<style>
.sticky-demo {
  width: 500px;
  margin: 20px auto;
  border: 1px solid #ccc;
  padding: 20px;
}

.sticky-title {
  height: 40px;
  line-height: 40px;
  background: #9C27B0;
  color: white;
  padding: 0 10px;
  
  position: sticky;
  /* 滚动到距离视口顶部10px时固定 */
  top: 10px;
}
</style>

CSS五种定位方式图解完整代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS五种定位方式可视化演示</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      font-family: 'Arial', sans-serif;
    }

    body {
      padding: 20px;
      line-height: 1.6;
      background-color: #f5f5f5;
    }

    .demo-section {
      background: white;
      padding: 30px;
      margin-bottom: 50px;
      border-radius: 8px;
      box-shadow: 0 2px 8px rgba(0,0,0,0.1);
    }

    h2 {
      color: #333;
      margin-bottom: 20px;
      padding-bottom: 10px;
      border-bottom: 2px solid #eee;
    }

    h3 {
      color: #555;
      margin: 15px 0;
    }

    .desc {
      color: #666;
      margin-bottom: 20px;
      padding: 10px;
      background: #f9f9f9;
      border-radius: 4px;
    }

    /* 公共盒子样式 */
    .box {
      width: 100px;
      height: 100px;
      color: white;
      font-weight: bold;
      text-align: center;
      line-height: 100px;
      border-radius: 6px;
      display: inline-block;
    }

    .box1 { background: #ff4444; }
    .box2 { background: #00C851; }
    .box3 { background: #2196F3; }

    /* 参考容器样式 */
    .container {
      width: 100%;
      height: 250px;
      border: 2px dashed #999;
      padding: 20px;
      margin: 10px 0;
      position: relative; /* 用于absolute定位参考 */
    }

    /* 1. static定位演示 */
    .static-demo .box {
      position: static; /* 默认值 */
    }

    /* 2. relative定位演示 */
    .relative-demo .box2 {
      position: relative;
      top: 30px;
      left: 50px;
    }

    /* 3. absolute定位演示 */
    .absolute-demo .box3 {
      position: absolute;
      top: 80px;
      right: 100px;
    }

    /* 4. fixed定位演示 */
    .fixed-box {
      position: fixed;
      bottom: 30px;
      right: 30px;
      width: 80px;
      height: 80px;
      background: #FFC107;
      color: #333;
      text-align: center;
      line-height: 80px;
      border-radius: 50%;
      box-shadow: 0 2px 10px rgba(0,0,0,0.2);
    }

    /* 5. sticky定位演示 */
    .sticky-container {
      height: 500px; /* 用于滚动演示 */
      margin-top: 20px;
    }

    .sticky-header {
      position: sticky;
      top: 10px;
      height: 50px;
      line-height: 50px;
      background: #9C27B0;
      color: white;
      padding: 0 20px;
      border-radius: 4px;
    }

    .scroll-content {
      height: 1000px; /* 制造滚动区域 */
      padding: 20px;
      background: #f0f8ff;
      border-radius: 4px;
    }

    .note {
      color: #ff6b6b;
      font-style: italic;
      margin-top: 10px;
    }
  </style>
</head>
<body>
  <h1>CSS五种定位方式可视化演示</h1>

  <!-- 1. static定位 -->
  <section class="demo-section">
    <h2>1. static(默认定位)</h2>
    <div class="desc">
      元素按照正常文档流排列,<code>top/left</code>等偏移属性无效,块级元素从上到下排列, inline-block从左到右排列。
    </div>
    
    <div class="container static-demo">
      <div class="box box1">box1</div>
      <div class="box box2">box2</div>
      <div class="box box3">box3</div>
    </div>
    
    <div class="note">→ 三个盒子按默认顺序排列,没有任何偏移</div>
  </section>

  <!-- 2. relative定位 -->
  <section class="demo-section">
    <h2>2. relative(相对定位)</h2>
    <div class="desc">
      元素相对于自身原位置偏移,<strong>原位置仍被保留</strong>(不脱离文档流),通过<code>top/left/bottom/right</code>设置偏移量。
    </div>
    
    <div class="container relative-demo">
      <div class="box box1">box1</div>
      <div class="box box2">box2<br>(偏移后)</div>
      <div class="box box3">box3</div>
    </div>
    
    <div class="note">→ 中间的box2相对于自身原位置向右下方偏移,原位置保留空白</div>
  </section>

  <!-- 3. absolute定位 -->
  <section class="demo-section">
    <h2>3. absolute(绝对定位)</h2>
    <div class="desc">
      元素<strong>脱离文档流</strong>,相对于最近的非static定位祖先元素(这里是虚线容器)定位,原位置不再保留。
    </div>
    
    <div class="container absolute-demo">
      <div class="box box1">box1</div>
      <div class="box box2">box2</div>
      <div class="box box3">box3<br>(绝对定位)</div>
    </div>
    
    <div class="note">→ box3脱离文档流,相对于虚线容器右上角偏移,原位置被box1和box2占据</div>
  </section>

  <!-- 4. fixed定位 -->
  <section class="demo-section">
    <h2>4. fixed(固定定位)</h2>
    <div class="desc">
      元素<strong>脱离文档流</strong>,相对于浏览器视口定位,<strong>不随页面滚动变化</strong>,常用于固定导航或回到顶部按钮。
    </div>
    
    <div class="container">
      <p>向下滚动页面,观察右下角的黄色圆形按钮</p>
      <div style="height: 800px;"></div> <!-- 制造滚动区域 -->
    </div>
    
    <div class="fixed-box">fixed</div>
    <div class="note">→ 右下角的fixed按钮会始终停留在浏览器视口的固定位置</div>
  </section>

  <!-- 5. sticky定位 -->
  <section class="demo-section">
    <h2>5. sticky(粘性定位)</h2>
    <div class="desc">
      结合relative和fixed特性:滚动未到阈值时表现为relative(在文档流中),滚动到阈值后表现为fixed(固定在视口)。
    </div>
    
    <div class="sticky-container">
      <p>向下滚动页面,观察下方的紫色标题</p>
      <div class="sticky-header">我是粘性标题(滚动试试)</div>
      <div class="scroll-content">
        <p>滚动内容区域...</p>
        <p>继续滚动...</p>
        <p>当标题快离开视口顶部时会固定住</p>
        <p>继续滚动查看效果...</p>
      </div>
    </div>
    
    <div class="note">→ 紫色标题在滚动到距离视口顶部10px时会固定,向上滚动时会恢复原位</div>
  </section>

</body>
</html>

总结

定位类型核心差异点典型应用场景
static遵循文档流,无偏移效果所有元素默认状态
relative相对自身偏移,不脱离流微调位置、作为 absolute 容器
absolute相对非 static 祖先,脱离流弹窗、下拉菜单
fixed 相对视口固定,不随滚动变化回到顶部按钮、固定导航
sticky滚动时自动切换定位方式粘性标题、筛选栏