【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 之简单图形
从本质上讲,box-shadow 是将自身投影到另一个地方,在很多情况下,我们是可以利用 box-shadow 来复制自身的!
利用这个特性,我们可以用 box-shadow 制作一些简单的图形,在我的单标签图形 Demo 中,有这样一个图形:

其中的云层,就是利用了 多重box-shaodw 在一个伪元素内生成的。下面我利用不同的颜色,直观的表达一下如何利用 box-shadow 绘制这个图形:
当所有阴影的颜色都是同色的时候,就很自然变成了一朵云朵:
当然,脑洞够大的话,更复杂一点的也是可以的,来看看下面这个图形,也是由单个标签完成:

其中比较困难的是其中环绕字母 e 的那个圆以及那个切入的不规则角,看看用阴影怎么把它做出来,利用了两重 box-shadow:

嗯,当然,你问我这些图形有什么用。我觉得实用性真的不强吧,我个人而言是兴趣,从中获取到了乐趣,同时也学到了很多东西,对属性本身印象也更加深刻,遇到许多 CSS 方面的问题的时候,思路更加开阔。
更多有趣的图形,可以 戳这里 – Demo
多重 box-shadow 实现立体感
这种方法运用在 text-shadow 上同样可以,可以实现文字的立体感。
运用多重 box-shadow ,不断偏移 1px ,就可以产生十分立体的感觉。
运用在按钮:
运用在文字:
多重 box-shadow 实现任意图片转换
嗯,讲真~~ 我觉得这个是最有趣的。
多重 box-shadow 还能做什么呢。由于 box-shadow 的多重性,也就是 无论多少重都可以,那么理论上任意一张图片,每一个像素点都可以由一重 1px*1px 的 box-shadow 来表示。
为了完成这个任务, canvas 刚好提供了一个方法 CanvasRenderingContext2D.getImageData 可以获取到图片每一个像素点的 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 SECRET》(CSS揭秘)这本大作也对 filter:drop-shadow 有详细的描述,可以去看看。
希望这篇文章对大家有所帮助,尤其是在对问题解决的思维层面上。
到此本文结束,如果还有什么疑问或者建议,可以多多交流,写文章不容易,觉得不错的希望大家点个推荐。
原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。
【CSS进阶】box-shadow 与 filter:drop-shadow 详解及奇技淫巧的更多相关文章
- CSS中伪类及伪元素用法详解
CSS中伪类及伪元素用法详解 伪类的分类及作用: 注:该表引自W3School教程 伪元素的分类及作用: 接下来让博主通过一些生动的实例(之前的作业或小作品)来说明几种常用伪类的用法和效果,其他的 ...
- 小白进阶之Scrapy第六篇Scrapy-Redis详解(转)
Scrapy-Redis 详解 通常我们在一个站站点进行采集的时候,如果是小站的话 我们使用scrapy本身就可以满足. 但是如果在面对一些比较大型的站点的时候,单个scrapy就显得力不从心了. 要 ...
- 【二次元的CSS】—— 用 DIV + CSS3 画咸蛋超人(详解步骤)
[二次元的CSS]—— 用 DIV + CSS3 画咸蛋超人(详解步骤) 2016-05-17 HTML5cn 仅仅使用div作为身体的布局,用css3的各种transform和圆角属性来绘制各部位的 ...
- web前端学习(三)css学习笔记部分(6)-- 选择器详解
9.选择器详解 9.1 属性选择器 CSS3 属性选择器,在 CSS3 中,追加了三个属性选择器分别为:[att*=val].[att^=val]和[att$=val],使得属性选择器有了通配符的概 ...
- box-shadow 与 filter:drop-shadow 详解及奇技淫巧
box-shadow 在前端的 CSS 编写工作想必十分常见.但是 box-shadow 除去它的常规用法,其实还存在许多不为人知的奇技淫巧. 喜欢 markdown 版本的可以戳这里. box-sh ...
- CSS样式----CSS的继承性和层叠性(图文详解)
CSS的继承性 我们来看下面这样的代码,来引入继承性: 上方代码中,我们给div标签增加红色属性,却发现,div里的每一个子标签<p>也增加了红色属性.于是我们得到这样的结论: 有一些属性 ...
- CSS 块状元素和内联元素的详解
我们先来分析一下块级元素.内联级元素的定义和解析: 块元素(block element)一般是其他元素的容器元素,块元素一般都从新行开始,它可以容纳内联元素和其他块元素,常见块元素是段落标签'P&q ...
- CSS中padding、margin、bordor属性详解
一.图解CSS padding.margin.border属性 W3C组织建议把所有网页上的对像都放在一个盒(box)中,设计师可以通过创建定义来控制这个盒的属性,这些对像包括段落.列表.标题.图片以 ...
- RequireJS进阶-模块的优化及配置的详解
概述 关于RequireJS已经有很多文章介绍过了.这个工具可以将你的JavaScript代码轻易的分割成苦干个模块(module)并且保持你的代码模块化与易维护性.这样,你将获得一些具有互相依赖关系 ...
随机推荐
- 快速理解-Ajax
AJAX即“Asynchronous JavaScript and XML”,意思是异步JavaScript和XML,是指一种创建交互式网页的网页开发技术. 虽然现在很少有人去自己手动写AJAX,大多 ...
- C# webBrowser 开新窗口保持Session(转)
首先为项目添加引用 Microsoft Internet Controls public Form1() { InitializeComponent(); this.webBrowser1.Allow ...
- Windows多线程多任务设计初步(转)
Windows多线程多任务设计初步 [前言:]当前流行的Windows操作系统,它能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程 ...
- [LintCode] Trailing Zeroes 末尾零的个数
Write an algorithm which computes the number of trailing zeros in n factorial. Have you met this que ...
- 递归一题总结(OJ P1117倒牛奶)
题目: 农民约翰有三个容量分别是A,B,C升的桶,A,B,C分别是三个从1到20的整数,最初,A和B桶都是空的,而C桶是装满牛奶的.有时,约翰把牛奶从一个桶倒到另 ...
- Java中堆内存和栈内存详解
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间 ...
- 安卓 自定义AlertDialog对话框(加载提示框)
AlertDialog有以下六种使用方法: 一.简单的AlertDialog(只显示一段简单的信息) 二.带按钮的AlertDialog(显示提示信息,让用户操作) 三.类似ListView的Aler ...
- java之数据结构之链表及包装类、包
链表是java中的一种常见的基础数据结构,是一种线性表,但是不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针.与线性对应的一种算法是递归算法:递归算法是一种直接或间接的调用自身算法的过 ...
- 小菜学习设计模式(五)—控制反转(Ioc)
写在前面 设计模式目录: 小菜学习设计模式(一)—模板方法(Template)模式 小菜学习设计模式(二)—单例(Singleton)模式 小菜学习设计模式(三)—工厂方法(Factory Metho ...
- eventbus 备注
Event在整个系统中是单例的. EventBus.getDefault().register(this); 注册 EventBus.getDefault().unregister(this); 注销 ...