WEB前端奇淫巧计-奇妙的头像效果
简介
在我们的日常开发中,难免会遇到需要显示头像的情况
但是传统的头像显示,仅仅就是一张图片摆在那里,毫无新颖性,既枯燥又乏味,多看几眼还感觉是不是头像中的人物长的有问题,害~,一言难尽
有的时候我精心选的头像,别人都不会多看一眼,甚至就假装没看见一样就草草的把页面关掉,导致用户在浏览自己做的页面时毫无体验感
所谓体验感,就是在浏览页面时,会不由自主的发出:“卧槽,这个牛!”
今天我们要介绍一个头像的展示效果,也许你看起来它实现起来有点难,但是真正实现起来一点都不简单
废话不多说了,开门见山,先看一下最终的效果
看见没,是不是很少有看到这样的头像效果,有没有在内心中惊呼,这个牛
注意喔,这个没用到一点 js,是纯 css 实现的哦
但是这个实现起来雀氏没有我们想象的那么简单,不过我们可以从实现中学到很多知识
错误的想法
有些精通 css 的小伙伴们就说了,这还不简单,分分钟的事
直接在 img 标签外面放个 div,然后 div 直接 overflow:hidden,再加一个 hover 效果,放大图片
不过实现出来可能是这样的
看到没,是不是完全感觉不一样
其实我们我们仔细想一下就知道,人物的头部是可以跨过外部的圆圈的,而身体是在圆的内部被隐藏掉的,就光这一点就会让人头皮发麻
具体的实现方案
首先我们先在身体内丢个 img,并引入心怡的图片
<body>
<img src="./avatar.webp" />
</body>
先看下部分 css
img {
--size: 280px; /* 头像的尺寸 */
--borderWidth: 5px; /* 头像外边框的宽度 */
--borderColor: #c02942; /* 头像边框的颜色*/
width: var(--size);
aspect-ratio: 1; /* 头像的宽高比,这里是1:1,也是就现在头像是正方形 */
padding-top: calc(var(--size) / 5);
cursor: pointer;
border-radius: 0 0 calc(var(--size) / 2) calc(var(--size) / 2);
outline: var(--borderWidth) solid var(--borderColor);
}
先来解释下
css 变量的声明和使用
我们知道在 less 和 sass 中都可以给 css 声明变量,其实在纯 css 中也可以声明变量
--变量名,就是 css 声明变量的方式,后面的值就是给变量赋的值
在使用时直接用 var(–变量名), 就可以取到这个变量的值
举个例子
--size: 280px;
width: var(--size);
等同于
width: 280px;
aspect-ratio
-
这个属性是定义宽高比的
-
aspect-ratio:1; 这个时候宽高比是 1:1
-
aspect-ratio:4/3; 这个时候宽高比是 4:3
border-radius
-
这个属性我们经常用,但很少有人知道它可以有四个值
-
border-radius:0 0 140px 140px;
-
四个值分别对应盒子的是左上,右上,右下,左下四个角
-
border-radius:14px; 就相当于 border-radius:14px 14px 14px 14px;
outline
- outline 用法和 border 类似,不过作用在 border 外面
经过以上 css 最终的呈现效果是这样的
接下来重点来了
background: radial-gradient(
circle closest-side,
#ecd078 calc(99% - var(--borderWidth)),
var(--borderColor) calc(100% - var(--borderWidth)) 99%,
#0000
) center / 100% no-repeat content-box;
background
-
可详细了解下background,可点击链接查看详情
-
background 其实可以有很多值
-
background: bg-image position/bg-size bg-repeat bg-origin;
例如
background: url(./buouyu.png) center / 100% no-repeat content-box;
url 引入一个图片路径表示要显示的图片
center 表示图片的位置居中
100%表示图片的大小撑满盒子的宽高
no-repeat 表示图片不重复出现
content-box 表示图片只占用盒子的 content 区域,也就是不包含 border 和 padding
注意斜杠前面是 background-position 斜杠后面是 background-size
如 50% 50%/100% 100% 则:
background-position:50% 50%;
background-size:100% 100%;
radial-gradient
-
注意以上的 url(./buouyu.png) 也可以换成 radial-gradient,也就是把图片换成渐变色
-
也可详细了解下radial-gradient,点击链接可查看详情
-
radial-gradient(shape size , start-color, …, last-color);
例如
height: 200px;
width: 200px;
background-color: yellow; /* 浏览器不支持的时候显示 */
border-radius: 50%;
background-image: radial-gradient(
circle closest-side,
red 90%,
green 90% 95%,
#0000
);
在 radial-gradient 里
circle 表示指定圆形的径向渐变
closest-side 表示指定径向渐变的半径长度为从圆心到离圆心最近的边
red 90% 表示从 0 到 90%的区域都是红色
green 90% 95% 表示从 90%到 95%都是绿色
#0000 这个其实是个透明色,#000000 和 #000 都表示黑色,#0000 是 #0000000 的简写,后面两位表示透明度
从 95%到 100%为绿色到透明色的渐变
最终展现出来是这样的
我们的头像加了那段代码就变成了这样
到这一步我们发现,头像的上半圆和下半圆并没有对齐
这时我们需要设置下轮廓框架在 border 边缘外的偏移
outline-offset: -5px;
outline-offset
这个表示轮廓和 border 之间的距离
举个例子
border: 2px solid black;
outline: 2px solid red;
outline-offset: 15px;
看下效果
图片上的黑色框到红色框之间的距离就是 15px
再来看下设置 outline-offset 后我们的头像效果
哦吼,感觉快完成啦
现在我们需要把圆以外的框框隐藏掉就行啦
-webkit-mask: linear-gradient(#000 0 0) no-repeat 50% calc(
1px + var(--borderWidth)
) / calc(100% - 2 * var(--borderWidth) - 2px) 50%, radial-gradient(
circle closest-side,
#000 99%,
#0000
) center / 100% 100% no-repeat content-box;
-webkit-mask 可能有很多小伙伴没见过,别急别急
让我来跟你解释
-webkit-mask
我们来直接看一个例子
background: url("images/logo.png") no-repeat;
-webkit-mask: url("images/mask.png");
看一下原理
怎么样是不是一目了然,接下来我们需要画出需要显示的区域就行啦
linear-gradient
创建线性渐变的图片
详情可参考官方文档linear-gradient
linear-gradient(#000 0 0)是生成背景为纯黑的图片
height: 200px;
width: 200px;
border: 1px solid red;
background: linear-gradient(#000 0 0) no-repeat 50% 6px / calc(
100% - 10px - 2px
)
50%;
效果是
加上下面的圆
background: linear-gradient(#000 0 0) no-repeat 50% 6px / calc(
100% - 10px - 2px
)
50%, radial-gradient(
circle closest-side,
#000 calc(100% - 6px),
#0000 calc(100% - 6px) 100%
) 50% / 100% 100% no-repeat content-box;
效果是
此时放在我们头像上就是这样的
最终的原理就是这样纸
终于能看到一个完整的图片啦
但看上去和普通的头像没什么区别
我们需要加上动画和稍加微调,这是头像的灵魂
下面是完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>mytest</title>
<style>
img {
--size: 280px;
/* 头像的尺寸 */
--borderWidth: 5px;
/* 头像外边框的宽度 */
--borderColor: #c02942;
/* 头像边框的颜色*/
width: var(--size);
aspect-ratio: 1;
/* 头像的宽高比,这里是1:1,也是就现在头像是正方形 */
padding-top: calc(var(--size) / 5);
cursor: pointer;
border-radius: 0 0 calc(var(--size) / 2) calc(var(--size) / 2);
outline: var(--borderWidth) solid var(--borderColor);
--f: 1;
/* 初始化大小*/
--_g: 50% / calc(100% / var(--f)) 100% no-repeat content-box;
--_o: calc((1 / var(--f) - 1) * var(--size) / 2 - var(--borderWidth));
background: radial-gradient(
circle closest-side,
#ecd078 calc(99% - var(--borderWidth)),
var(--borderColor) calc(100% - var(--borderWidth)) 99%,
#0000
) var(--_g);
outline-offset: var(--_o);
-webkit-mask: linear-gradient(#000 0 0) no-repeat 50% calc(
1px - var(--_o)
) / calc(100% / var(--f) - 2 * var(--borderWidth) - 2px) 50%, radial-gradient(
circle closest-side,
#000 99%,
#0000
) var(--_g);
transform: scale(var(--f));
transition: 0.5s;
}
img:hover {
--f: 1.35;
}
</style>
</head>
<body>
<img src="./avatar.webp" />
</body>
</html>
最终效果