您看过 Netlify 的新闻页面吗?那里是您可以获取公司徽标下载的地方之一。我今天早上正在寻找它,因为我需要该徽标作为 CSS-Tricks 上一篇文章的特色图片。
好吧,我注意到他们有一些漂亮的按钮可以下载徽标。它们小巧而锐利。它们吸引了注意力,但又不碍事。
它们还是交互式的!看看它们在悬停时如何展开并显示“下载”字样。
不错,对吧?!我实际上注意到它们在 Safari 中看起来有点偏离。

这让我很好奇它们是如何制作的。因此,我在清理一些间距内容的同时,在这里重新创建了它们作为演示。
查看 CodePen 上 Geoff Graham (@geoffgraham) 编写的
Netlify 滑动按钮。
在 CodePen 上。
它们是如何做到的?秘诀实际上归结为四种成分
- 使用
left
属性将“下载”标签滑动进出视野 - 在按钮的悬停状态下使用
padding
为显示悬停时的“下载”标签创建更多空间 - 在按钮的悬停状态下声明 1:1 的
scale()
,以便在内容移动时所有内容都保持在容器内。 - 指定按钮
padding
、按钮图标的background-position
和transform
属性的transition
,以便在按钮的默认状态和悬停状态之间实现平滑动画。
以下是没有所有演示样式的样子
查看 CodePen 上 Geoff Graham (@geoffgraham) 编写的
无样式 Netlify 滑动按钮。
在 CodePen 上。
如果您难以想象发生了什么,这里有一个插图显示了“下载”标签如何在按钮外部隐藏(由于 overflow: hidden
)以及它在悬停时如何被推入视野。

因此,通过在图标和“下载”标签上设置负 left
值,我们将它们推到视野之外,然后在整个按钮悬停时将这些值重置为正值。
/* Natural State */
.button {
background:
#f6bc00
url(data:image/svg+xml;base64,...)
no-repeat -12px center;
overflow: hidden;
}
.button span:nth-child(1) {
position: absolute;
left: -70px;
}
/* Hovered State */
.button:hover {
padding-left: 95px;
background-position: 5px center;
}
.button span:nth-child(1) {
position: absolute;
left: -70px;
}
请注意,保持这种状态将使按钮图标滑动到视野中并为“下载”标签腾出足够的空间,但标签实际上会在悬停时从按钮上漂浮。
查看 CodePen 上 Geoff Graham (@geoffgraham) 编写的
无样式 Netlify 滑动按钮。
在 CodePen 上。
这就是在按钮上添加 1:1 比例有助于保持内容完整的原因。
* Hovered State */
.button:hover {
padding-left: 95px;
background-position: 5px center;
transform: scale(1, 1);
}
这些填充值是 魔法数字。根据字体、字体大小和其他因素,它们对您来说将有所不同,因此您的体验可能会有所不同。
最后一个核心成分是 transition
属性,它使所有内容平滑地滑动到位,而不是让它们突然跳动。它提供了更好的体验。
/* Natural State */
.button {
background:
#f6bc00
url(data:image/svg+xml;base64,...)
no-repeat -12px center;
overflow: hidden;
transition: padding .2s ease, background-position .2s ease, transform .5s ease;
}
添加一些小装饰,如圆角等,您就拥有了一个非常漂亮的按钮。
查看 CodePen 上 Geoff Graham (@geoffgraham) 编写的
Netlify 滑动按钮。
在 CodePen 上。
我不知道 transform: scale 与 position: relative 有相同的效果。谢谢!
令人惊讶的是,它确实有。
不过,如果想要进行缩放但又不想影响定位,感觉有点像黑客手段。
我想知道为什么需要 transform 以及为什么不使用 position:relative,后者更容易理解并且效果相同。
一开始不明白使用 transform: scale 的效果,感谢您提到它 :)
顺便问一下,您认为设置转换(transform .5s ease)有什么特别的理由吗?
我仍在努力理解
scale
在这里的作用。感谢您撰写本文!我也是!
我认为 Scale 确保它平滑地伸展。
据我理解,作者使用
transform: scale(1, 1);
来创建 包含块用于绝对定位的
span:nth-child(1)
,即 下载 字样。可以通过在父元素(在本例中为
<a class="button">
)上设置position: relative;
来实现。总的来说,我不喜欢这种交互方式。只有我一个人觉得它真的很令人迷失方向吗?
非常棒的交互。我认为您可以通过删除转换中的
ease
来节省一些字符(因为ease
是默认的计时函数)。我认为可以通过动画化进出转换的元素的(最大)宽度来实现这一点,而无需使用太多魔法数字。为了尝试这一点,我在此处分叉了您的 CodePen:https://codepen.io/jperals/pen/jONZxWQ?editors=1100
我所做的是将“下载”文本和图标组合在一个元素中,并对该元素的(最大)宽度进行动画处理。我遇到的一个问题是无法从 0 动画化宽度到“auto”,这在另一篇不错的 CSS Tricks 文章中得到了很好的解释:https://css-tricks.org.cn/using-css-transitions-auto-dimensions。但是您可以改为对最大宽度进行动画处理。正如文章所解释的那样,这种方法有一个小缺点,即您仍然必须硬编码一些最大宽度作为魔法数字,当然,它只在内容不超过该宽度时有效,并且转换持续时间也将基于该最大值。但尽管如此,我仍然认为这是一种更灵活的方法,因为它允许您拥有可变大小的内容(请注意右侧的按钮具有更长的文本)。我们也在对更少的东西进行动画处理(实际上只有一个)。您怎么看?
感谢这篇文章,它让我学习了一些东西,并进行了一些黑客尝试 :)
很酷的文章。我在浏览器内布局编辑器的工具栏按钮中也做了类似的事情。去年,我必须为工作中的 Dacor 设备促销创建一个自定义登陆页面。我能够仅使用 CSS、伪元素和自定义 HTML 数据属性来重新创建他们很酷的 JS 按钮效果。Dacor 的网站上不再有按钮效果,但下面的 CodePen 显示了我如何使其正常工作。