CSS Anchor Positioning 实战
CSS Anchor Positioning API 让元素可以相对于其他元素定位,不再需要 JavaScript 计算位置。
基础概念
/* 定义锚点 */
.anchor {
anchor-name: --my-anchor;
}
/* 相对于锚点定位 */
.tooltip {
position: absolute;
position-anchor: --my-anchor;
top: anchor(bottom);
left: anchor(center);
}
实际案例:Tooltip
<button class="btn">
Hover me
<span class="tooltip">Tooltip content</span>
</button>
.btn {
position: relative;
anchor-name: --btn-anchor;
}
.tooltip {
position: absolute;
position-anchor: --btn-anchor;
/* 定位在锚点下方 */
top: anchor(bottom);
left: anchor(center);
transform: translateX(-50%);
/* 间距 */
margin-top: 8px;
/* 样式 */
background: #333;
color: white;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
/* 默认隐藏 */
opacity: 0;
pointer-events: none;
transition: opacity 0.2s;
}
.btn:hover .tooltip {
opacity: 1;
}
下拉菜单
<div class="dropdown">
<button class="dropdown-trigger">
Menu
</button>
<div class="dropdown-menu">
<a href="#">Option 1</a>
<a href="#">Option 2</a>
<a href="#">Option 3</a>
</div>
</div>
.dropdown-trigger {
anchor-name: --dropdown-anchor;
}
.dropdown-menu {
position: absolute;
position-anchor: --dropdown-anchor;
top: anchor(bottom);
left: anchor(left);
margin-top: 4px;
background: white;
border: 1px solid #ddd;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
/* 默认隐藏 */
display: none;
}
.dropdown:focus-within .dropdown-menu {
display: block;
}
锚点定位函数
anchor() 函数支持多种值:
.positioned {
/* 相对于锚点的边 */
top: anchor(top);
right: anchor(right);
bottom: anchor(bottom);
left: anchor(left);
/* 相对于锚点的中心 */
top: anchor(center);
left: anchor(center);
/* 组合 */
top: anchor(bottom); /* 在锚点下方 */
left: anchor(center); /* 水平居中 */
/* 计算值 */
top: calc(anchor(bottom) + 8px);
}
边界处理
position-try-fallbacks 处理空间不足的情况:
.tooltip {
position: absolute;
position-anchor: --anchor;
/* 默认在下方 */
top: anchor(bottom);
left: anchor(center);
/* 空间不足时尝试其他位置 */
position-try-fallbacks:
flip-block, /* 上下翻转 */
flip-inline, /* 左右翻转 */
flip-block flip-inline;
/* 或自定义 */
position-try-fallbacks:
--top-position,
--right-position;
}
@position-try --top-position {
top: anchor(top);
bottom: auto;
}
@position-try --right-position {
left: anchor(right);
right: auto;
}
弹出层
配合 Popover API:
<button popovertarget="menu" class="trigger">
Open Menu
</button>
<div id="menu" popover class="menu">
<a href="#">Item 1</a>
<a href="#">Item 2</a>
</div>
.trigger {
anchor-name: --trigger-anchor;
}
.menu {
position-anchor: --trigger-anchor;
top: anchor(bottom);
left: anchor(left);
}
居中对话框
.dialog-trigger {
anchor-name: --dialog-anchor;
}
.dialog {
position: fixed;
position-anchor: --dialog-anchor;
/* 居中 */
top: anchor(center);
left: anchor(center);
transform: translate(-50%, -50%);
/* 或使用 inset-area */
inset-area: center;
}
浏览器支持
| 浏览器 | 版本 |
|---|---|
| Chrome | 125+ |
| Edge | 125+ |
| Safari | 实验性 |
| Firefox | 实验性 |
兼容性检测:
@supports (position-anchor: --test) {
/* 支持 Anchor Positioning */
}
// JS 检测
if (CSS.supports('position-anchor', '--test')) {
// 支持
} else {
// 降级方案
}
降级方案
.tooltip {
/* 降级:相对于直接父元素 */
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
}
@supports (position-anchor: --test) {
.trigger {
anchor-name: --trigger-anchor;
}
.tooltip {
position-anchor: --trigger-anchor;
top: anchor(bottom);
left: anchor(center);
}
}
小结
CSS Anchor Positioning 的优势:
- 无需 JavaScript 计算位置
- 自动处理边界情况
- 与 Popover API 配合好
- 性能更好
适合场景:
- Tooltip
- 下拉菜单
- 弹出层
- 拖拽辅助
2024 年底开始在 Chrome 中可用,可以作为渐进增强方案。
CSS
返回首页