anchor()
语法
/* 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(--my-anchor bottom);
inset-block-end: anchor(--my-anchor start);
/* side of named anchor with fallback */
top: anchor(--my-anchor bottom, 50%);
inset-block-end: anchor(--my-anchor start, 200px);
left: calc(anchor(--my-anchor right, 0%) + 10px);
参数
anchor() 函数的语法如下:
anchor(<anchor-name> <anchor-side>, <length-percentage>)
参数为:
<anchor-name>可选-
你希望元素的一侧相对于其定位的锚点元素的
anchor-name属性值。这是一个<dashed-ident>值。如果省略,则使用元素的默认锚点,该锚点在其position-anchor属性中引用,或通过anchorHTML 属性与元素关联。备注: 在
anchor()函数中指定<anchor-name>并不会将元素与锚点关联;它只是相对于该锚点定位元素。仍然需要使用position-anchorCSS 属性或anchorHTML 属性来创建关联。 <anchor-side>-
指定锚点的一侧,或距离
start侧的相对距离,元素将相对于该侧进行定位。如果使用的物理或逻辑值与设置anchor()的内边距属性不兼容,则会使用回退值。有效值包括:top-
锚点元素的顶部。
right-
锚点元素的右侧。
bottom-
锚点元素的底部。
left-
锚点元素的左侧。
inside-
与内边距属性相同的一侧。
outside-
与内边距属性相反的一侧。
start-
锚点元素的包含块沿设置
anchor()函数的内边距属性轴的逻辑起点。 end-
锚点元素的包含块沿设置
anchor()函数的内边距属性轴的逻辑终点。 self-start-
锚点元素的内容沿设置
anchor()函数的内边距属性轴的逻辑起点。 self-end-
锚点元素的内容沿设置
anchor()函数的内边距属性轴的逻辑终点。 center-
设置
anchor()函数的内边距属性轴的中心。 <percentage>-
以百分比形式指定距离元素内容沿设置
anchor()函数的内边距属性轴的起点的距离。
<length-percentage>可选-
指定一个回退值,当
anchor()函数因其他原因无效时,该函数应解析为此值。
返回值
返回一个 <length> 值。
描述
anchor() 函数可以相对于锚点元素的边缘定位一个元素。它仅在绝对定位或固定定位元素的内边距属性值中有效。
它返回一个 <length> 值,指定了由内边距值指定的锚点定位元素的边与由所选 <anchor-side> 值指定的锚点元素的边之间的距离。由于它返回一个 <length>,因此可以在接受长度值的其他 CSS 函数中使用,包括 calc()、clamp() 等。
如果不存在由 <anchor-name> 指定名称的锚点,或者定位元素没有与之关联的锚点(即通过 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> 值可以在物理内边距属性的值中使用。换句话说,top 和 bottom 边在 left 和 right 属性值中无效,而 left 和 right 边在 top 和 bottom 属性值中无效。例如,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> |
top 和 bottom |
top、bottom、start、end、self-start、self-end |
left 和 right |
left、right、start、end、self-start、self-end |
inset-block-start 和 inset-block-end |
start、end、self-start 和 self-end水平书写模式下的 top 和 bottom垂直书写模式下的 left 和 right |
inset-inline-start 和 inset-inline-end |
start、end、self-start 和 self-end水平书写模式下的 left 和 right垂直书写模式下的 top 和 bottom |
使用 anchor() 定位弹出框
当使用 anchor() 定位弹出框时,请注意弹出框的默认样式可能会与你试图实现的位置冲突。通常的问题是 margin 和 inset 的默认样式,因此建议重置它们:
.positionedPopover {
margin: 0;
inset: auto;
}
CSS 工作组正在寻找避免需要这种变通方法的方法。
在 calc() 中使用 anchor()
当 anchor() 函数引用默认锚点的一侧时,你可以包含一个 margin 来在锚点和定位元素的边缘之间创建所需的间距。或者,你可以在 calc() 函数中包含 anchor() 函数来添加间距。
此示例将定位元素的右边缘与锚点元素的左边缘对齐,然后添加 margin 以在边缘之间留出一些空间:
.positionedElement {
right: anchor(left);
margin-left: 10px;
}
此示例将定位元素的逻辑块末端边缘定位在距离锚点元素逻辑块起始边缘 10px 的位置:
.positionedElement {
inset-block-end: calc(anchor(start) + 10px);
}
相对于多个锚点定位元素
你可以通过在同一元素的不同内边距属性的 anchor() 函数中指定不同的 <anchor-name> 值来相对于多个锚点定位一个元素(参见下面的相对于多个锚点定位的元素)。这可以用于创建有用的功能,例如在定位元素的角上创建可用于调整其大小的拖动手柄。
虽然一个定位元素可以相对于多个锚点元素进行定位,但它只与通过其 position-anchor 属性(或 anchor HTML 属性)定义的单个锚点相关联。这是该元素在页面滚动时将随之滚动的锚点;它还可以用于控制该元素何时有条件地隐藏。
正式语法
<anchor()> =
anchor( <anchor-name>? &&
<anchor-side> , <length-percentage>? )
<anchor-name> =
<dashed-ident>
<anchor-side> =
inside |
outside |
top |
left |
right |
bottom |
start |
end |
self-start |
self-end |
<percentage> |
center
<length-percentage> =
<length> |
<percentage>
示例
常见用法
在此示例中,anchor() 函数通过将底部和顶部边缘设置为锚点的底部和顶部边缘,来将锚点定位元素的高度设置为其锚点的高度。然后,在 calc() 函数中使用 anchor() 函数来使锚点定位元素与其锚点产生偏移。
HTML
我们包含一个 <div> 元素,我们将其设置为我们的锚点,以及一个 <p> 元素,我们将相对于该锚点进行定位:
<div class="anchor">⚓︎</div>
<p class="positionedElement">This is a positioned element.</p>
CSS
我们将锚点元素的 anchor-name 值设置为定位元素的 position-anchor 属性的值以关联元素,然后在锚点定位元素上设置三个内边距属性。前两个将元素的顶部边缘与锚点的顶部边缘对齐,底部边缘与锚点的底部边缘对齐。在第三个内边距属性中,anchor() 函数在 calc() 函数中使用,以将元素的左边缘定位到锚点右边缘右侧 10px 的位置。
.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;
}
结果
不同 anchor-side 值的比较
此示例展示了一个通过其 top 和 left 属性相对于一个锚点定位的元素,这些属性是使用 anchor() 函数定义的。它还包括两个下拉菜单,允许你改变这些 anchor() 函数内的 <anchor-side> 值,这样你就可以看到它们的效果。
HTML
我们指定了两个 <div> 元素,一个带有 anchor 类,一个带有 infobox 类。它们分别用作锚点元素和我们将与之关联的定位元素。
我们还在两个 <div> 元素周围添加了一些填充文本,以使 <body> 更高,从而使其可以滚动。此示例还包括两个 <select> 元素,用于创建下拉菜单,以便选择不同的 <anchor-side> 值来放置定位元素。为简洁起见,我们隐藏了填充文本和 <select> 元素。
<div class="anchor">⚓︎</div>
<div class="infobox">
<p>This is an information box.</p>
</div>
CSS
我们通过 anchor-name 属性在其上设置一个锚点名称,将 anchor <div> 声明为锚点元素。然后,我们通过为其 position-anchor 属性设置相同的值,将其与定位元素关联。top: anchor(--my-anchor bottom) 将信息框的顶部边缘与其锚点的底部边缘对齐,而 left: anchor(right) 将信息框的左边缘与其锚点的右边缘对齐。这提供了一个初始位置,当从下拉菜单中选择不同值时,该位置将被覆盖。
.anchor {
anchor-name: --my-anchor;
}
.infobox {
position: fixed;
position-anchor: --my-anchor;
top: anchor(--my-anchor bottom);
left: anchor(right);
}
JavaScript
我们监听选择新的 <anchor-side> 值时发生的 change 事件,并将所选值设置为信息框相关内边距属性(top 或 left)值中 anchor() 函数内的 <anchor-side>。
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(--my-anchor ${anchorSide})`;
});
leftSelect.addEventListener("change", (e) => {
const anchorSide = e.target.value;
infobox.style.left = `anchor(${anchorSide})`;
});
结果
从下拉菜单中选择不同的值,看看它们如何影响信息框的定位。
相对于多个锚点定位的元素
此示例将一个元素相对于两个不同的锚点进行定位,这两个锚点用于设置锚点定位元素的左上角和右下角的位置。这些锚点可以通过键盘控制或拖动来移动,从而调整定位元素的大小。
HTML
我们总共指定了三个 <div> 元素。前两个带有 anchor 类,将被定义为锚点;每个都有一个单独的 id,用于为它们提供不同的定位信息。最后一个 <div> 带有 infobox 类,将被定义为定位元素。我们包含 tabindex 属性,以使它们能够接收键盘焦点。
<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,以及不同的内边距值,以将锚点定位成一个矩形。
.anchor {
position: absolute;
}
#anchor1 {
anchor-name: --my-anchor1;
top: 50px;
left: 100px;
}
#anchor2 {
anchor-name: --my-anchor2;
top: 200px;
left: 350px;
}
锚点定位元素的 position 设置为 fixed,通过其 position-anchor 属性与一个锚点相关联。通过在其内边距属性上设置的 anchor() 函数中包含两个不同的 <anchor-name> 值,它相对于两个锚点进行定位。在这种情况下,我们为 <anchor-side> 参数使用了<percentage> 值,指定了从函数设置的内边距属性轴的起点开始的距离。
.infobox {
position-anchor: --my-anchor1;
position: fixed;
top: anchor(--my-anchor1 100%);
left: anchor(--my-anchor1 100%);
bottom: anchor(--my-anchor2 0%);
right: anchor(--my-anchor2 0%);
}
结果
定位元素相对于两个锚点元素进行定位。用鼠标拖动它们,或者按 Tab 键切换到它们,然后使用 W、A、S 和 D 键向上、下、左、右移动它们。看看这如何改变它们的位置,以及因此改变定位元素的区域。滚动页面,看看所有元素的位置是如何保持的。
注意: 此示例是一个概念验证,不适用于生产代码。其缺点之一是,如果你试图将锚点水平或垂直地移动过彼此,示例就会中断。
规范
| 规范 |
|---|
| CSS 锚点定位 # anchor-pos |
浏览器兼容性
加载中…