我的博客:[译] CSS 变量实现炫酷鼠标悬浮效果
我最近从 Grover 网站上的有趣的悬停动画中获得灵感将鼠标移动到订阅按钮上可以显示光标移动后的彩色渐变这个想法很简单, 但结果是一个按钮从复位和等待点击中脱颖而出
那怎样实现类似的效果使我们的网站同样出色呢? 很好, 它并没有你想象的那么困难!
跟踪位置
我们需要做的第一件事便是跟踪鼠标光标的位置
- document.querySelector('.button').onmousemove = (e) => {
- const x = e.pageX - e.target.offsetLeft
- const y = e.pageY - e.target.offsetTop
- e.target.style.setProperty('--x', `${ x }px`)
- e.target.style.setProperty('--y', `${ y }px`)
- }
选中目标元素并监听用户鼠标划过的事件
计算鼠标相对于该元素的坐标
将坐标保存到 CSS 的变量中
是的, 只需要 6 行代码就可以让你的 CSS 知道用户鼠标的位置通过这些信息你可以实现更多更庞大的效果但是让我们先实现 CSS 部分
为渐变设置动画效果
我们已经将鼠标坐标存储在 CSS 变量中, 所以可以在 CSS 中的任何地方使用它们
- .button {
- position: relative;
- appearance: none;
- background: #f72359;
- padding: 1em 2em;
- border: none;
- color: white;
- font-size: 1.2em;
- cursor: pointer;
- outline: none;
- overflow: hidden;
- border-radius: 100px;
- span {
- position: relative;
- }
- &::before {
- --size: 0;
- content: '';
- position: absolute;
- left: var(--x);
- top: var(--y);
- width: var(--size);
- height: var(--size);
- background: radial-gradient(circle closest-side, #4405f7, transparent);
- transform: translate(-50%, -50%);
- transition: width .2s ease, height .2s ease;
- }
- &:hover::before {
- --size: 400px;
- }
- }
将文本包裹在一个 span 中, 防止渐变层覆盖到文字上方
初始 width 和 height 为 0px 并且当鼠标悬浮在按钮上时将它们增加到 400px 不要忘记设置 transition 让它有个渐入的效果
使用 JS 中设置坐标跟随鼠标
应用一个 radial-gradient 到 background 上并使用
closest-side circle
closest-side 使得 background 充满整个 before 但又没有超出它
效果
就这样, 添加缺少的 html 就可以了:
在线预览
See the Pen Mouse movement button with border-radius by Tobias Reich (@electerious) on CodePen.
拓展
只需对鼠标的位置作出反应, 即可建立如此多的效果它非常华丽并且使得互动如此有趣
以下是我在 basicScroll 的网站上使用的类似动画:
- May the hover be with you https://t.co/2jrmVorLRW
- @electerious
或者看中并建立一个 3D 视差按钮:
- 3D parallax button with JS controlled CSS variables @CodePen https://t.co/qE0woiNip8 https://t.co/Wyi0xjRzPq
- @electerious
可能性是无止境的你可以在下方评论区分享你使用它创建的效果
Q&A
Q: 为什么使用 width 和 height 而不是使用 transform: scale() 实现动画呢?
A: 对于动画的性能, width 和 height 是不好的, 你可能会尽量地尝试使用 transform 你为什么我不这样做呢? 问题在于浏览器在加速图层中呈现元素 (正在转换) 当按钮具有非矩形边缘时, 此图层可能会导致问题
Q: 为什么改变 top 和 left 而不是
transform: translate()
呢?
A: 参照上条
Q: 我可以在 Twitter 关注你吗?
A: 当然(原作者推特 @electerious)
来源: https://juejin.im/post/5a924fcaf265da4e7d6061a6