anchor()

有限可用性

此功能不是基线,因为它在一些最广泛使用的浏览器中不起作用。

实验性: 这是一个 实验性技术
在生产环境中使用此功能之前,请仔细查看 浏览器兼容性表格

anchor() CSS 函数 可在锚点定位元素的 内边距属性 值中使用,返回相对于其关联锚点元素边缘位置的长度值。

语法

css
/* side or percentage */
top: anchor(bottom);
top: anchor(50%);
top: calc(anchor(bottom) + 10px)
inset-block-end: anchor(start);

/* side of named anchor */
top: anchor(--myAnchor bottom);
inset-block-end: anchor(--myAnchor start);

/* side of named anchor with fallback */
top: anchor(--myAnchor bottom, 50%);
inset-block-end: anchor(--myAnchor start, 200px);
left: calc(anchor(--myAnchor right, 0%) + 10px);

参数

anchor() 函数的语法如下

anchor(<anchor-element> <anchor-side>, <length-percentage>)

参数为

<anchor-element> 可选

您希望将元素的边相对于其定位的锚点元素的 anchor-name 属性值。这是一个 <dashed-ident> 值。如果省略,则使用元素的默认锚点,该锚点在其 position-anchor 属性中引用,或通过 anchor HTML 属性与元素关联。

注意:anchor() 函数内指定 <anchor-element> 不会将元素与锚点关联;它只是将元素相对于该锚点定位。仍然需要 position-anchor CSS 属性或 anchor HTML 属性来创建关联。

<anchor-side>

指定锚点的边,或元素相对于其定位的 start 边的相对距离。如果使用与设置 anchor() 函数的内边距属性不 兼容 的物理或逻辑值,则使用回退值。有效值包括

top

锚点元素的顶部。

锚点元素的右侧。

bottom

锚点元素的底部。

left

锚点元素的左侧

start

锚点元素的 包含块 在设置 anchor() 函数的内边距属性轴上的逻辑起点。

end

锚点元素的包含块在设置 anchor() 函数的内边距属性轴上的逻辑终点。

self-start

锚点元素的内容在设置 anchor() 函数的内边距属性轴上的逻辑起点。

self-end

锚点元素的内容在设置 anchor() 函数的内边距属性轴上的逻辑终点。

center

设置 anchor() 函数的内边距属性轴的中心。

<percentage>

指定从元素内容在设置 anchor() 函数的内边距属性轴上的起点开始的距离,以百分比表示。

CSS 锚点定位模块引入了两个额外的 <anchor-side> 值,insideoutside,但尚未实施。

<length-percentage> 可选

指定如果 anchor() 函数在其他情况下无效,则函数应解析到的回退值。

返回值

返回一个 <length> 值。

描述

anchor() 函数允许元素相对于锚点元素的边进行定位。它只在设置在绝对或固定定位元素上的 内边距属性 值内有效。

它返回一个 <length> 值,指定由内边距值指定的锚点定位元素边与由所选 <anchor-side> 值指定的锚点元素边之间的距离。因为它返回一个 <length>,所以它可以在接受长度值的 其他 CSS 函数 中使用,包括 calc()clamp() 等。

如果没有名为 <anchor-element> 的锚点存在,或者如果定位元素没有与它关联的锚点(例如,通过 position-anchor 属性),则第一个参数被认为无效,如果存在回退 <length-percentage> 值,则使用它。例如,如果在定位元素上指定了 top: anchor(bottom, 50px),但没有与它关联的锚点,则将使用回退值,因此 top 将获得 50px 的计算值。

有关锚点功能和用法的详细信息,请参见 CSS 锚点定位 模块着陆页和 使用 CSS 锚点定位 指南。

接受 anchor() 函数值的属性

接受 anchor() 函数作为值组件的 CSS 内边距属性 包括

内边距属性和 <anchor-side> 值的兼容性

在内边距属性值内使用 anchor() 函数时,在 anchor() 函数内指定的 <anchor-side> 参数必须与内边距属性所在的轴兼容。

这意味着如果属性与 <anchor-side> 具有相同的轴方向,则可以在物理内边距属性的值内使用物理 <anchor-side> 值。换句话说,topbottom 边在 leftright 属性值内无效,leftright 边在 topbottom 属性值内无效。例如,top: anchor(bottom) 是可以的,因为它们都是垂直值,但 top: anchor(left) 无效,因为 left 是水平值。如果指定了 top: anchor(left, 50px),则将使用回退值,因此 top 将获得 50px 的计算值。如果不存在回退,则内边距属性的行为就像设置为 auto 一样。

您可以在逻辑和物理内边距属性内使用逻辑 <anchor-side> 值,因为逻辑 <anchor-side> 值相对于内边距属性的相关轴,无论属性是逻辑还是相对。例如,top: anchor(start)top: anchor(self-end)inset-block-start: anchor(end)inset-inline-end: anchor(self-start) 都可以正常工作。

