CSS锚点定位功能想必您已有所耳闻,对吧?这项功能允许您将页面上的任何元素链接到另一个元素,即锚点。它对所有工具提示都非常有用,但也能创造许多其他不错的效果。
本文将研究菜单导航,我依靠锚点定位在链接上创建出色的悬停效果。
很酷,对吧?我们有一个滑动效果,蓝色矩形通过流畅的过渡完美地适应文本内容。如果您不熟悉锚点定位,此示例非常适合您,因为它很简单,可以让您了解这项新功能的基础知识。我们还将学习另一个示例,所以请坚持到最后!
请注意,在我撰写本文时,只有基于Chromium的浏览器完全支持锚点定位。在其他浏览器更广泛地支持此功能之前,您需要在Chrome或Edge等浏览器中查看演示。
让我们从HTML结构开始,它只是一个包含无序链接列表的nav元素:
<nav><ul> <li><a href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">Home</a></li> <li><a href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">About</a></li> <li><a href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">Projects</a></li> <li><a href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">Blog</a></li> <li><a href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">Contact</a></li> </ul></nav>
我们不会花太多时间解释这个结构,因为如果您的用例不同,它也可能不同。只需确保语义与您尝试执行的操作相关即可。至于CSS部分,我们将从一些基本样式开始,以创建水平菜单导航。
ul { padding: 0; margin: 0; list-style: none; display: flex; gap: .5rem; font-size: 2.2rem; } ul li a { color: https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b000; text-decoration: none; font-weight: 900; line-height: 1.5; padding-inline: .2em; display: block; }
到目前为止,没有什么特别的。我们删除了一些默认样式并使用Flexbox将元素水平对齐。
首先,让我们了解效果的工作原理。乍一看,似乎我们有一个矩形,它缩小到很小的高度,移动到悬停的元素,然后增长到全高。这就是视觉效果,但实际上,涉及多个元素!
这是我的第一个演示,我使用不同的颜色来更好地了解正在发生的事情。
每个菜单项都有其自己的“元素”可以收缩或增长。然后我们有一个公共“元素”(红色的那个),它在不同的菜单项之间滑动。第一个效果是使用背景动画完成的,第二个效果是锚点定位发挥作用的地方!
对于第一部分,我们将动画化CSS渐变的高度:
/* 1 */ ul li { background: conic-gradient(lightblue 0 0) bottom/100% 0% no-repeat; transition: .2s; } /* 2 */ ul li:is(:hover,.active) { background-size: 100% 100%; transition: .2s .2s; } /* 3 */ ul:has(li:hover) li.active:not(:hover) { background-size: 100% 0%; transition: .2s; }
我们定义了一个宽度为100%,高度为0%的渐变,位于底部。渐变语法可能看起来很奇怪,但它是允许我拥有单色渐变的最短语法。
相关:“如何正确定义单色渐变”
然后,如果菜单项被悬停或具有.active类,我们将高度设置为100%。请注意此处延迟的使用,以确保增长发生在收缩之后。
最后,我们需要处理.active项的特殊情况。如果我们悬停任何项(不是活动项),则.active项会获得收缩效果(渐变高度等于0%)。这就是代码中第三个选择器的作用。
我们的第一个动画完成了!请注意,由于我们在第二个选择器中定义的延迟,增长是如何在收缩完成之后开始的。
第一个动画非常容易,因为每个项目都有自己的背景动画,这意味着我们不必关心文本内容,因为背景会自动填充整个空间。
我们将使用一个元素进行第二个动画,该元素在所有菜单项之间滑动,同时调整其宽度以适应每个项目的文本。这就是锚点定位可以帮助我们的地方。
让我们从以下代码开始:
<nav><ul> <li><a href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">Home</a></li> <li><a href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">About</a></li> <li><a href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">Projects</a></li> <li><a href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">Blog</a></li> <li><a href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">Contact</a></li> </ul></nav>
为了避免添加额外的元素,我更喜欢在ul上使用伪元素。它应该是绝对定位的,我们将依靠两个属性来激活锚点定位。
我们使用anchor-name属性定义锚点。当菜单项被悬停或具有.active类时,它将成为锚元素。如果另一个项目处于悬停状态,我们还必须从.active项目中删除锚点(因此,代码中的最后一个选择器)。换句话说,一次只定义一个锚点。
然后我们使用position-anchor属性将伪元素链接到锚点。请注意两者如何使用相同的表示法--li。这类似于例如,我们如何使用特定名称定义@keyframes,然后在animation属性中使用它。请记住,您必须使用
伪元素已正确放置,但什么也看不见,因为我们没有定义任何维度!让我们添加以下代码:
ul { padding: 0; margin: 0; list-style: none; display: flex; gap: .5rem; font-size: 2.2rem; } ul li a { color: https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b000; text-decoration: none; font-weight: 900; line-height: 1.5; padding-inline: .2em; display: block; }
height属性很简单,但anchor()是新成员。以下是Juan Diego在Almanac中对其的描述:
CSS anchor()函数获取锚元素的一侧并解析为其定位的
。它只能用于内嵌属性(例如top、bottom、bottom、left、right等),通常用于相对于锚点放置绝对定位的元素。
让我们也查看MDN页面:
anchor() CSS 函数可以在锚定位元素的内嵌属性值中使用,返回相对于其关联锚元素边缘位置的长度值。
通常,我们使用left: 0将绝对元素放置在其包含块(即具有position: relative的最近祖先)的左边缘。left: anchor(left)将执行相同的操作,但它将考虑关联的锚元素,而不是包含块。
就是这样——我们完成了!在下面的演示中悬停菜单项,看看伪元素是如何在它们之间滑动的。
每次您将鼠标悬停在菜单项上时,它都会成为伪元素(ul:before)的新锚点。这也意味着anchor(...)值将发生变化,从而产生滑动效果!让我们不要忘记使用transition,否则我们将有一个突然的变化。
我们也可以这样编写代码:
<nav><ul> <li><a href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">Home</a></li> <li><a href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">About</a></li> <li><a href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">Projects</a></li> <li><a href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">Blog</a></li> <li><a href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">Contact</a></li> </ul></nav>
换句话说,我们可以依靠inset简写,而不是使用left、right和bottom等物理属性,并且代替定义position-anchor,我们可以在anchor()函数中包含锚点的名称。我们在这里重复了三次相同的名称,这可能不是最佳选择,但在某些情况下,您可能希望您的元素考虑多个锚点,在这种情况下,此语法将很有意义。
现在,我们将两种效果结合起来,瞧,幻觉完美了!
请注意transition值,其中延迟很重要:
ul { padding: 0; margin: 0; list-style: none; display: flex; gap: .5rem; font-size: 2.2rem; } ul li a { color: https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b000; text-decoration: none; font-weight: 900; line-height: 1.5; padding-inline: .2em; display: block; }
我们有一系列三个动画——缩小渐变的高度、滑动伪元素和增大渐变的高度——因此我们需要在它们之间设置延迟才能将所有内容组合在一起。这就是为什么对于伪元素的滑动,我们有一个等于一个动画持续时间的延迟(transition: .2 .2s),而对于增长部分,延迟等于持续时间的两倍(transition: .2s .4s)。
让我们尝试另一个奇特的动画,其中高亮矩形变形为一个小圆圈,跳到下一个项目,然后再次变形回矩形!
我不会过多解释这个例子,因为这是你剖析代码的作业!我将提供一些提示,以便您可以解包正在发生的事情。
与之前的效果一样,我们结合了两个动画。对于第一个,我将使用每个菜单项的伪元素,我将调整尺寸和border-radius来模拟变形。对于第二个动画,我将使用ul伪元素创建一个小的圆圈,我将它移动到菜单项之间。
这是另一个版本的演示,颜色不同,过渡速度较慢,以便更好地可视化每个动画:
棘手的部分是跳跃效果,我使用了一个奇怪的cubic-bezier(),但我有一篇详细的文章在我的CSS-Tricks文章“使用cubic-bezier()的先进CSS动画”中解释了这种技术。
我希望您喜欢使用锚点定位功能进行的这个小实验。我们只查看了三个属性/值,但这足以让您准备好使用这项新功能。anchor-name和position-anchor属性是将一个元素(在此上下文中通常称为“目标”元素)链接到另一个元素(在此上下文中我们称为“锚”元素)的强制性部分。从那里,您可以使用anchor()函数来控制位置。
相关:CSS锚点定位指南
以上是使用锚定位的花式菜单导航的详细内容。更多信息请关注PHP中文网其他相关文章!