【CSS进阶】box-shadow与filter:drop-shadow详解及
奇技淫巧
box-shadow 在前端的 CSS 编写⼯作想必⼗分常见。但是 box-shadow 除去它的常规⽤法,其实还存在许多不为⼈知的奇技淫巧。
box-shadow 常规⽤法
说到 box-shadow ,⾸先想到的必然是它能够⽣成阴影,所以称之为 shaodow ,简单看看它的语法:
基础属性语法
box-shadow属性向框添加⼀个或多个阴影。
box-shadow: h-shadow v-shadow blur spread color inset;
像这样box-shadow: 10px 10px 5px #888888;除此之外,我们要知道,box-shadow 是分外 shadow 和内 shadow 的,内阴影即是在属性上添加inset 。
OK,本⽂已经假设你对 box-shadow 有了⼀定的了解,在此基础上,我们再看看 box-shadow 有什么其它妙⽤。
box-shadow 模拟多边框
通常⽽⾔,我们会给许多元素添加边框border,但是当如果需要多重边框,这个时候,由于border单重的限制,box-shadow 就可以闪亮登场了。我们可以轻松的使⽤外阴影或者内阴影来模拟边框效果。
可以看到,由内⾄外,这⾥利⽤ box-shadow ,设置了⽩⾊、⿊⾊、灰⾊三层边框及最外层带模糊的阴影。
box-shadow 有⼀个参数是设置 blur 的,即是模糊的距离,在上⾯的例⼦中,即是第⼆重阴影0 0 0 10px #333,中的第三个 0 ,当 blur 的值为0 ,那么阴影本⾝是不会模糊的,那么就很容易模拟出边框的效果。
⽽且,元素可以设置多重阴影,并且它们存在层叠关系,离 box-shadow 最近设置的层叠优先级最⾼,依次递减,这个对照代码很好理解。当然,值得注意的是:
阴影并不是边框,它们并不占有实际的空间,也不能归属于box-sizing的范围。不过,你可以通过使⽤内边距或外边距(取决于阴影是内部的还是外部的)占据额外的空间来模拟。
上述⽰例模拟的边框是位于元素外部的。它不能捕获类似悬停和点击的⿏标事件。如果事件很重要,那么可以通过添加 inset 关键字让阴影出现在元素的内部。注意,你可能需要添加额外的内边距来扩充空间。
box-shadow 模拟半透明遮罩层
很多时候,我们需要⽤到类似下图这样的遮罩层,通过半透明遮罩层把背景调暗,凸显某些 UI 组件,提升⽤户体验。
常规的做法通常都会⽤到⼀个额外的元素,⽤作遮罩层,⾄少也是⼀个伪元素,before或者after。
不考虑低版本的兼容性的话,其实⽤ box-shadow 也可以模拟遮罩层这种效果。
这⾥还有⼀个例⼦,hover 时利⽤配合 scale 放⼤元素, box-shadow 产⽣遮罩,聚焦⽤户关注视野。
当然,值得注意的是:
使⽤这种⽅法不可避免的需要考虑兼容性,IE9+、Firefox 4、Chrome、Opera 以及 Safari 5.1.1 ⽀持 box-shadow 属性。
由于每个⼈的浏览器视⼝⼤⼩不⼀致,为了所有情况下 box-shadow ⽣成的阴影都能覆盖整个页⾯,可能需要将阴影的尺⼨spread设置的很⼤。
如果你真的想尝试这个⽅法,box-shadow 从性能⾓度⽽⾔属于耗性能样式,不同样式在消耗性能⽅⾯是不同的,box-shadow 从渲染⾓度来讲⼗分耗性能,原因就是与其他样式相⽐,它们的绘制代码执⾏时间过长。虽然有 GPU 的 3D 加速,但是具体使⽤的时候还是值得斟酌考虑。不过你要知道,没有不变的事情,在今天性能很差的样式,可能明天就被优化,并且浏览器之间也存在差异。
下⾯再讲讲多重 box-shadow 能⼲啥:
多重 box-shadow 之简单图形
css鼠标点击样式
从本质上讲,box-shadow 是将⾃⾝投影到另⼀个地⽅,在很多情况下,我们是可以利⽤ box-shadow 来复制⾃⾝的!
利⽤这个特性,我们可以⽤ box-shadow 制作⼀些简单的图形,在我的单标签图形中,有这样⼀个图形:
其中的云层,就是利⽤了多重box-shaodw在⼀个伪元素内⽣成的。下⾯我利⽤不同的颜⾊,直观的表达⼀下如何利⽤ box-shadow 绘制这个图形:
当所有阴影的颜⾊都是同⾊的时候,就很⾃然变成了⼀朵云朵:
当然,脑洞够⼤的话,更复杂⼀点的也是可以的,来看看下⾯这个图形,也是由单个标签完成:
其中⽐较困难的是其中环绕字母 e 的那个圆以及那个切⼊的不规则⾓,看看⽤阴影怎么把它做出来,利⽤了两重 box-shadow:
嗯,当然,你问我这些图形有什么⽤。我觉得实⽤性真的不强吧,我个⼈⽽⾔是兴趣,从中获取到了乐趣,同时也学到了很多东西,对属性本⾝印象也更加深刻,遇到许多 CSS ⽅⾯的问题的时候,思路更加开阔。
更多有趣的图形,可以
多重 box-shadow 实现⽴体感
这种⽅法运⽤在 text-shadow 上同样可以,可以实现⽂字的⽴体感。
运⽤多重 box-shadow ,不断偏移 1px ,就可以产⽣⼗分⽴体的感觉。
运⽤在按钮:
运⽤在⽂字:
多重 box-shadow 实现任意图⽚转换
嗯,讲真~~ 我觉得这个是最有趣的。
多重 box-shadow 还能做什么呢。由于 box-shadow 的多重性,也就是⽆论多少重都可以,那么理论上任意⼀张图⽚,每⼀个像素点都可以由⼀重 1px*1px 的 box-shadow 来表⽰。
为了完成这个任务,canvas刚好提供了⼀个⽅法ImageData可以获取到图⽚每⼀个像素点的 rgba 值,那么图⽚转为⼀个完全由 box-shadow 表⽰的图⽚是完全可⾏的。
为此,我倒腾了许久,写了这么⼀个⼩插件,可以将任意图⽚转化为由 box-shadow 表⽰的单个 div 标签。
如果上⾯的⼏点还有⽤武之地,那么这个功能我觉得除了看似厉害之外真的是毫⽆实⽤之处,上⾯也
说了,box-shadow 是⽐较耗性能的,因为即便是⼀个100px*100px的图形,转化之后都有10000重阴影,⽆论是对性能还是可读性⽽⾔,都是毁灭性的,但是讲真,还是挺有趣的。
box-shadow 就先说这些吧,box-shadow 肯定还要其它的⼀些妙⽤,细⼼之⼈可以继续挖掘之。
filter:drop-shadow
其实说到 box-shadow,就不得不提到另⼀个和它极为相似的 CSS3 新属性filter:drop-shadow,filter 即是 CSS 滤镜,可以在元素呈现之前,为元素的渲染提供⼀些效果,如模糊、颜⾊转移之类的。滤镜常⽤于调整图像、背景、边框的渲染。
当然这⾥我们只说 filter:drop-shadow。
filter:drop-shadow 也很好玩,本想继续长篇⼤论讨论下去,⽆奈发现张鑫旭⼤神两篇⽂章已经把我想说的都囊括了,前⼈栽树,后⼈乘凉,我也就不再献丑了。
两篇⾮常值得⼀读的⽂章:
另外(CSS揭秘)这本⼤作也对filter:drop-shadow有详细的描述,可以去看看。
希望这篇⽂章对⼤家有所帮助,尤其是在对问题解决的思维层⾯上。
到此本⽂结束,如果还有什么疑问或者建议,可以多多交流,写⽂章不容易,觉得不错的希望⼤家点个推荐。
原创⽂章,⽂笔有限,才疏学浅,⽂中若有不正之处,万望告知。