CSS:positioning的偏移属性

定义

lefttoprightbottomCSS 定位(positioning)系统中的偏移属性,用于精确控制元素的位置

这些属性 只有在元素的 position 值不是 static(默认值)时才生效。即:position: relativeabsolutefixedsticky 时可用。

它们定义了「元素的某条边」距离「其定位上下文对应边」的偏移量。

属性 控制哪条边? 相对于谁? 增大值 → 元素往哪走?
left 元素的 左边缘 定位上下文的 左边缘 向右 移动
top 元素的 上边缘 定位上下文的 上边缘 向下 移动
right 元素的 右边缘 定位上下文的 右边缘 向左 移动
bottom 元素的 下边缘 定位上下文的 下边缘 向上 移动

方向

left: 20rpx 表示:把元素的左边缘,放到「定位上下文左边缘往右 20rpx」的位置。

👉 实际上是向移动!

  • ❌ 错误理解:“left: 20 就是让元素向左边移动 20 个单位

假设有一个容器(定位上下文)宽 300rpx:

定位上下文(父容器)
┌──────────────────────────────┐
0                              300rpx
│                              │
│                              │
└──────────────────────────────┘

情况 1:元素默认位置(left: auto 或未设置)

.child { position: absolute; }

→ 浏览器会把它放在 左上角(0, 0)

┌──────────────────────────────┐
│[■■■]                         │ ← 元素贴在最左边
└──────────────────────────────┘

情况 2:设置 left: 20rpx

.child { position: absolute; left: 20rpx; }

→ 元素的左边缘被推到 距离父容器左边 20rpx 的地方向右移动了 20rpx

┌──────────────────────────────┐
│    [■■■]                     │ ← 向右偏移了!
└──────────────────────────────┘
     ↑
   20rpx

定位上下文

定位上下文(Positioning Context)就是 当前这个元素在定位时所“参考”的那个父容器

它不是随便哪个父元素,而是:最近的、position 不是 static(即 relative / absolute / fixed / sticky)的祖先元素。

如果找不到这样的祖先,那就以 整个页面视口(viewport) 为参考。

简单说:你爸爸(或爷爷)中第一个“有定位能力”的人,就是你的定位上下文。

<template>
  <view class="grandparent">
    <!-- 没有定位,不是定位上下文 -->
    
    <view class="parent">
      <!-- 有 position: relative,成为定位上下文 -->
      
      <view class="child">我是子元素</view>
    </view>
  </view>
</template>

<style scoped>
.grandparent {
  width: 750rpx;
  height: 800rpx;
  background: #f0f0f0;
  padding: 100rpx; /* 留点空间 */
}

.parent {
  width: 500rpx;
  height: 400rpx;
  background: lightblue;
  /* 👇 关键:让它成为定位上下文 */
  position: relative;
  margin: 0 auto; /* 水平居中,方便观察 */
}

.child {
  width: 150rpx;
  height: 100rpx;
  background: coral;
  position: absolute;
  left: 50rpx; /* ← 这里的 "left" 参考谁? */
  top: 50rpx;
}
</style>

问题:left: 50rpx 中的 “50rpx” 是从哪里开始量的?

✅ 答案:.parent 的左边缘开始量!

页面(grandparent)
┌──────────────────────────────────────┐
│                                      │
│   .parent(定位上下文)              │
│   ┌──────────────────────────────┐   │
│   │                              │   │
│   │  ↑                           │   │
│   │ 50rpx                        │   │
│   │  ↓                           │   │
│   │  ┌──────────────┐            │   │
│   │  │   .child     │            │   │
│   │  └──────────────┘            │   │
│   │  ↑                           │   │
│   │ 50rpx(left 值)             │   │
│   └──────────────────────────────┘   │
│        ↑                             │
│        └── 这就是“定位上下文的左边缘” │
└──────────────────────────────────────┘

如果父元素没有定位呢?把上面例子中的 .parentposition: relative 去掉:

.parent {
  /* position: relative; ← 注释掉 */
}

.child 会向上找,发现 .grandparent 也没有定位(默认 static);
→ 最终,定位上下文变成整个页面(视口)
left: 50rpx 就变成 距离屏幕左边 50rpx

屏幕
┌──────────────────────────────────────┐
│                                      │
│50rpx → ┌──────────────┐              │
│        │   .child     │              │
│        └──────────────┘              │
│                                      │
│        .parent(不再作为参考)       │
│        ┌──────────────────────┐      │
│        │                      │      │
│        └──────────────────────┘      │
└──────────────────────────────────────┘