在逻辑内边距属性值内使用物理 <anchor-side> 参数时,情况会变得更加复杂,因为物理边必须与当前书写模式下内边距属性相关的轴匹配。例如

  • 在水平书写模式下,块方向为从上到下,因此 inset-block-end: anchor(bottom) 将起作用,但 inset-block-end: anchor(left) 不兼容。如果设置了 inset-block-end: anchor(left, 50px),则计算值为 50px,并且定位元素将从其最近的定位祖先或视窗的块末尾(底部)定位 50px,具体取决于设置的 position 值。
  • 在垂直书写模式下,块方向为从右到左或从左到右,因此 inset-block-end: anchor(left) 将起作用,但 inset-block-end: anchor(top) 不兼容。如果设置了 inset-block-end: anchor(top, 50px),则计算值为 50px,并且定位元素将从其最近的定位祖先或视窗的块末尾(左或右,具体取决于书写模式)定位 50px,具体取决于设置的 position 值。

为了减轻使用这些值可能造成的混淆,建议您在逻辑 <anchor-side> 值内使用逻辑内边距属性,在物理 <anchor-side> 值内使用物理内边距属性。您应该尽可能使用逻辑值,因为它们更适合 国际化

center<percentage> 值在所有逻辑和物理内边距属性内的 anchor() 函数内有效。

下表列出了内边距属性以及与它们兼容的 <anchor-side> 参数值。我们只列出了长内边距属性;它们包括简写内边距属性值。

内边距属性 兼容的 <anchor-side>
所有 center
所有 <percentage>
topbottom topbottomstartendself-startself-end
leftright leftrightstartendself-startself-end
inset-block-startinset-block-end startendself-startself-end
水平书写模式下的 topbottom
垂直书写模式下的 leftright
inset-inline-startinset-inline-end startendself-startself-end
水平书写模式下的 leftright
垂直书写模式下的 topbottom

calc() 内使用 anchor()

anchor() 函数引用默认锚点的边时,您可以包含一个 margin,以便在锚点和定位元素的边缘之间创建必要的间距。或者,您可以在一个 calc() 函数内包含 anchor() 函数以添加间距。

此示例将定位元素的右边缘与锚点元素的左边缘对齐,然后添加边距以在边缘之间留出一些空间

css
.positionedElement {
  right: anchor(left);
  margin-left: 10px;
}

此示例将定位元素的逻辑块结束边缘从锚点元素的逻辑块开始边缘定位 10px

css
.positionedElement {
  inset-block-end: calc(anchor(start) + 10px);
}

相对于多个锚点定位元素

您可以通过在同一元素的不同内边距属性的 anchor() 函数内指定不同的 <anchor-element> 名称来相对于多个锚点定位元素(请参见下面的 相对于多个锚点定位的元素)。这可以用来创建有用的功能,例如定位元素角落处的拖动句柄,这些句柄可用于调整元素的大小。

虽然定位元素可以相对于多个锚点元素定位,但它始终只与通过其 position-anchor 属性(或 anchor HTML 属性)定义的单个锚点相关联。这是元素在页面滚动时将与之一起滚动的锚点;它还可以用于控制何时 有条件地隐藏 元素。

正式语法

<anchor()> = 
anchor( <anchor-element>? &&
<anchor-side> , <length-percentage>? )

<anchor-element> =
<dashed-ident>

<anchor-side> =
inside |
outside |
top |
left |
right |
bottom |
start |
end |
self-start |
self-end |
<percentage> |
center

<length-percentage> =
<length> |
<percentage>

示例

常见用法

在此示例中,anchor() 函数用于通过将底部和顶部边缘设置为锚点的底部和顶部边缘,将锚点定位元素的高度设置为其锚点的高度。然后,anchor() 函数在 calc() 函数内使用,以将锚点定位元素从其锚点偏移。

HTML

我们包含一个 <div> 元素,我们将将其设置为我们的锚点,以及一个 <p>,我们将相对于该锚点进行定位

html
<div class="anchor">⚓︎</div>

<p class="positionedElement">This is a positioned element.</p>

CSS

我们将锚点元素的 anchor-name 值设置为定位元素的 position-anchor 属性的值,以关联元素,然后在锚点定位元素上设置三个内边距属性。前两个将元素的顶部边缘与锚点的顶部边缘对齐,底部边缘与锚点的底部边缘对齐。在第三个内边距属性中,anchor() 函数在 calc() 函数内使用,以将元素的左边缘与锚点的右边缘定位 10px

css
.anchor {
  anchor-name: --infobox;
  background: palegoldenrod;
  font-size: 3em;
  width: fit-content;
  border: 1px solid goldenrod;
}

.positionedElement {
  position: absolute;
  position-anchor: --infobox;
  margin: 0;
  top: anchor(top);
  left: calc(anchor(right) + 10px);
  bottom: anchor(bottom);
  background-color: olive;
  border: 1px solid darkolivegreen;
}

