CSS 如何实现羽化效果
羽化是photoshop术语,羽化原理是令选区内外衔接部分虚化,起到渐变的作用从而达到自然衔接的效果,是ps及其其它版本中的处理图片的重要工具。
一、羽化的原理
羽化其实就是将边缘变得模糊,在 CSS 中其实就是创建一个边缘模糊的遮罩(mask),也就是需要一种半透明的渐变。
关于遮罩,这里简单介绍一下,基本语法很简单,和background的语法基本一致
.content{
-webkit-mask: '遮罩图片' ;
}
/*完整语法*/
.content{
-webkit-mask: '遮罩图片' [position] / [size] ;
}
这里的遮罩图片和背景的使用方式基本一致,可以是PNG图片、SVG图片、也可以是渐变绘制的图片,同时也支持多图片叠加。
遮罩的原理很简单,最终效果只显示不透明的部分,透明部分将不可见,半透明类推
先举个圆形的例子,这个比较简单,因为可以直接通过径向渐变创建
比如,下面有一个头像,现在直接放在背景上非常突兀
我们可以将这个头像通过径向渐变绘制出了一个从不透明到透明的遮罩,达到和背景融合的效果
.head{ -webkit-mask: radial-gradient(closest-side circle,#000 60%, transparent 100%); }
原理是这样的
最后效果如下
二、矩形的羽化原理
根据上面的分析,如果希望羽化矩形边缘,需要创建这一个遮罩
那么问题来了,如何创建这一个边缘模糊的矩形呢?貌似没办法直接通过渐变来实现,而且还需要是尺寸自适应的(自动跟随容器尺寸)
如果单纯看这样一个矩形,还是很容易实现的,通过box-shadow
即可实现
.shadow{ width: 200px; height: 200px; background:black; border-radius:10px; box-shadow:0 0 5px black, 0 0 10px black, 0 0 15px black }
根据需求,可以多叠加几层box-shadow
,这里叠加了3层,效果如下
三、通过 SVG foreignObject 转换成图片
上面提到,通过 CSS 阴影可以很轻松的实现我们说需要的效果,但可惜现在还是 dom
阶段,所以需要将这个 dom 转换成图像。
在这里,需要借助 SVG
中的foreignObject元素,通过这个元素,可以将 HTML
嵌入到SVG
中,轻松实现 dom
转图片的效果
有兴趣的可以参考之前这几篇文章
原理如下
回到这里,我们仅需要将上面的结果放到foreignObject
元素中,由于需要自适应尺寸,这里的body
宽高都是100%
,如下
<svg xmlns="http://www.w3.org/2000/svg"> <foreignObject width="100%" height="100%"> <body class="wrap" xmlns="http://www.w3.org/1999/xhtml"> <style> .wrap{ box-sizing: border-box; margin: 0; height: 100%; padding: 10px; } .shadow{ height: 100%; background:black; border-radius:10px; box-shadow:0 0 5px black, 0 0 10px black, 0 0 15px black } </style> <div class="shadow"></div> </body> </foreignObject> </svg>
这样就得到了一个宽高自适应的SVG
图像,无论宽高怎么变化,都是撑满的
别看这么多标签,这其实已经是一张图片,可以直接使用,接下来看看如何运用
四、矩形的羽化
其实上面得到的 SVG
可以直接当成一个图片资源,正常使用了,就像这样
.name{ -webkit-mask: url('./fearher.svg') }
不过,也可以将这个SVG
图片转换成内联形式,减少资源依赖,转换后仍然保持自适应特性
这里推荐张鑫旭老师的SVG在线压缩合并工具
转换后就是这个样子
.name{ -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3CforeignObject width='100%25' height='100%25'%3E%3Cbody class='wrap' xmlns='http://www.w3.org/1999/xhtml'%3E%3Cstyle%3E.wrap%7Bbox-sizing:border-box;margin:0;height:100%25;padding:10px%7D.shadow%7Bheight:100%25;background:%23000;border-radius:10px;box-shadow:0 0 5px %23000,0 0 10px %23000,0 0 15px %23000%7D%3C/style%3E%3Cdiv class='shadow'/%3E%3C/body%3E%3C/foreignObject%3E%3C/svg%3E") }
效果如下
而且由于尺寸是动态的,换个书名也能完美适应
最后再来对比一下,下面哪个一眼看上去效果最好?
五、总结一下
以上就是本文全部内容了,一个还不错的绘制小技巧,最后来回顾一下一些实现要点
- 羽化其实就是将边缘变得模糊,在 CSS 中其实就是创建一个边缘模糊的遮罩,也就是需要一种半透明的渐变。
- 圆形的边缘很好羽化,因为径向渐变可以直接绘制
- 矩形的边缘就稍微复杂点,因为不能直接通过渐变绘制
- 边缘模糊在 CSS 中很好实现,用 box-shadow 就行了
- 可以通过 SVG foreignObject 将 dom 转换成图片
- SVG 转换成内联形式,好处是减少资源依赖,转换后仍然保持自适应特性