假设您想移动一个元素 在 :hover
上,以获得有趣的视觉效果。
@media (hover: hover) {
.list--item {
transition: 0.1s;
transform: translateY(10px);
}
.list--item:hover,
.list--item:focus {
transform: translateY(0);
}
}
不错。但是,如果您有多个列表项,并且您希望它们在悬停时都移动,但每个列表项的计时都交错呢?
诀窍在于 transition-delay
,并为每个项目应用略微不同的延迟。让我们分别选择每个列表项并应用不同的延迟。在本例中,我们将选择一个内部跨度只是为了好玩。
@media (hover: hover) {
.list li a span {
transform: translateY(100px);
transition: 0.2s;
}
.list:hover span {
transform: translateY(0);
}
.list li:nth-child(1) span {
transition-delay: 0.0s;
}
.list li:nth-child(2) span {
transition-delay: 0.05s;
}
.list li:nth-child(3) span {
transition-delay: 0.1s;
}
.list li:nth-child(4) span {
transition-delay: 0.15s;
}
.list li:nth-child(5) span {
transition-delay: 0.2s;
}
.list li:nth-child(6) span {
transition-delay: 0.25s;
}
}
查看 Pen
交错动画,作者为 Chris Coyier (@chriscoyier)
在 CodePen 上。
如果您想获得更多可编程控制,可以将延迟设置为 CSS 自定义属性
@media (hover: hover) {
.list {
--delay: 0.05s;
}
.list li a span {
transform: translateY(100px);
transition: 0.2s;
}
.list:hover span {
transform: translateY(0);
}
.list li:nth-child(1) span {
transition-delay: calc(var(--delay) * 0);
}
.list li:nth-child(2) span {
transition-delay: calc(var(--delay) * 1);
}
.list li:nth-child(3) span {
transition-delay: calc(var(--delay) * 2);
}
.list li:nth-child(4) span {
transition-delay: calc(var(--delay) * 3);
}
.list li:nth-child(5) span {
transition-delay: calc(var(--delay) * 4);
}
.list li:nth-child(6) span {
transition-delay: calc(var(--delay) * 5);
}
}
这可能有点挑剔,不合您的口味。假设您的列表开始增长,可能达到七个或更多项目。由于这不能容纳那么多列表项,所以交错突然在新的项目上不起作用。
如果您愿意,可以从 HTML 中传递延迟
<ul class="list">
<li><a href="#0" style="--delay: 0.00s;">① <span>This</span></a></li>
<li><a href="#0" style="--delay: 0.05s;">② <span>Little</span></a></li>
<li><a href="#0" style="--delay: 0.10s;">③ <span>Piggy</span></a></li>
<li><a href="#0" style="--delay: 0.15s;">④ <span>Went</span></a></li>
<li><a href="#0" style="--delay: 0.20s;">⑤ <span>To</span></a></li>
<li><a href="#0" style="--delay: 0.25s;">⑥ <span>Market</span></a></li>
</ul>
@media (hover: hover) {
.list li a span {
transform: translateY(100px);
transition: 0.2s;
}
.list:hover span {
transform: translateY(0);
transition-delay: var(--delay); /* comes from HTML */
}
}
或者,如果您倾向于使用 Sass,可以创建循环,其项目数超过您目前需要的项目数(知道多余的代码将非常有效地进行 gzip 压缩)
@media (hover: hover) {
/* base hover styles from above */
@for $i from 0 through 20 {
.list li:nth-child(#{$i + 1}) span {
transition-delay: 0.05s * $i;
}
}
}
这无论您是否选择循环次数超过需要,都可能很有用。
我更喜欢 Sass 版本,因为我在很多不同的东西中都使用过它,我在 codepen 中创建了一个单色主题生成器以及其他一些简单的交错效果。它确实创建了很多 nth 子节点,即使我还没有利用 CSS 变量。
在生产环境中,可以说 CSS 和 HTML 技术在更大规模上更容易控制,即使它将延迟放在了(很可能)单独的文档中。
看起来在 CSS 规范中实现索引并不困难。Nth-child 但可以在 calc 中使用。li 可能知道 ul/ol 中有多少项在它之前。
.list-item:nth-child(index) span {
transition-delay: calc(index + var(–delay));
}
我想在实现之前,SASS 是首选,或者 JS。
Apple 移动网站菜单是这种效果的一个很好的例子。他们已经从以前的样子稍微调整了一下,但您仍然可以看出打开/关闭时的交错淡入淡出效果。
快速悬停和取消悬停该 codepen 很酷!
今天我了解了
@media (hover: hover)
,它测试设备的主要输入机制是否可以悬停在元素上。感谢您!为什么 CSS-Tricks 经常使用列表项来表示并非列表项的事物,就像在本例中一样?我认为这只会让事情变得有点难以理解、难以阅读,并且与语义的大局观相冲突。
我问另一位设计师他为什么这样做,他说:“因为 WordPress 这样做。” 就我个人而言,我认为 WordPress 代码是一团糟,您永远不应该模仿它,但我又知道什么呢?
这是为了复制一些导航,就像旧的 CSS-Tricks 设计一样,并且 导航应该在列表中.
我甚至不知道该如何回应。WordPress,什么,自动将所有标记放到列表中?在哪里?如何?这里到底发生了什么?
我不确定我是否正确理解了对 WordPress 的引用,但这是使用列表的情况,因为它实际上是单词列表,而不是句子,不应以这种方式阅读。
我认为 Texxs 这里争论的本质是“导航不是列表”论点,只是可能更广泛。这将使 WordPress 代码部分更有意义,因为 WordPress 默认情况下会将其导航输出为列表。
尽管如此……这是一场永远不会结束的古老战斗。如果这是一个 Stack Overflow 问题,它将被关闭,因为任何答案都是“主要基于意见”
使用列表项作为您的导航非常有用。CSS tricks 在 2013 年发表了一篇文章, https://css-tricks.org.cn/navigation-in-lists-to-be-or-not-to-be/
这与使用 WordPress 无关。列表清楚地传达导航层次结构。而且它们对屏幕阅读器很有用。更多信息在这里: https://www.w3.org/TR/2008/WD-WCAG20-TECHS-20081103/H50 以及上面列出的文章
如果有人无法解释他们为什么使用某些东西,而他们唯一的解释是“仅仅因为 WP 这样做”,那就不好了。
但在这种情况下,使用列表是合理的。这个例子是单词列表,设计也显示了一些通常是菜单的东西,而菜单通常是列表,因为它实际上是条目列表。有道理。
这似乎非常适合以下内容:
transition-delay: calc(0.05 * attr(data-delay));
您从其中提取属性
<span data-delay="1">...</span>
这……根据
calc()
,我们应该能够做到,但我猜想,自从 5 年多前达成协议以来,还没有浏览器开发人员真正开始添加支持。当我看到自定义属性的使用时,我本以为会传递索引而不是延迟
<span style="--index: 1">...</span>
然后在 css 中使用它
transition-delay: calc(var(--delay) * var(--index));
同意!我迫不及待地等待它落地。
公平地讲,对于浏览器来说,这目前无法工作的原因不是
calc()
规范。attr()
函数受到 CSS 级别 2 规范的严格限制,它只能用于content
属性,并且引用的值始终以<string>
返回。随着即将在 CSS 值 3 中的更改,您将能够为
attr()
指定<type-or-unit>
和<fallback>
参数。因此,您的示例将变为非常酷,容易理解。感谢分享!
Chris,我喜欢这篇文章中的想法。这让我思考:使用一点点 Javascript 动态添加索引 CSS 自定义属性有多容易?
事实证明,这相对简单:我在此处分叉了笔: https://codepen.io/kbav/pen/gOYMYJm
接下来,我想用变异观察器来玩玩,看看是否可以解决动态列表添加/删除/过滤/排序等问题,因为自定义属性的顺序将不再映射到它们的“真实”索引。
顺便说一句,如果
:nth-child(n)
选择器允许在calc()
中重复使用n
,那不是太棒了吗?:)