css 毛玻璃_css揭秘-视觉效果

8e6c7859fb3ba54d111d3c8a6549a0a1.png

单侧投影

难题

box-shadow 如何在元素的一侧(偶尔是两侧)设置投影。

单侧投影

大多数人使用 box-shadow 的方法是,指定三个长度值和一个颜色值:

box-shadow

box-shadow 的绘制原理:

  1. 以该元素相同的尺寸和位置,画一个 rgba(0,0,0,.5) 的矩形;
  2. 把它向右移 2px,向下移 3px;
  3. 使用模糊算法将它进行 4px 的模糊处理;
  4. 将模糊后的矩形与原始元素的交集部分会被切除掉。

a1c095c992c98dad34812daa2883b2fe.png

使用 4px 的模糊半径意味着投影的尺寸会比元素本身的尺寸大约 8px ,因此投影的最外圈会从元素的四面向外显露出来,只需改变偏移量,就可以把投影的顶部和左侧隐藏起来,只要这两个方向上的偏移量不小于4px 就可以了。但是,这在某种程度上会导致外露的投影太过浓重,看起来不是很美观。另外,就算这个问题勉强可以接受,但跟想要的投影在单侧的不相符。

最终的解决方案来自 box-shadow 的第四个长度参数,排在模糊半径参数的后面,称作扩张半径。这个参数会根据指定的值去扩大(当指定值为负数)缩小投影的尺寸。举例来说:一个 -5px 的扩张半径会把投影的宽度和高度各减少 10px。因此,下面代码即为想要的效果:

box-shadow

c01a28b3cff9f574a6c8214b87454e4e.png
下右上左投影的矩形

邻边投影

box-shadow

a1fb46be9bb0b7f421b6740ccaff5382.png
两种邻边投影以及双侧投影

双侧投影

因为扩张半径在四个方向上的作用是相等的(即无法指定投影在水平方向上放大,而在垂直方向上缩小),唯一的办法是用两块投影(每边各一块)来达到目的。

box-shadow

不规则投影

难题

给一个矩形或者其他能用 border-radius 生成的形状加投影时,box-shadow 的表现都堪称完美。但是当元素添加了一些伪元素或者半透明的装饰后,box-shadow 就有点力不从心了。这类情况包括:

  • 半透明图像、背景图像、或者 border-image;
  • 元素设置了点状、虚线或半透明的边框,但没有背景;
  • 对话气泡,它的小尾巴通常是用伪元素生成的;
  • 在“切角效果”一节中见过的切角形状;
  • 几乎所有的折角效果,包括“折角效果”一节将提到的例子;
  • 通过 clip-path 生成的形状,比如“菱形图片”一节中提到的菱形图像。

如果对这些元素使用 box-shadow 则会得到如下所示的效果。

cb6a85c718658df727818e524724632e.png
图中 box-shadow 的值为:2px 2px 10pxrgba(0,0,0,.5)

解决方案

滤镜效果规范为这个问题提供了一个解决方案,它引入了一个叫作 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
原图以及加了不同滤镜的图片展示

此时,就把图片的色调改变了,如果这个效果需要由 :hover 或其他状态来触发切换,还可以为这个变化增加过渡动画:

img 

68db97cac8c203c4e5cb731276c0a0dd.gif

基于混合模式的方案

对一个元素设置混合模式,有两个属性可以使用:mix-blend-mode 可以为整个元素设置混合模式,background-blend-mode 可以为每层背景单独指定混合模式。因此有两种:

  1. 把图片包裹在一个容器中,并把容器的背景色设置为想要的主色调。
  2. 不用图片元素,而是用 <div> 元素——把这个元素的第一层背景设置为要染色的图片,并把第二层的背景设置为想要的主色调。
<

滤镜是可动画的,而混合模式则不是!

<

170ad7c9afea763715e504203e345d15.gif
使用div 实现动画

上述两种方法可以实现滤镜,但是都不够理想:

  • 图片的尺寸需要在 CSS 代码中写死;
  • 在语义上,这个元素并不是一张图片,因此并不会被读屏器之类的设备读出来。

毛玻璃效果

难题

半透明颜色最初的使用场景之一就是作为背景。将其叠放在照片类或其他花哨的背层之上,可以减少对比度,确保文本的可读性。在传统的平面设计中,这个问题的解决方案通常是把文本层所覆盖的那部分图片区域作模糊处理。

借助 blur() 滤镜,我们在 CSS 中获得了对元素进行模糊处理的能力。如果直接使用 blur() 滤镜,整个元素都会被模糊,文本反而变得更加无法阅读了。有没有某种方法可以只对元素的背层(即被该元素遮住的那部分背景)应用这个滤镜呢?

解决方案

不能直接对元素本身进行模糊处理,就对一个伪元素进行处理,然后将其定位到元素的下层,它的背景将会无缝匹配 <body> 的背景。

<

2e911e8e28331fd98a76ef8eec5c05b5.png

折角效果

难题

把元素的一个角(通常是右上角或右下角)处理为类似折角的形状,再配上或多或少的拟物样式,这种效果已经成为一种非常流行的装饰手法。

已实现的方法的原理通常是在右上角增加两个三角形:一个三角形用来体现折页的形状,另一个白色的三角形遮住元素的一角,用来模拟翻折所产生的缺口。这两个三角形通常都是由经典的边框技巧来生成的。

但是,当折角元素下不是纯色或者折角不是45°时,已有的方案就不能满足了。

45°折角的解决方案

在矩形的右上角创建一个大小为 0.5em 的斜面切角,代码为:

background

接下来所需要做的就是增加一个暗色的三角形来实现翻折效果。实现方法是增加另一层渐变来生成这个三角形并将其定位在右上角,这样就可以通过 background-size 来控制折角大小。

background

但是,看到折角并不是所期望的样子,第二层渐变中的 2em 折角尺寸是写在色标中的,因此它是沿着渐变轴进行度量的,是对角线尺寸;而 background-size 中的 2em 长度是背景贴片的宽度和高度,是在水平和垂直方向上进行度量的。因此为了使两者对齐:

  1. 如果要保留对角线的 2em 长度,就要将 background-size 乘以 2 。
  2. 如果要保留水平和垂直方向上的 2em 长度,就要用切角渐变的角标位置值除以 √2 。

因为 background-size 使用了两次长度,因此使用第二种方案更合适,因此其值为2/√2。

background

f57cededa65f46431cb6d1714b9fd1b5.png
折角的变换

其他角度的解决方案

.

5e41890e24df20b3b30e63d65cae0ebb.png
更贴近实际的折角

mixin的写法

@mixin
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值