先放张效果图,或者戳这里体验一下;或者直接去看作者英文文档找作者
起步
首先来搭个按钮的基本的架子
<style>
.wrapper {
background: #A30036;
border-radius: 12px;
border: none;
padding: 0;
cursor: pointer;
outline-offset: 4px;
}
.front {
display: block;
padding: 12px 42px;
border-radius: 12px;
font-size: 1.25rem;
background: red;
color: white;
transform: translateY(-4px);
}
</style>
<body>
<button class="wrapper">
<span class="front">
戳一下
</span>
</button>
</body>
接下来在点击的时候使用transform: translate滑动前景图层,让它动起来,产生3d的效果,
这是实现这种效果的最佳方法,因为转换可以通过硬件加速。
.wrapper:active .front {
transform: translateY(-2px);
}
现在基本的动作有了,但感觉还是很生硬,来在原来基础上加点动画,这里使用了will-change以便这个动画可以被硬件加速
.front{
will-change: transform;
transition: transform 600ms cubic-bezier(0.3, 0.7, 0.4, 1);/*控制按压回弹*/
}
.wrapper:hover .front {
transform: translateY(-6px);
transition: transform 250ms cubic-bezier(.3, .7, .4, 1);//
}
.wrapper:active .front {
transform: translateY(-2px);
transition: transform 34ms;
}
这里需要注意,不要把hover和active顺序搞反了,否则按钮就点击不了了
关于
cubic-bezier请移步贝塞尔曲线
添加阴影
底部阴影
为了让效果更像3D,可以使用box-shadow达到阴影效果,但为了能达到更好的效果,这里采用之前的方法,新增了一层shadow,用来展示阴影效果
<style>
.wrapper:hover .shadow {
transform: translateY(4px);
transition: transform 250ms cubic-bezier(.3, .7, .4, 1.5);
}
.wrapper:active .shadow {
transform: translateY(1px);
transition: transform 34ms;
}
</style>
<body>
<button class="wrapper">
<span class="shadow"></span>
<span class="front">
戳一下
</span>
</button>
</body>
底部阴影渐变
新增一层edge,使其产生阴影渐变的效果
<style>
.edge {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 12px;
background: linear-gradient(
to left,
hsl(340deg 100% 16%) 0%,
hsl(340deg 100% 32%) 8%,
hsl(340deg 100% 32%) 92%,
hsl(340deg 100% 16%) 100%
);
}
</style>
<body>
<button class="wrapper">
<span class="shadow"></span>
<span class="edge"></span>
<span class="front">
戳一下
</span>
</button>
</body>
移动端优化
- 在移动端,点击按钮会发现出现一个点击反馈的框框
可以使用以下属性去除
.wrapper {
-webkit-tap-highlight-color: transparent;
}
- ios中无法点击按钮,添加
ontouchstart,或者docuemnt上绑定touchstart事件
<button class="wrapper" ontouchstart="">
...
</span>
</button>
document.addEventListener("touchstart", function() {
// .....
},false);
完整案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Title</title>
<style>
body{
text-align: center;
padding-top: 20px;
}
.wrapper {
position: relative;
background: transparent;
border-radius: 12px;
border: none;
padding: 0;
cursor: pointer;
outline-offset: 4px;
user-select: none;
-webkit-tap-highlight-color: transparent;
}
.wrapper:hover {
filter: brightness(110%);
}
.front {
user-select: none;
display: block;
padding: 12px 42px;
border-radius: 12px;
font-size: 1.25rem;
background: red;
color: white;
transform: translateY(-4px);
will-change: transform;
/*控制按压回弹*/
transition: transform 600ms cubic-bezier(0.3, 0.7, 0.4, 1);
}
.shadow {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 12px;
background: hsl(0deg 0% 0% / 0.25);
will-change: transform;
transform: translateY(2px);
transition:
transform
600ms
cubic-bezier(.3, .7, .4, 1);
}
.wrapper:hover .front {
transform: translateY(-6px);
transition:
transform
250ms
cubic-bezier(.3, .7, .4, 1);
}
.wrapper:active .front {
transform: translateY(-2px);
transition: transform 34ms;
}
.wrapper:hover .shadow {
transform: translateY(4px);
transition:
transform
250ms
cubic-bezier(.3, .7, .4, 1.5);
}
.wrapper:active .shadow {
transform: translateY(1px);
transition: transform 34ms;
}
.edge {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 12px;
background: linear-gradient(
to left,
hsl(340deg 100% 16%) 0%,
hsl(340deg 100% 32%) 8%,
hsl(340deg 100% 32%) 92%,
hsl(340deg 100% 16%) 100%
);
}
</style>
</head>
<body>
<button class="wrapper" ontouchstart="">
<span class="shadow"></span>
<span class="edge"></span>
<span class="front">
戳一下
</span>
</button>
</body>
</html>