#前言
1.单侧投影
我们都知道box-shadow
可以设置元素的投影,但有时候我们只想设置一侧为投影效果,类似与这样:
具体代码实现:
div {
width: 1.6in;
height: 1in;
background: #fb3;
box-shadow: 0 5px 4px -4px black;
}
主要技术是通过指定box-shadow
的第四个长度参数扩张半径来扩大或缩小投影的尺寸,而这个值和模糊半径相等,为什么呢,因为我们的模糊半径最终会通过高斯模糊算法或者类似算法将半径进行模糊处理,最终会处理成两倍,在这里也就是8px
(近似理解成阴影边缘发生阴影色和纯透明色之间的颜色过度长度,但我们实际看到似乎大概只有4px
偏移,个人理解是由于过度效果导致剩余一部分看不见),所以我们如果用扩张半径缩小这个4px
,那么我们投影的尺寸将会和我们投影所属的尺寸完全一致,除非我们使用前两个参数来移动它,否则你讲看不到任何阴影效果。
所以如果通过设置水平或垂直方向的偏移量来改变阴影位置,那么我们将得到完美的单侧投影效果。
如果我们希望设置邻边投影,那怎么做呢?首先投影不能缩得太小,因此扩张半径设置为模糊半径的一半则好,另外需要设置水平和垂直偏移量,它的值应该大于或等于模糊半径的一半,举例来说:
div {
width: 1.6in;
height: 1in;
background: #fb3;
box-shadow: 3px 3px 6px -3px black;
}
双侧投影,如果我们要在左边和右边都设置投影,那该怎么实现?一块投影是解决不了问题,所以我们要用两块投影,代码如下:
div {
width: 1.6in;
height: 1in;
background: #fb3;
box-shadow: 3px 0 6px -3px black,
-3px 0 6px -3px black;
}
2.不规则投影
请看下面一张效果图:
它们都是不规则的图形,如果我们给它们应用box-shadow
,那么得到的效果将是这种:
他并没有给我们用伪元素生成的右三角生成阴影,这是因为默认box-shadow
会忽略掉透明部分,好在我们可以通过filter
这个属性解决它,但可能浏览器支持程度不够好,具体代码为:
div {
-webkit-filter: drop-shadow(.1em .1em .1em rgba(0,0,0,.5));
filter: drop-shadow(.1em .1em .1em rgba(0,0,0,.5));
}
这里的drop-shadow
和box-shadow
效果类似,只不过没有扩张半径以及inset
关键字,类似的函数还有blur
和grayscale
3.染色效果
染色效果我们需要用到滤镜效果filter
,这是一个工作草案,目前还没有完全支持,它支持多个函数传入从而改变图像的染色效果,包括blur
,invert
等函数,具体点击这里,加入我们下面一张原始图片,我们想对他进行模糊处理:
代码为:
img {
-webkit-filter: blur(1);
filter: blur(1px);
}
效果:
除了filter
,我们还可以使用混合,类似于ps软件中的一样,将多种颜色混合在一起,从而达到我们适合的颜色效果,要对一个元素设置混合选项,有两个元素可以用上:mix-blend-mode
以及background-blend-mode
可以设置值为luminosity
达到混合效果,其中mix-blend-mode
需要一个父级元素,类似这样:
<a href=''>
<img src=''>
</a>
a{
background: red;
}
img{
mix-blend-mode: luminosity;
}
而第二个则不需要父级元素包裹住,直接作用于目标元素。
5.折半效果
如果我们要实现下面这种效果,那怎么实现?
我们可以通过CSS的渐变以及偏移实现,具体代码如下:
div{
background:
linear-gradient(to left bottom, transparent 50%, rgba(0,0,0,.4) 0) no-repeat 100% 0 / 2em 2em,
linear-gradient(-135deg, transparent 2em, #58a 0);
}
上面的第一个渐变会产生一个下三角的背景图:
第二个渐变会产生折页的效果,类似下面:
最终的效果是这样的:
突然发现这里没有对齐,为什么?在第一个渐变上面我们设置宽高都是2em
,由于进行了旋转,所以最终的宽度其实是斜边上的高,也就是2em/ √2
,初中几何问题,等腰直角三角形斜边上的高等于任意一边的1/√2:
在第二个渐变里面我们进行了旋转,所以我们设置的长度是多少就是斜边上的长度:
当没有进行旋转的时候,透明部分的高度是第一个图里面的阴影部分,也就是2em
,当进行旋转的时候,我们的四边形的高度就变成了DI
直线的长度。
因此我们的这两个的高度度是不相等的,导致对不齐,所以我们只需要:
减少第二个线性渐变的高度让它和第一个的高度的相等,也就是除以√2,即2/√2=1.414
, 取整为1.5
。
另一种就是让第一个线性渐变的高度等于2em
,也就是对其宽高都乘以√2倍,以此使得斜边上的高为2em
,刚好对其。
在这里我们采用第一种方案,代码如下:
div{
background:
linear-gradient(to left bottom, transparent 50%, rgba(0,0,0,.4) 0) 100% 0 no-repeat,
linear-gradient(-135deg, transparent 1.5em, #58a 0);
background-size: 2em 2em, auto;
}
知道了这个原理后,就可以通过正弦余弦函数求得任意角度的折角效果,这里不在赘述。
但是这看起来似乎很僵硬,我们换一种实现的方法,通过伪元素实现:
div::before {
content: '';
position: absolute;
top: 0; right: 0;
width: 1.73em; height: 3em;
background: linear-gradient(to left bottom, transparent 50%, rgba(0,0,0,.2) 0, rgba(0,0,0,.4)) 100% 0 no-repeat;
transform: translateY(-1.3em) rotate(-30deg);
transform-origin: bottom right;
border-bottom-left-radius: .5em;
box-shadow: -.2em .2em .3em -.1em rgba(0,0,0,.15)
}
效果看起来似乎更加合理一点:
详情可查看这个demo。