简单CSS头像动画快速入门CSS 3D
一个看起来非常mini的效果——鼠标经过,头像探出边框,如果你碰到这样的需求会怎么实现呢?
分析需求
正常状态下,头像图片位于相框之内。当鼠标悬停时,头像变大并且上半部分压住相框,下半部分依然在相框内。这样就产生了探出头的效果。也就是在鼠标悬停时实现下图第3个图片的效果。
学习了两位css-tricks大佬的文章后(地址附在文末),我学会了两种纯CSS的实现方式。
CSS 3D 实现
个人更喜欢3D的实现方式,通过这个简单动画,更加深入的学习了CSS 3D。
首先需要了解CSS的三维坐标系,记住3个轴的正负值方向。刚开始我记错了三维坐标系的方向,理解3D变换就很晕 😇 ,记住坐标系之后就很好理解每个轴上正负值变化以及旋转的效果。
- x轴 : 水平向右,x右边是正值,左边是负值
- y轴 : 垂直向下,y下面是正值,上面是负值
- z轴 : 垂直屏幕,往外面是正值,往里面是负值
只需一个html标签
没错,只需要一个div
<div class="d3"></div>
CSS
画出基本形态
之所以只用到一个div,因为我们可以用::after和::before这两个伪元素打配合。
::before画出边框,::after放头像图片
.d3 {
position: relative;
width: 200px; height: 200px;
background-color: lightpink;
border-radius: 100%;
}
.d3::before {
position: absolute;bottom:0;
content: '';
width: 100%; height: 100%;
border: 6px solid green;
border-radius: 100%;
}
.d3::after {
content: '';
position: absolute; bottom:0;
background: url(~/assets/images/avatar2.png) no-repeat center 100%;
background-size: 90%;
width: 100%; height: 100%;
border-radius: 0 0 900px 900px;
}
现在小丸子还是在相框外面,怎么让她进去?接下来是关键!!!
transform-style: preserve-3d
transform-style接受两个值
- flat:设置元素的子元素位于该元素的平面中(子元素不设置3D空间)
- perserve-3d:设置元素的子元素应用于3D空间中
既然要用到3D,首先需要告诉浏览器给我们准备好3D空间,我们先给div加上
.d3 {
transform-style: preserve-3d;
...
}
rotate3d
为了让小丸子头像上半部分在相框之上,下半部分在边框之下,我们让她绕着X轴旋转一下
transform: rotateX(-10deg);
rotate3d()
CSS 函数定义一个变换,它将元素围绕固定轴移动而不使其变形。运动量由指定的角度定义; 如果为正,运动将为顺时针,如果为负,则为逆时针。
此处只需要绕X轴旋转,所以使用rotateX
。
头像旁用CSS画了一个示意图,能够更直观的看出两个元素在空间中的位置
不过这个时候,小丸子头像的下部被粉色背景遮挡了。因为在旋转时,上半部分透了出来,而下半部分退到父元素后面去了。没关系我们继续
translate
我们给::before和::after都加上,这样头像和相框都会在Z轴上往前移动,不会再被粉色背景(div)元素遮挡。
translate: 0 0 30px;
CSS 属性
translate
允许你单独声明平移变换,并独立于transform
属性。这在一些典型的用户界面上更好用,而且这样就无需在transform
中声明该函数并记住转换函数的确切顺序了。
鼠标悬停放大
修改小丸子伪元素的height和background-size让头像变大,
width需要和相框伪元素保持一致,因为用border-radius实现圆角,如果2个元素width不一致,下边的圆弧半径就会不同,效果不太好。
// 悬停状态
.d3:hover::after {
width: 95%;
height: 115%;
left: 2.5%;
background-size: 115%;
}
.d3:hover::before {
transform: scale(0.95) translateY(2.5%);
}
transform-origin
transform-origin
CSS 属性让你更改一个元素变形的原点
这张小丸子头像选的不是很好,脑袋太大了,如果悬停时放大百分比比较大,头发就会被遮挡一部分。所以额外给::after再增加一个样式,让旋转的原点靠下一点。
transform-origin: 50% 60%;
现在差不多可以了,但是我给div加了一个粉色背景,又在悬停时缩小了相框,所以还有点问题,悬停时背景漏出来不好看。
如果不需要背景,那么没事了,想要保留背景的话,我们还需要处理一下。
perspective
给div加上透视效果
transform: perspective(450px);
CSS 属性
perspective
指定了观察者与 z=0 平面的距离,使具有三维位置变换的元素产生透视效果。z>0 的三维元素比正常大,而 z<0 时则比正常小,大小程度由该属性的值决定。
perspective可能比较难理解一些,它就像绘画里面的透视效果,远小近大。perspetive的值越小,透视效果就越明显。我们只要记住相同perspective属性值,同样大小的元素,在Z轴上越往前(正值变大)屏幕上显示越大,反之显示变小。
我们给相框和图片设置了translate: 0 0 30px
让它们在z轴下往前走,在屏幕上它们会变大,div相对就小了,在放大时也不会漏出来(具体取值可以根据实际情况调整)。
虽然这个效果很不起眼,但是完整的走一遍,让我入门了CSS 3D,只能说CSS越来越强大了。
CSS源码
最后放上完整的CSS代码
.d3 {
margin-left: 100px;
transform-style: preserve-3d;
transform: perspective(450px);
position: relative;
width: 200px;
height: 200px;
background-color: lightpink;
border-radius: 100%;
}
.d3::before {
display: block;
position: absolute;
bottom: 0;
content: '';
width: 100%;
height: 100%;
border: 6px solid green;
border-radius: 100%;
transition: transform 0.15s ease-in-out;
transform-style: preserve-3d;
perspective: 450px;
translate: 0 0 30px;
}
.d3::after {
content: '';
position: absolute;
background: url(~/assets/images/avatar2.png) no-repeat center 100%;
background-size: 90%;
width: 100%;
height: 100%;
border-radius: 0 0 900px 900px;
display: block;
left: 0;
bottom: 0;
transform: rotateX(-10deg);
transform-origin: 50% 60%;
transition: 0.15s ease-in-out;
translate: 0 0 30px;
}
// 悬停状态
.d3:hover::after {
width: 95%;
height: 115%;
left: 2.5%;
background-size: 115%;
}
.d3:hover::before {
transform: scale(0.95) translateY(2.5%);
}
不用3D的实现方式
红色边框是另一种实现方式,代码量更少。这里只贴源码,大家有兴趣可以看作者的原文 《Fancy Hover Effect For Your Avatar》
<img src="~/assets/images/avatar2.png" />
img {
--s: 200px; /* image size */
--b: 6px; /* border thickness */
--c: var(--el-color-danger); /* border color */
--cb: #e9ecef; /* background color */
--f: 1; /* initial scale */
box-sizing: content-box;
width: var(--s);
height: var(--s);
aspect-ratio: 1;
padding-top: calc(var(--s) / 5);
cursor: pointer;
border-radius: 0 0 999px 999px;
--_g: 50% / calc(100% / var(--f)) 100% no-repeat content-box;
--_o: calc((1 / var(--f) - 1) * var(--s) / 2 - var(--b));
outline: var(--b) solid var(--c);
outline-offset: var(--_o);
background: radial-gradient(
circle closest-side,
var(--cb) calc(99% - var(--b)),
var(--c) calc(100% - var(--b)) 99%,
#0000
)
var(--_g);
-webkit-mask: linear-gradient(#000 0 0) no-repeat 50% calc(1px - var(--_o)) /
calc(100% / var(--f) - 2 * var(--b) - 2px) 50%,
radial-gradient(circle closest-side, #000 99%, #0000) var(--_g);
transform: scale(var(--f));
transition: 0.5s;
}
img:hover {
--f: 1.2; /* hover scale */
}
参考文章:
- Re-Creating the Porky Pig Animation from Looney Tunes in CSS css-tricks.com/re-creating…
- Fancy Hover Effect For Your Avatar css-tricks.com/a-fancy-hov…
转载自:https://juejin.cn/post/7237309353509847097