位置锚点

Avatar of Juan Diego Rodríguez
Juan Diego Rodríguez

DigitalOcean 为您的旅程的每个阶段提供云产品。 从 价值 200 美元的免费积分开始!

position-anchor 属性将绝对定位的元素链接到一个“锚点”元素。 这将定义默认锚点,并用于“目标”元素上的几个锚点属性和函数。

换句话说,该属性将一个元素定位(或锚定)到我们设置为该属性值的另一个元素。

.target {
  position-anchor: --my-anchor
}

就其本身而言,此示例除了告诉 .target 元素它被定位(或锚定)到一些其他元素之外,并没有做任何其他事情,该元素由称为 --my-anchor 的虚线标识表示。 问题是,我们还没有真正定义 --my-anchor 到底是什么。

在获得有关该属性的更多上下文(包括其语法和接受的值)之后,我们将介绍一个完全有效的示例。

语法

position-anchor: auto | <anchor-element>;
  • 初始值:隐式
  • 应用于:绝对定位的元素
  • 继承:
  • 百分比:N/A
  • 计算值:如指定
  • 规范顺序:按语法
  • 动画:离散

/* Keyword values */
position-anchor: auto;

/* <dashed-ident> examples */
position-anchor: --anchor;
position-anchor: --my-anchor;
position-anchor: --myAnchor;
  • auto将目标元素链接到其隐式锚点。 隐式锚点可以使用非标准 anchor 全局属性或使用 Popover API 找到。
  • <dashed-ident>所需锚点元素的名称。 该值称为“虚线”标识,因为它必须以两个连字符 (–) 为前缀,就像我们对 CSS 自定义属性所做的那样,例如 –my-anchor。

基本用法

在第一个示例中,仅使用 position-anchor 不会有任何效果。 我们告诉 .target 元素它被锚定到另一个我们称为 --my-anchor 的元素。 但是 --my-anchor 代表什么元素? 我们需要它,否则我们就没有锚定到任何真正存在的元素。

定义元素作为其他元素的“锚点”的最简单方法是在我们想要作为锚点的元素上添加 anchor-name 属性。

假设我们在 HTML 中有两个不相关的元素

<div class="anchor">My Anchor</div>
<div class="target">My Target</div>

我们希望 .anchor 元素成为锚点,然后根据 .anchor 元素的位置来定位 .target 元素的位置。

.anchor {
  anchor-name: --my-anchor;
}

.target {
  position: absolute; /* or position: fixed; */
  position-anchor: --my-anchor;
}

就是这样!现在 .anchor.target 元素之间存在关联。 当我们更改 .target 元素的位置时,它将使用 .anchor 元素的位置作为其起始基础。

但同样,我们在这个示例中没有看到太多变化。 这是因为我们还没有改变 .target 元素的位置来查看这种关系的实际效果。 因此,让我们将注意力转向两种不同的方法来更新该元素的位置:使用 anchor() 函数以及内边距属性,或者使用 inset-area 属性

方法 1:anchor() 函数和内边距属性

.target 元素被绝对定位,这意味着它可以使用内边距属性 (top, right, bottom, left) 移动。 将 .target 定位到 .anchor 旁边是理想的,但我们如何知道 .anchor 在哪里才能利用内边距属性? anchor 函数就是为此而生的。 它接收锚点的一侧,并解析为其定位的 <length>

现在我们可以将 .target 的一侧连接到 .anchor 的另一侧。

.target {
  position: absolute;
  position-anchor: --my-anchor;

  top: anchor(bottom);
}

这实际上是在说,“将 .target 的顶部与 .anchor 元素的底部缝合在一起”。 一图胜千言

Two boxes stacked vertically, the top one labeled anchor and the bottom one labeled target.

anchor() 函数采用链接到 target 元素的默认 anchor,但如果我们更明确地说明要锚定到什么,我们也可以直接引用 anchor-name

.target {
  position: absolute;

  top: anchor(--my-anchor bottom);
}

……甚至可以引用页面上的其他锚点! 例如,我们可以告诉 .target 元素将自己锚定到 --my-anchor 元素,但我们仍然可以根据页面上任何其他锚点的位置来定位它,只需在 anchor() 函数中调用它即可

.target {
  position: absolute;
  position-anchor: --my-anchor;

  top: anchor(--my-other-anchor bottom);
}

方法 2:inset-area 属性

也许重新定位锚点的一个“更简单”的方法是使用 inset-area 属性。 你可以想象一个围绕 .anchor 元素的 3×3 虚拟网格

Three by three grid with a yellow element in the center tile labeled 'anchor'.

然后,我们使用以下方法将锚定的 .target 元素定位到网格上的列和行:

  • 物理值,如 left, right, topbottom
  • 尊重当前书写模式的逻辑值,如 startend),以及
  • center 共享值。

例如,如果我们要将 .target 元素跨越虚拟网格上的两个方块,我们可以在任何值上使用 span- 前缀,甚至可以使用 span-all 值将 .target 元素跨越整个网格。

.target {
  position: absolute;
  position-anchor: --my-anchor;

  inset-area: start center,
  /* or */
  inset-area: bottom left,
  /* or */
  inset-area: span-top right,
}

演示

规范

position-anchor 属性在 CSS 锚点定位模块级别 1 规范中定义,该规范在撰写本文时处于工作草案状态。 这意味着在该功能成为正式的候选推荐以供实施之前,可能会发生很多变化,因此请谨慎在实时网站上使用该属性,直到该规范被 W3C 采纳并被浏览器实施为止。

浏览器支持

Data on support for the css-anchor-positioning feature across the major browsers from caniuse.com

处理旧版浏览器支持

锚点定位是一个相对较新的 CSS 模块,它没有得到所有浏览器的完全支持,并且可能在旧版本中存在问题。 它最常见的用例是用于改进工具提示,因此可以在下面找到一个简单工具提示元素的 polyfill。 它检查是否支持锚点定位,并在我们的锚点元素下方创建一个老式工具提示。

@supports not (position-anchor: --my-anchor) {
  .target {
    display: none;
  }

  .anchor {
    position: relative;
    display: flex;
    justify-content: center;
  }

  .anchor::before {
    content: "My Target";
    position: absolute;
    top: 100%;
  }
}

更多信息和教程