结果

不同锚点边值的比较

此示例显示一个元素通过其 topleft 属性相对于锚点定位,这些属性是使用 anchor() 函数定义的。它还包括两个下拉菜单,允许您改变这些 anchor() 函数内的 <anchor-side> 值,这样您就可以看到它们的影响。

HTML

我们指定了两个 <div> 元素,一个具有 anchor 类,另一个具有 infobox 类。它们分别用于作为锚点元素和我们将与其关联的定位元素。

我们还在两个 <div> 元素周围包含一些填充文本,以使 <body> 更高,以便它可以滚动。此示例还包含两个 <select> 元素,用于创建下拉菜单,允许选择不同的 <anchor-side> 值来放置定位元素。为了简洁起见,我们隐藏了填充文本和 <select> 元素。

html
<div class="anchor">⚓︎</div>

<div class="infobox">
  <p>This is an information box.</p>
</div>

CSS

我们通过在 anchor-name 属性中设置锚点名称来将 anchor <div> 声明为锚点元素。然后,我们通过在其 position-anchor 属性中设置相同的值来将其与定位元素关联。top: anchor(--myAnchor bottom) 将信息框的顶部边缘与锚点的底部边缘对齐,而 left: anchor(right) 将信息框的左边缘与锚点的右边缘对齐。这提供了将被从下拉菜单中选择不同的值覆盖的初始位置。

css
.anchor {
  anchor-name: --myAnchor;
}

.infobox {
  position: fixed;
  position-anchor: --myAnchor;
  top: anchor(--myAnchor bottom);
  left: anchor(right);
}

JavaScript

我们监听在选择新的 <anchor-side> 值时发生的 change 事件,并将所选值设置为信息框的相关内边距属性(topleft)值内的 anchor() 函数中的 <anchor-side>

js
const infobox = document.querySelector(".infobox");
const topSelect = document.querySelector("#top-anchor-side");
const leftSelect = document.querySelector("#left-anchor-side");

topSelect.addEventListener("change", (e) => {
  const anchorSide = e.target.value;
  infobox.style.top = `anchor(--myAnchor ${anchorSide})`;
});

leftSelect.addEventListener("change", (e) => {
  const anchorSide = e.target.value;
  infobox.style.left = `anchor(${anchorSide})`;
});

结果

从下拉菜单中选择不同的值,以查看它们如何影响信息框的定位。

相对于多个锚点定位的元素

此示例将元素相对于两个不同的锚点定位,这两个锚点用于设置锚点定位元素的左上角和右下角的位置。锚点可以通过键盘控制或拖动来移动,从而调整定位元素的大小。

HTML

我们总共指定了三个 <div> 元素。前两个具有 anchor 类,并将被定义为锚点;每个锚点都有一个单独的 id,用于为它们提供不同的定位信息。最后一个 <div> 具有 infobox 类,并将被定义为定位元素。我们包括 tabindex 属性,以使它们能够接收键盘焦点。

html
<div id="anchor1" class="anchor" tabindex="0">⚓︎1</div>

<div id="anchor2" class="anchor" tabindex="0">⚓︎2</div>

<div class="infobox">
  <p>This is an information box.</p>
</div>

CSS

每个锚点都赋予了不同的 anchor-name 值,position 值为 absolute,以及不同的内边距值,以将锚点定位在矩形形状中。

css
.anchor {
  position: absolute;
}

#anchor1 {
  anchor-name: --myAnchor1;
  top: 50px;
  left: 100px;
}

#anchor2 {
  anchor-name: --myAnchor2;
  top: 200px;
  left: 350px;
}

具有 position 属性设置为 fixed 的锚点定位元素,通过其 position-anchor 属性与一个锚点关联。它通过在内边距属性上设置两个不同的 <anchor-name> 值,并使用 anchor() 函数,相对于两个锚点进行定位。在本例中,我们使用 <percentage> 值作为 <anchor-side> 参数,指定距离设置函数的内边距轴起点的位置。

css
.infobox {
  position-anchor: --myAnchor1;
  position: fixed;
  top: anchor(--myAnchor1 100%);
  left: anchor(--myAnchor1 100%);
  bottom: anchor(--myAnchor2 0%);
  right: anchor(--myAnchor2 0%);
}

结果

定位元素相对于两个锚点元素进行定位。使用鼠标或 Tab 键拖动它们,并使用 WASD 键向上、向下、向左和向右移动它们。观察这将如何改变它们的位置,以及定位元素区域的变化。滚动以查看所有元素的位置如何保持不变。

注意: 此示例是一个概念验证,不建议在生产代码中使用。在它的缺点中,如果你尝试将锚点水平或垂直移动到彼此的过去,示例将被破坏。

规范

规范
CSS 锚点定位
# anchor-pos

浏览器兼容性

BCD 表格只在启用 JavaScript 的浏览器中加载。

另请参阅