❗ 这就是为什么:要让子元素相对于某个父容器定位,父容器必须设置 position: relative(或其他非-static 值)!

不同 position 值下的行为对比

position: relative(相对定位)

  • 元素仍在文档流中(占位);
  • left/top/right/bottom 表示 相对于它“原本位置”的偏移
  • 其他元素不会感知它的移动(空间仍被保留)。
.box {
  position: relative;
  left: 50rpx;   /* 向右移动 50rpx */
  top: 30rpx;    /* 向下移动 30rpx */
}

✅ 用途:微调位置、制作动画起点、配合绝对定位子元素。

position: absolute(绝对定位)

  • 元素脱离文档流(不占位,其他元素会“无视”它);
  • left/top/right/bottom 相对于最近的非-static 定位祖先
  • 如果祖先都没有定位,则相对于初始包含块(通常是视口)。
.parent {
  position: relative; /* 成为定位上下文 */
}
.child {
  position: absolute;
  left: 20rpx;
  top: 20rpx; /* 距离 .parent 左上角 20rpx */
}

✅ 用途:弹窗、悬浮按钮、居中布局、覆盖层。


position: fixed(固定定位)

  • 类似 absolute,但定位上下文永远是视口(viewport)
  • 滚动页面时,元素固定不动
.header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
}

✅ 用途:顶部导航栏、返回顶部按钮、悬浮客服。


4. position: sticky(粘性定位)

  • 混合模式:默认像 relative,但当滚动到阈值时,表现像 fixed
  • 必须配合 top / bottom 使用(left/right 支持较弱)。
.sticky-title {
  position: sticky;
  top: 0; /* 滚动到顶部时“吸顶” */
}

✅ 用途:列表分组标题、表格表头吸顶。

关键规则与技巧

leftright 可同时设置(top/bottom 同理)

.full-width {
  position: absolute;
  left: 0;
  right: 0; /* 自动宽度 = 100% */
}

💡 当同时设置 left + right,且未设 width 时,元素宽度 = 容器宽度 - left - right。

规则 2:冲突时的优先级

  • 水平方向:left 优先级 > right(如果写了 leftright 会被忽略,除非 left: auto);
  • 垂直方向:top 优先级 > bottom
  • 但现代浏览器通常能智能处理(如 left:0; right:0 正常工作)。

值可以是

  • 长度:10rpx, 20px, 1em
  • 百分比:50%(相对于定位上下文的宽/高
  • auto(默认值,表示“不偏移”)

值为负数

负数表示“反方向偏移”

属性 负值效果 移动方向 是否超出容器
left: -N 左边缘在定位上下文左边 N 处 ← 向左 是(左)
top: -N 上边缘在定位上下文上边 N 处 ↑ 向上 是(上)
right: -N 右边缘在定位上下文右边 N 处 → 向右 是(右)
bottom: -N 下边缘在定位上下文下边 N 处 ↓ 向下 是(下)

left: -20rpxleft: 20rpx

  • 图示:

    定位上下文
    ← 负 x 方向        原点 (0)         正 x 方向 →
    ... ────|───────────────┬─────────────────────── ...
           -20             0                       +100
                            ↑
                      定位上下文左边缘(x = 0)
    
  • left: 20rpx → 元素左边缘放在 x = +20 的位置(在原点右边);

    • 元素左边缘位于「定位上下文左边缘左侧 20rpx 处」
  • left: -20rpx → 元素左边缘放在 x = -20 的位置(在原点左边)。

    • 元素左边缘位于「定位上下文左边缘右侧 20rpx 处」

      定位上下文(父容器)
              ┌──────────────────────┐
              │                      │
      ← 20rpx →│                      │
      [■■■]   │                      │
              └──────────────────────┘
      ↑
      元素左边缘在这里(在父容器左边外面)
      

top: -30rpx :把元素的上边缘,放到「定位上下文上边缘往上 30rpx」的位置。

  • 元素向上移动超出定位上下文的上边框

            ↑
          [■■■] ← 元素顶部在这里(在父容器上面外面)
            │
            ├──────────────────────┤ ← 定位上下文上边缘
            │                      │
            │                      │
            └──────────────────────┘
    

×

喜欢就点赞,疼爱就打赏