![8e6c7859fb3ba54d111d3c8a6549a0a1.png](https://img-blog.csdnimg.cn/img_convert/8e6c7859fb3ba54d111d3c8a6549a0a1.png)
单侧投影
难题
box-shadow 如何在元素的一侧(偶尔是两侧)设置投影。
单侧投影
大多数人使用 box-shadow 的方法是,指定三个长度值和一个颜色值:
box-shadow
box-shadow 的绘制原理:
- 以该元素相同的尺寸和位置,画一个 rgba(0,0,0,.5) 的矩形;
- 把它向右移 2px,向下移 3px;
- 使用模糊算法将它进行 4px 的模糊处理;
- 将模糊后的矩形与原始元素的交集部分会被切除掉。
![a1c095c992c98dad34812daa2883b2fe.png](https://img-blog.csdnimg.cn/img_convert/a1c095c992c98dad34812daa2883b2fe.png)
使用 4px 的模糊半径意味着投影的尺寸会比元素本身的尺寸大约 8px ,因此投影的最外圈会从元素的四面向外显露出来,只需改变偏移量,就可以把投影的顶部和左侧隐藏起来,只要这两个方向上的偏移量不小于4px 就可以了。但是,这在某种程度上会导致外露的投影太过浓重,看起来不是很美观。另外,就算这个问题勉强可以接受,但跟想要的投影在单侧的不相符。
最终的解决方案来自 box-shadow 的第四个长度参数,排在模糊半径参数的后面,称作扩张半径。这个参数会根据指定的值去扩大(当指定值为负数)缩小投影的尺寸。举例来说:一个 -5px 的扩张半径会把投影的宽度和高度各减少 10px。因此,下面代码即为想要的效果:
box-shadow
![c01a28b3cff9f574a6c8214b87454e4e.png](https://img-blog.csdnimg.cn/img_convert/c01a28b3cff9f574a6c8214b87454e4e.png)
邻边投影
box-shadow
![a1fb46be9bb0b7f421b6740ccaff5382.png](https://img-blog.csdnimg.cn/img_convert/a1fb46be9bb0b7f421b6740ccaff5382.png)
双侧投影
因为扩张半径在四个方向上的作用是相等的(即无法指定投影在水平方向上放大,而在垂直方向上缩小),唯一的办法是用两块投影(每边各一块)来达到目的。
box-shadow
不规则投影
难题
给一个矩形或者其他能用 border-radius 生成的形状加投影时,box-shadow 的表现都堪称完美。但是当元素添加了一些伪元素或者半透明的装饰后,box-shadow 就有点力不从心了。这类情况包括:
- 半透明图像、背景图像、或者 border-image;
- 元素设置了点状、虚线或半透明的边框,但没有背景;
- 对话气泡,它的小尾巴通常是用伪元素生成的;
- 在“切角效果”一节中见过的切角形状;
- 几乎所有的折角效果,包括“折角效果”一节将提到的例子;
- 通过 clip-path 生成的形状,比如“菱形图片”一节中提到的菱形图像。
如果对这些元素使用 box-shadow 则会得到如下所示的效果。
![cb6a85c718658df727818e524724632e.png](https://img-blog.csdnimg.cn/img_convert/cb6a85c718658df727818e524724632e.png)
解决方案
滤镜效果规范为这个问题提供了一个解决方案,它引入了一个叫作 filter 的新属性,比如blur() 、 grayscale() 以及我们需要的 drop-shadow()
drop-shadow() 滤镜可接受的参数基本上跟 box-shadow 属性是一样的,但不包括扩张半径,不包括 inset 关键字,也不支持逗号分割的多层投影语法。举个例子,上面的投影:
box-shadow
可以这样写:
filter
染色效果
难题
为一幅灰度图片(或是被转换为灰度模式的彩色图片)增加染色效果(color tint),是一种流行且优雅的方式,可以给一系列风格迥异的照片带来视觉上的一致性。我们通常会在静止状态下应用这个效果,当发生 :hover或其他交互时再去除。最初的解决方法是用不同的图片来做,这样不仅会增加 HTTP 的请求,同时一旦色系发生变化,则又需要重新作图,成本很高。
另外一种方法是:在图片的上层覆盖一层半透明的纯色;或者把图片设置为半透明并覆盖在一层实色背景之上。但这并不是真正的染色效果。
此外还有基于 JavaScript 的方案,把图片置入 <canvas> 元素中,并利用脚本对其进行染色处理。但是用这种方案限制很多。
基于滤镜的方案
没有现成的滤镜可以实现这个效果,需要将多个滤镜进行组合。
sepia() :给图片增加一种降饱和度的橙黄色染色效果
saturate() :给每个像素提升饱和度
hue-rotate() :把每个像素的色相以指定的度数进行偏移
filter
![080d66ae98310265a56cd29175863783.png](https://img-blog.csdnimg.cn/img_convert/080d66ae98310265a56cd29175863783.png)
此时,就把图片的色调改变了,如果这个效果需要由 :hover 或其他状态来触发切换,还可以为这个变化增加过渡动画:
img
![68db97cac8c203c4e5cb731276c0a0dd.gif](https://img-blog.csdnimg.cn/img_convert/68db97cac8c203c4e5cb731276c0a0dd.gif)
基于混合模式的方案
对一个元素设置混合模式,有两个属性可以使用:mix-blend-mode 可以为整个元素设置混合模式,background-blend-mode 可以为每层背景单独指定混合模式。因此有两种:
- 把图片包裹在一个容器中,并把容器的背景色设置为想要的主色调。
- 不用图片元素,而是用 <div> 元素——把这个元素的第一层背景设置为要染色的图片,并把第二层的背景设置为想要的主色调。
<
滤镜是可动画的,而混合模式则不是!
<
![170ad7c9afea763715e504203e345d15.gif](https://img-blog.csdnimg.cn/img_convert/170ad7c9afea763715e504203e345d15.gif)
上述两种方法可以实现滤镜,但是都不够理想:
- 图片的尺寸需要在 CSS 代码中写死;
- 在语义上,这个元素并不是一张图片,因此并不会被读屏器之类的设备读出来。
毛玻璃效果
难题
半透明颜色最初的使用场景之一就是作为背景。将其叠放在照片类或其他花哨的背层之上,可以减少对比度,确保文本的可读性。在传统的平面设计中,这个问题的解决方案通常是把文本层所覆盖的那部分图片区域作模糊处理。
借助 blur() 滤镜,我们在 CSS 中获得了对元素进行模糊处理的能力。如果直接使用 blur() 滤镜,整个元素都会被模糊,文本反而变得更加无法阅读了。有没有某种方法可以只对元素的背层(即被该元素遮住的那部分背景)应用这个滤镜呢?
解决方案
不能直接对元素本身进行模糊处理,就对一个伪元素进行处理,然后将其定位到元素的下层,它的背景将会无缝匹配 <body> 的背景。
<
![2e911e8e28331fd98a76ef8eec5c05b5.png](https://img-blog.csdnimg.cn/img_convert/2e911e8e28331fd98a76ef8eec5c05b5.png)
折角效果
难题
把元素的一个角(通常是右上角或右下角)处理为类似折角的形状,再配上或多或少的拟物样式,这种效果已经成为一种非常流行的装饰手法。
已实现的方法的原理通常是在右上角增加两个三角形:一个三角形用来体现折页的形状,另一个白色的三角形遮住元素的一角,用来模拟翻折所产生的缺口。这两个三角形通常都是由经典的边框技巧来生成的。
但是,当折角元素下不是纯色或者折角不是45°时,已有的方案就不能满足了。
45°折角的解决方案
在矩形的右上角创建一个大小为 0.5em 的斜面切角,代码为:
background
接下来所需要做的就是增加一个暗色的三角形来实现翻折效果。实现方法是增加另一层渐变来生成这个三角形并将其定位在右上角,这样就可以通过 background-size 来控制折角大小。
background
但是,看到折角并不是所期望的样子,第二层渐变中的 2em 折角尺寸是写在色标中的,因此它是沿着渐变轴进行度量的,是对角线尺寸;而 background-size 中的 2em 长度是背景贴片的宽度和高度,是在水平和垂直方向上进行度量的。因此为了使两者对齐:
- 如果要保留对角线的 2em 长度,就要将 background-size 乘以 2 。
- 如果要保留水平和垂直方向上的 2em 长度,就要用切角渐变的角标位置值除以 √2 。
因为 background-size 使用了两次长度,因此使用第二种方案更合适,因此其值为2/√2。
background
![f57cededa65f46431cb6d1714b9fd1b5.png](https://img-blog.csdnimg.cn/img_convert/f57cededa65f46431cb6d1714b9fd1b5.png)
其他角度的解决方案
.
![5e41890e24df20b3b30e63d65cae0ebb.png](https://img-blog.csdnimg.cn/img_convert/5e41890e24df20b3b30e63d65cae0ebb.png)
mixin的写法
@mixin