高级CSS特效解析其示范案例
1. 概述
2. 形状特效
2.1 概述
HTML 元素天生就是方形的,在博文玩转CSS盒子之 三角形盒子我们讨论了依赖border
、transparent
等属性让盒子看上去成为三角形,类似的思路我们还能绘少量其它简单图形。但是这些总归是基于盒模型最基础的方式,很多效果仍然无法实现。在本节我们要介绍的是 CSS 中提供给我们基于 shape
相关属性用法,它能帮助我们实现更丰富的图形与特殊效果。
属性 | 描述 | 说明 |
shape-inside |
该属性允许你将内容包装到一个形状中 | 目前主流浏览器中尚未实现该属性 |
shape-outside |
该属性定义了一个可以是非矩形的形状,相邻的内联内容应围绕该形状进行包装。 | |
shape-margin |
该属性用于设定由 shape-outside 创建的CSS形状的外边距。 |
|
shape-image-threshold |
该属性通过设定一个 alpha通道 的界限值来提取 shape-outside 值为图像的形状。 |
2.2 shape-outside
属性
2.2.1 属性解析
该属性定义了一个可以是非矩形的形状,相邻的内联内容应围绕该形状进行包装。 默认情况下,内联内容包围其边距框。shape-outside
属性提供了一种自定义此包装的方法,可以将文本包装在复杂对象周围而不是简单的框中。
语法
/* 关键字值 */ shape-outside: none; /* 该浮动区域不产生影响,行内元素以默认的方式包裹着该元素的margin box。 */ shape-outside: margin-box; /* 定义一个由外边距的外边缘封闭形成的形状。这个形状的角的半径由相应的border-radius 和margin 的值决定。 */ shape-outside: content-box; /* 定义一个由内容区域的外边缘封闭形成的形状,每一个角的弧度取 0 或 border-radius - border-width - padding 中的较大值。 */ shape-outside: border-box; /* 定义一个由边界的外边缘封闭形成的形状。 这个形状遵循正常的边界外部圆角的形成规则。 */ shape-outside: padding-box; /* 定义一个由内边距的外边缘封闭形成的形状。这个形状遵循正常的边界内部圆角的形成规则。 */ /* 函数值,参见 2.2.2节:形状函数 */ shape-outside: circle(); shape-outside: ellipse(); shape-outside: inset(10px 10px 10px 10px); shape-outside: polygon(10px 10px, 20px 20px, 30px 30px); /* <url> 值 */ shape-outside: url(image.png); /* 渐变值 */ shape-outside: linear-gradient(45deg, rgba(255, 255, 255, 0) 150px, red 150px); /* 全局值 */ shape-outside: initial; shape-outside: inherit; shape-outside: unset;
其中shape-outside
属性的值可以是 关键字值、函数值 、<url>
值 和 渐变值 等
示例:使用(形状)函数作为属性值
<div class="box"> <div class="left"></div> <div class="right"></div> <p> China launched a Long March 11 solid-propellant carrier rocket on Wednesday morning from the Jiuquan Satellite Launch Center in Northwest China, deploying three satellites into space, according to China Aerospace Science and Technology Corp (CASC). The rocket blasted off at 10:29 am and soon placed the Tianping 2A, 2B and 2C satellites into their planned orbit. </p> </div> <style lang="scss"> .box { width: 460px; margin: auto; .left { float: left; shape-outside: polygon(0 0, 100% 100%, 0 100%); clip-path: polygon(0 0, 100% 100%, 0 100%); } .right { float: right; shape-outside: polygon(100% 0, 100% 100%, 0 100%); clip-path: polygon(100% 0, 100% 100%, 0 100%); } .left, .right { width: 40%; height: 12ex; background-color: rgb(91, 208, 143); border-radius: 69%; } } </style>
其效果如下:
【解析】:
在这个案例中,我们首先使用了浮动将 left
和 right
两个 HTML 元素浮动于父元素 box
两端,看起来效果是这样的:
给左右两个盒子加一个圆角属性,看起来是这样的:
可以发现,文字并没有围绕该形状进行包装。于是使用我们的 shape-outside
属性:
shape-outside: polygon(100% 0, 100% 100%, 0 100%);
关于polygon()
请阅读下一节 形状函数 。现在效果变成了这样:
另外最后我们使用了clip-path
属性,该属性使用裁剪方式创建元素的可显示区域以达到区域内的部分显示,区域外的隐藏的效果,详细参考 3. 剪切效果 小节。在这里哦我们剪裁去了多余的部分得到了最终的效果。
2.2.2 形状函数
在上一小节中我们使用了一个简单的案例展了 shape-outside
属性 的用法,其中使用了一个名为polygon()
的CSS自带函数,这个函数属于本节讲解的 形状函数 之一,这些 形状函数 为我们提供了绘制各类形状的能力,其CSS数据类型为 <basic-shape>
。他们基于 inset()
, circle()
, ellipse()
, 或者 polygon()
其中一个创造出来的形状计算出浮动区域。<basic-shape>
类型的这些形状函数除了可以作为本节 shape-outside
属性的值,还可以作为 第3 节 中clip-path 的值。
2.2.1 inset() 函数
<basic-shape>
数据类型的一个函数,它定义了一个插入矩形。
语法
inset( <shape-arg>{1,4} [round <border-radius>]? )
参数 | 描述 |
<length-percentage>{1,4} |
当提供了所有四个参数时,它们表示从参考框向内的上、右、下和左偏移,定义了插入矩形的边缘位置。这些参数遵循margin速记的语法,允许您用一个、两个或四个值设置所有四个insets。 |
<border-radius> |
可选的 border-radius 参数使用边框半径速记语法为插入矩形定义圆角。 |
例如:
shape-outside: inset(20px 50px 10px 0 round 50px);
例子
效果如下:
2.2.2 circle() 函数
<basic-shape>
数据类型的一个函数,用于绘制圆。
语法
circle( [<shape-radius>]? [at <position>]? )
参数 | 描述 |
<shape-radius> |
代表了 圆形的半径r , 不接受负数作为该参数的值。一个以百分比表示的值将以公式 s q r t ( w i d t h 2 + h e i g h t 2 ) / s q r t ( 2 ) sqrt(width^2+height^2)/sqrt(2)sqrt(width2+height2)/sqrt(2)计算,其中width与height为相关盒模型的宽与高。 |
<position> |
定义了圆心的位置。省缺值为盒模型的中心。 |
2.2.3 ellipse() 函数
<basic-shape>
数据类型的一个函数,用于绘制椭圆。
语法
ellipse( [<shape-radius>{2}]? [at <position>]? )
参数 | 描述 |
<shape-radius> 参数 |
代表了 rx 与 ry , |
其中:
rx
代表了x
轴方向的半径;ry
代表了y
轴方向的半径。
该参数不接受负数值。以百分比表示的长度将把盒模型的宽与高作为参照,宽作为 rx 的参照值,高作为 ry 的参照值。
2.2.4 polygon() 函数
<basic-shape>
数据类型的一个函数,用于绘制多边形。
语法
polygon( [<fill-rule>,]? [<shape-arg> <shape-arg>]# )
<fill-rule>
表示填充规则,指定用于确定多边形内部的填充规则。可以是非零或偶数。默认值为非零。<shape-arg>
:表示形状参数,这可以通过以下任一方式指定:
<length>
: - 用于指定要使用的<length>
值(例如 px、em、vw 等)作为半径。<percentage>
: - 用于指定要使用的<percentage>
值。百分比值使用参考框的宽度和高度。
2.2.3 使用关键字值
2.2.4 使用渐变值
2.3 shape-margin
属性
该属性用于设定由shape-outside创建的CSS形状的外边距,这个外边距可以让你调整(浮动元素的)形状边缘与环绕内容之间的距离。
例如:
<section> <div class="shape"></div> Greater effort will be paid to training intellectual property specialists, the most fundamental, core and critical element in helping our country become a global center of IPR, an official from the country's top IPR regulator said. "As we train more specialists, we plan to optimize the system by paying close attention to education on IPR protection, application, public services and international affairs," Feng Zhaolong, from the National Intellectual Property Administration's Personnel Department, told a news conference on Wednesday. </section> <style lang="scss"> section { max-width: 400px; margin: auto; .shape { float: left; width: 150px; height: 150px; background-color: rgb(0, 128, 38); clip-path: polygon(0 0, 150px 150px, 0 150px); shape-outside: polygon(0 0, 150px 150px, 0 150px); } } .sm-30{ shape-margin: 30px; } .sm-60{ shape-margin: 60px; } </style>
现在,逐个将sm-xx
放入 shape div 中:
<div class="shape"></div>
效果为:
<div class="shape sm-30"></div>
效果为:
<div class="shape sm-60"></div>
效果为:
2.4 shape-image-threshold
属性
该属性通过设定一个 alpha通道
的界限值来提取 shape-outside
值为图像的形状。所有 alpha值
比这个界限值大的像素都会被当做形状的一部分,以此确定形状的边界。例如,界限值为 0.5 时,形状会包含所有不透明度超过50%的像素。
2.4.1 阿尔法通道
参考自百度百科,更详细请看原文:https://baike.baidu.com/item/alpha%E9%80%9A%E9%81%93/3163191?fr=aladdin
阿尔法通道(α Channel或Alpha Channel)是指一张图片的透明和半透明度。由于每个像素再增加一个 Alpha 通道,取值为0到1,用来储存这个像素是否对图片有“贡献”,0
代表透明、1
代表不透明,这样Alpha 通道储存一个值,其外在表现是透明度,但 α 本身没有透明度的意思。
例如一个使用16位存储的图片,可能5位表示红色,5位表示绿色,5位表示蓝色,1位是阿尔法。在这种情况下,它要么表示透明要么不是。一个使用32位存储的图片,每8位表示红绿蓝,和阿尔法通道。在这种情况下,就不光可以表示透明还是不透明,阿尔法通道还可以表示256级的半透明度。
2.4.2 属性语法
/* <length> 值 */ shape-margin: 10px; shape-margin: 20mm; /* <percentage> 值 */ shape-margin: 60%; /* Global 值 */ shape-margin: inherit; shape-margin: initial; shape-margin: unset;
2.4.3 例子
3. 剪切效果
3.1 效果描述
属性 | 描述 | 说明 |
clip |
该属性定义了元素的哪一部分是可见的,但只适用于 position:absolute 的元素 |
已废弃: 该特性已经从 Web 标准中删除,虽然一些浏览器目前仍然支持它,但也许会在未来的某个时间停止支持,请尽量不要使用该特性。 |
clip-path |
该属性使用裁剪方式创建元素的可显示区域。 区域内的部分显示,区域外的隐藏。 |
3.2 clip-path
属性
3.3 使用 SVG 属性
只需要通过URL引入一个<clipPath>元素,clip-path
属性还可以使用 SVG 文档剪切元素。你可以借助 Adobe Illustrator、Inkscape绘图软件创建想要的形状。
3.3.1 clipPath
SVG 元素 <clipPath>
定义一条剪切路径,可作为其他元素的 clip-path
属性的值。剪切路径限制了图形的可见范围。从概念上来说,如果图形超出了当前剪切路径所包围的区域,那么超出部分将不会绘制。
从概念上讲,剪切路径等于给引用元素设置了一个自定义的可视区域。因此,它虽然会影响一个元素的绘制,但不会影响这个元素本身的几何形状,比如被剪切元素(通过 clip-path 属性引用了 的元素及其子元素)的包围盒和没有被剪切时相同。
<svg viewBox="0 0 100 100"> <-- 定义一条剪切路径 --> <clipPath id="myClip"> <!-- 圆圈外的所有东西都会被裁剪掉,因此不可见。 --> <circle cx="40" cy="35" r="35"></circle> </clipPath> <!-- 作为引用元素(英文原文:for reference)的黑色心形 --> <path id="heart" d="M10,30 A20,20,0,0,1,50,30 A20,20,0,0,1,90,30 Q90,60,50,90 Q10,60,10,30 Z"></path> <!-- 和上述黑色心形形状相同的红色心形,剪切路径是上面定义的圆; 红色心形只有在圆内的部分可见。--> <use clip-path="url(#myClip)" xlink:href="#heart" fill="red"></use> </svg>
3.3.2 ------------
这是一个使用 绘制的SVG图形,它将被用作为 剪切源。用文本编辑器打开后可以看到代码大概如下:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="65.011909mm" height="63.5mm" viewBox="0 0 65.011909 63.5" version="1.1" id="svg8"> <defs id="defs2" /> <g id="layer1" transform="translate(-2.8606183,-2.2678528)"> <ellipse style="opacity:0.999;fill:#2f60e8;fill-opacity:0.414226;stroke-width:0.0740937" id="path902" cx="34.376438" cy="33.545383" rx="20.530245" ry="21.828125" /> <ellipse style="opacity:0.999;fill:#bfc253;fill-opacity:0.414226;stroke-width:0.0740937" id="path924" cx="34.773808" cy="34.518612" rx="30.994047" ry="5.8393712" /> </g> </svg>
下一步就是将图片转换为剪切路径了,如前所述,只需要将 SVG 代码块内容包装在一个 <clipPath>
元素中,并添加一个 id
属性。也就是这样的:
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="65.011909mm" height="63.5mm" viewBox="0 0 65.011909 63.5" version="1.1" id="svg8"> <clipPath id="svgclip"> <defs id="defs2" /> <g id="layer1" transform="translate(-2.8606183,-2.2678528)"> <ellipse style="opacity:0.999;fill:#2f60e8;fill-opacity:0.414226;stroke-width:0.0740937" id="path902" cx="34.376438" cy="33.545383" rx="20.530245" ry="21.828125" /> <ellipse style="opacity:0.999;fill:#bfc253;fill-opacity:0.414226;stroke-width:0.0740937" id="path924" cx="34.773808" cy="34.518612" rx="30.994047" ry="5.8393712" /> </g> </clipPath> </svg>
现在我们就可以在CSS中引用该SVG中的这个剪切路径了。
4. 蒙版效果
4.1 效果描述
蒙版效果最早出现在于2008年出现的Safari浏览器中的一个非标准属性——-webkit-mask-image
,该属性使用一张图片作为其蒙版元素透明层次的来源。对于用作蒙版的图片:
- 每一个像素都有一个透明度(阿尔法级别);
- 若蒙版图片中的像素是透明的,那么加蒙版元素中对应的像素也不可见;
- 反之,蒙版图片中像素完全不透明的区域,对应的加蒙版元素区域则完全可见。
如今蒙版相关属性已经得到表遵化和扩展,像clip-path
属性一样,SVG中的蒙版也可以应用到HTML内容。
4.2 mask-image
属性
(此属性在标准中仍属于实验阶段)
该属性用于设置元素上蒙版的图像。
语法示范
/* 键值 */ mask-image: none; /* <mask-source> 值 */ mask-image: url(masks.svg#mask1); /* <image> 值 */ mask-image: linear-gradient(rgba(0, 0, 0, 1.0), transparent); mask-image: image(url(mask.png), skyblue); /* 多个值 */ mask-image: image(url(mask.png), skyblue), linear-gradient(rgba(0, 0, 0, 1.0), transparent); /* Global 值 */ mask-image: inherit; mask-image: initial; mask-image: unset;
其中,其值的类型为<mask-source>
,默认值为none
。<mask-source>
可以是:
<mask>
或CSS图像的url
;<image>
数据类型用于表示一个图形。
例子
现在我有一张背景图,和一个SVG形状图:
其中SVG代码是这样
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" id="svg2" viewBox="0 0 99.999997 99.999997" height="100" width="100"> <defs id="defs4" /> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title></dc:title> </cc:Work> </rdf:RDF> </metadata> <g transform="translate(0,-952.36223)" id="layer1"> <path d="M 50.000001,954.80939 65.450848,986.11624 100,991.13652 74.999998,1015.5055 80.901699,1049.915 50,1033.6691 19.098298,1049.915 25.000001,1015.5055 -1.2134336e-6,991.13652 34.549151,986.11624 Z" id="path4136" style="opacity:1;fill:#000000;fill-opacity:0.50222224;stroke:none;stroke-width:22.67716599;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </g> </svg>
现在
<div class="box"> <div class="masked"></div> </div> <style scoped lang="scss"> .box{ width: 600px; height: 600px; .masked { width: 100%; height: 100%; background-image: url(../assets/img/backr.png); background-repeat:no-repeat; background-size:100%; mask-image: url(../assets/img/star.svg); -webkit-mask-image: url(../assets/img/star.svg); } } </style>
其效果如下:
.
5. 混合效果
5.1 混合效果简介
在图像的处理中,我们使用一些方式将源图片与目标图片进行叠加处理,采用不同的处理算法、选取不同的叠加参数,从而得到更多精致、优美、绚丽丰富的图形效果。例如正片叠加,采用将 源图片每个颜色通道的值 X 目标图片每个相应颜色通道的值,得到叠加后图片的相应颜色通道值。在CSS中,我们可以通过mix-blend-mode
属性和background-blend-mode
属性来定义定义了背景层的混合模式。
5.1.1 mix-blend-mode
属性
该属性描述了元素的内容应该与元素的直系父元素的内容和元素的背景如何混合,其语法格式如下:
mix-blend-mode: <blend-mode>;
其中<blend-mode>
类型的值可以是以下:
属性值 | 表达 | 描述 | 说明 |
normal |
B ( C b , C s ) = C s B(C_b, C_s) = C_sB(Cb,Cs)=Cs | 这是默认属性,指定没有混合。混合公式只是选择源颜色。 | - |
multiply |
B ( C b , C s ) = C b × C s B(C_b, C_s) = C_b \times C_sB(Cb,Cs)=Cb×Cs | 源颜色乘以目标颜色,并替换目标颜色。 | 结果颜色总是至少与源颜色或目标颜色一样暗。将任何颜色与黑色相乘都会得到黑色。将任何颜色与白色相乘都会保留原始颜色。 |
screen |
B ( C b , C s ) = 1 − [ ( 1 − C b ) × ( 1 − C s ) ] = C b + C s − ( C b × C s ) B(C_b, C_s) = 1 - [(1 - C_b) \times (1 - C_s)]= C_b + C_s -(C_b \times C_s)B(Cb,Cs)=1−[(1−Cb)×(1−Cs)]=Cb+Cs−(Cb×Cs) | 将背景色和源色值的补码相乘,然后对结果进行补码。 | 结果颜色总是至少与两种组成颜色中的任何一种颜色一样亮。用白色筛选任何颜色都会产生白色;用黑色加网会保持原来的颜色不变。其效果类似于将多张照片幻灯片同时投影到一个屏幕上。 |
overlay |
B ( C b , C s ) = H a r d L i g h t ( C s , C b ) B(C_b, C_s) = HardLight(C_s, C_b)B(Cb,Cs)=HardLight(Cs,Cb) | 根据背景颜色值,增加或屏蔽颜色。 | 源颜色覆盖背景,同时保留其高光和阴影。背景色不会被替换,而是与源色混合,以反映背景的明暗程度。overlay 是 hard-light 模式的反转。 |
darken |
B ( C b , C s ) = m i n ( C b , C s ) B(C_b, C_s) = min(C_b, Cs)B(Cb,Cs)=min(Cb,Cs) | 选择较暗的背景色和源色。 | 背景被替换为较暗的源;否则,保持不变。 |
lighten |
B ( C b , C s ) = m a x ( C b , C s ) B(C_b, C_s) = max(C_b, C_s)B(Cb,Cs)=max(Cb,Cs) | 选择背景色和源色中较浅的一种。背景被替换为光源较亮的地方的光源;否则,保持不变。 | 如果超出范围,结果必须向下舍入。 |
color-dodge |
if (C b = = 0 C_b == 0Cb==0):B ( C b , C s ) = 0 B(C_b, C_s) = 0B(Cb,Cs)=0 else if (C s = = 1 C_s == 1Cs==1):B ( C b , C s ) = 1 B(C_b, C_s) = 1B(Cb,Cs)=1 else :B ( C b , C s ) = m i n ( 1 , C b / ( 1 − C s ) ) B(C_b, C_s) = min(1, C_b / (1 - C_s))B(Cb,Cs)=min(1,Cb/(1−Cs)) |
使背景颜色变亮以反映源颜色。 | 用黑色绘画不会产生变化。 |
color-burn |
if (C b = = 1 C_b == 1Cb==1):B ( C b , C s ) = 1 B(C_b, C_s) = 1B(Cb,Cs)=1 else if (C s = = 0 C_s == 0Cs==0):B ( C b , C s ) = 0 B(C_b, C_s) = 0B(Cb,Cs)=0 else :B ( C b , C s ) = 1 − m i n ( 1 , ( 1 − C b ) / C s ) B(C_b, C_s) = 1 - min(1, (1 - Cb) / Cs)B(Cb,Cs)=1−min(1,(1−Cb)/Cs) |
使背景颜色变暗以反映源颜色。用白色绘画不会产生变化。 | - |
hard-light |
if (C s < = 0.5 C_s <= 0.5Cs<=0.5):B ( C b , C s ) = M u l t i p l y ( C b , 2 × C s ) B(C_b, C_s) = Multiply(C_b, 2 \times C_s)B(Cb,Cs)=Multiply(Cb,2×Cs) else :B ( C b , C s ) = S c r e e n ( C b , 2 × C s − 1 ) B(C_b, C_s) = Screen(C_b, 2 \times C_s -1)B(Cb,Cs)=Screen(Cb,2×Cs−1) |
根据源颜色值,增加或屏蔽颜色。 | 这种效果类似于将刺眼的聚光灯照射在背景上。 |
soft-light |
if (C s < = 0.5 C_s <= 0.5Cs<=0.5):B ( C b , C s ) = C b − ( 1 − 2 × C s ) × C b × ( 1 − C b ) B(C_b, C_s) = C_b - (1 - 2 \times C_s) \times C_b \times (1 - C_b)B(Cb,Cs)=Cb−(1−2×Cs)×Cb×(1−Cb) else :B ( C b , C s ) = C b + ( 2 × C s − 1 ) × ( D ( C b ) − C b ) B(C_b, C_s) = C_b + (2 \times C_s - 1) \times (D(C_b) - C_b)B(Cb,Cs)=Cb+(2×Cs−1)×(D(Cb)−Cb) with :if (C b < = 0.25 C_b <= 0.25Cb<=0.25):D ( C b ) = ( ( 16 ∗ C b − 12 ) x C b + 4 ) x C b D(Cb) = ((16 * Cb - 12) x Cb + 4) x CbD(Cb)=((16∗Cb−12)xCb+4)xCb else :D ( C b ) = s q r t ( C b ) D(Cb) = sqrt(Cb)D(Cb)=sqrt(Cb) |
根据源颜色值,使颜色变暗或变亮。 | 这种效果类似于将漫射聚光灯照射在背景上。 |
difference |
B ( C b , C s ) = ∥ C b − C s ∥ B(C_b, C_s)=\| C_b - C_s \|B(Cb,Cs)=∥Cb−Cs∥ | 从较亮的颜色中减去两种组成颜色中较暗的颜色。 | 用白色绘画会反转背景色;用黑色绘画不会产生变化。 |
exclusion |
B ( C b , C s ) = C b + C s − 2 × C b × C s B(C_b, C_s) = C_b + C_s - 2 \times C_b \times C_sB(Cb,Cs)=Cb+Cs−2×Cb×Cs | 产生的效果类似于差异模式,但对比度较低。 | 用白色绘画会反转背景色;用黑色绘画不会产生变化。 |
hue |
B ( C b , C s ) = S e t L u m ( S e t S a t ( C s , S a t ( C b ) ) , L u m ( C b ) ) B(C_b, C_s) = SetLum(SetSat(C_s, Sat(C_b)), Lum(C_b))B(Cb,Cs)=SetLum(SetSat(Cs,Sat(Cb)),Lum(Cb)) | 使用源颜色的色调和背景颜色的饱和度和亮度创建颜色。 | - |
saturation |
B ( C b , C s ) = S e t L u m ( S e t S a t ( C b , S a t ( C s ) ) , L u m ( C b ) ) B(C_b, C_s) = SetLum(SetSat(C_b, Sat(C_s)), Lum(C_b))B(Cb,Cs)=SetLum(SetSat(Cb,Sat(Cs)),Lum(Cb)) | 使用源颜色的饱和度和背景颜色的色调和亮度创建颜色。 | 使用此模式在纯灰色(无饱和度)的背景区域中绘画不会产生任何变化。 |
color |
B ( C b , C s ) = S e t L u m ( C s , L u m ( C b ) ) B(C_b, C_s) = SetLum(C_s, Lum(C_b))B(Cb,Cs)=SetLum(Cs,Lum(Cb)) | 使用源颜色的色调和饱和度以及背景颜色的亮度创建颜色。 | 这将保留背景的灰度,对于单色图像着色或彩色图像着色非常有用。 |
luminosity |
B ( C b , C s ) = S e t L u m ( C b , L u m ( C s ) ) B(C_b, C_s) = SetLum(C_b, Lum(C_s))B(Cb,Cs)=SetLum(Cb,Lum(Cs)) | 使用源颜色的亮度和背景颜色的色调和饱和度创建颜色。这会产生与颜色模式相反的效果。 | - |
5.1.2 background-blend-mode
属性
该属性定义该元素的背景图片以及背景色如何混合,混合模式应该按 background-image
CSS属性同样的顺序定义。如果混合模式数量与背景图像的数量不相等,它会被截取至相等的数量。其语法格式如下:
background-blend-mode: <blend-mode>
其中<blend-mode>
类型的值,可以参考 5.1.1 mix-blend-mode
属性 中的表格。
5.2 明度(luminionsity)及其应用
5.2.1 明度的概念
明度 一词有两方面的含义:
- 一方面表示亮度(brightness),即是眼睛对光源和物体表面的明暗程度的感觉,光线越强,看上去越亮;光线越弱,看上去越暗;
- 另一方面指颜色的明暗程度。不同的颜色,反射的光量强弱不一,因而会产生不同的明暗程度。
本质上看两种含义底层都归结于反射到人眼中光的强度。从混合的角度来看,所谓名度即将源图片中的像素亮度级别应用到目标图片对应像素的色相和饱和度。
.
5.3 滤色(screen)及其应用
.
5.4 隔离(isolation)及其应用
.
5.5 <blend-mode>
类型各值效果展示
6. 滤镜
与PhotoShop中的滤镜一样,CSS中的滤镜主要是用来实现各种特殊效果。CSS 标准里包含了一些已实现预定义效果的函数,使用 filter
属性,可以将这些已实现预定义效果的函数应用于一些元素的渲染上。
CSS 滤镜效果展示
6.1 亮度滤镜
6.2 透明度滤镜
6.3 饱和度滤镜
6.4 复古滤镜
6.5 阴影滤镜
6.6 颜色反转
6.7 灰度滤镜
6.7.1 灰度相关概念
把白色与黑色之间按对数关系分为若干等级,称为灰度,灰度分为256阶。黑白图片属于单色图片,也称灰度图(Gray Scale Image)。任何颜色都由红、绿、蓝 三原色组成,而灰度图只有一个通道,他有256个灰度等级,255代表全白,0表示全黑。
6.7.2 CSS grayscale()
函数
CSS 为我们提供了 grayscale()
函数用于将元素实现灰度化。其语法结构为:
grayscale(amount)
参数 | 描述 |
amount |
表示转换的数值,指定为<number> 或<percentage> 类型。值100%完全是灰度,而值0%保持输入不变。介于0%和100%之间的值是效果的线性乘数。省略时,默认值为1。插值的初始值为0。 |
例如
我们打开了一个外部的某知名网站,点击 F12 快捷键以打开开发人员工具。
图 某站点在使用灰度处理前的样子
在body
的样式声明中使用 grayscale()
函数,增新一条 灰度滤镜 规则,为该站点开启 悼念模式:
于是,该站点立马进入了如下灰度模式:
图 灰度滤镜实现网站特效(看到这里的记得先点个赞加收藏哦...)
6.8 色相旋转
6.8.1 色相的概念
色相是区别各种不同色彩的最准确的标准,任何黑白灰以外的颜色都有色相的属性。色相也就是由原色、间色和复色来构成的。
- 【原色】 :是指不能通过其他颜色的混合调配而得出的基本色,原色以不同比例混合时,会产生其他颜色。
原色并非是一种物理概念,反倒是一种生物学的概念。由于人类肉眼有三种不同颜色的感光体,因此所见的色彩空间通常可以由三种基本色所表达,这三种颜色被称为“三原色”。一般来说叠加型三原色是RGB即光的三原色。消减型三原色是品红色、黄色、青色,即颜料的三原色。 - 【间色】:是指两种原色配合成的颜色,如红和黄配合成的橙色,黄和蓝配合成的绿色。
- 【复色】:是指用任何两个间色或三个原色相混合而产生出来的颜色,也被称为次色。
6.8.2 CSS hue-rotate()
函数
hue-rotate()
函数用于旋转一个元素的颜色和它的内容,其结果是一个<filter-function>
。其语法形式为:
hue-rotate(angle)
参数 | 描述 |
angle |
指定为角度值,表示输入样本色彩的相对变化。值为0度时,输入保持不变。正色调旋转增加色调值,负色调旋转减少色调值。插值的空隙值为0。没有最小值或最大值;色调旋转(Ndeg)计算结果为N模360。 |
比如:
hue-rotate(0deg) /* 无效果 */ hue-rotate(90deg) /* 90deg 旋转 */ hue-rotate(.5turn) /* 180deg 旋转 */ hue-rotate(-90deg) /* 与旋转 270deg 一样 */ hue-rotate(405deg) /* 与旋转 45deg 一样 */
6.8.3 色相旋转应用
色相旋转对于典型的圆形对称图案,可以给人产生一种图标再旋转的感觉,比如:
<img class="pic" src="../assets/img/pic.png"> <style scoped lang="scss"> .pic{ animation:huerotate 2s infinite; } @keyframes huerotate { 0% {filter: hue-rotate(0);} 13% {filter: hue-rotate(45deg);} 25% {filter: hue-rotate(90deg);} 36% {filter: hue-rotate(135deg);} 50% {filter: hue-rotate(180deg);} 63% {filter: hue-rotate(225deg);} 75% {filter: hue-rotate(270deg);} 88% {filter: hue-rotate(315deg);} 100% {filter: hue-rotate(360deg);} } </style>
看起来,效果是这样的:
初看一眼,似乎图形在旋转,然而图形是静止的,旋转的只有图形上颜色的色相。作为对比,我们旋转一下图标:
<img class="pic" src="../assets/img/pic.png"> <style scoped lang="scss"> .pic{ animation:contrast 2s infinite; } @keyframes contrast { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } </style>
看起来,效果是这样的:
6.9 模糊滤镜
6.9.1 高斯模糊
图像处理的背后是算法, 高斯模糊 是将数学和算法应用于图像处理的一个经典且基础的应用。我们这里顺带介绍 高斯模糊 的相关概念和原理,以启迪更多敏感的心扉。
像素
在图像的底层,图片是由一个一个的像素组成,像素是由图像的小方格组成的,这些小方块都有一个明确的位置和被分配的色彩数值,小方格颜色和位置就决定该图像所呈现出来的样子。当我们放大显示器的时候,可以看到彩色显示器底层由一个个 RGB 格子构成,这就是显示器中的最小单元——像素,如图所示。
高斯模糊也叫高斯平滑,它将正态分布(即高斯分布)用于图像处理,实际上是一种数据平滑技术。
一开始我们能想到的模糊,其实就是将每一个像素都取周边像素的平均值。例如由9个像素点:
将其每个像素点都取周围像素点的平均值,那么对于中间这个像素点而言,经过这样的处理后它将变成 4 。经过这样的处理在图形上中间点将失去细节,就相当于产生模糊效果。
基于这种方式计算像素平均值时, 像素取值范围越大,图像的模糊效果就越强烈,从数值角度看,就是数值越平滑。 [1]
我们之所以提出采用图像处理后的每个像素为原图片该像素周围像素的平均值,是基于我们对图像的像素变化是连续的认知。也或许有可能你只是从直觉上来说觉得可行,因此我们可以借用 克劳德·艾尔伍德·香农(Claude Elwood Shannon) 的 信息论来理解。
信息论中认为,信息的基本作用就是消除人们对事物 的不确定性。像素的组合方式表现得越无序 则 信息熵越大,也就是其中包含的信息量越小(或者说要进一步认识所需要得信息量更大)。日常生活中的照片显然是包含了很多信息的,这意味着图像上的像素点都必然依据某种特定的规律进行排列,因此在包含信息越密集的区域像素排列的混乱(无序)程序越小,也就是该区域某个像素与其周围值的突变
程度越小。这就是为什么越靠近的像素点之间关系越密切,越远离的点关系越疏远。
因此当我们简单使用临近的像素点之间的值做平均时,顺带而来了另外一个问题,我们应该取多大的范围 [2] 才能使得图像不丢失过多必要的信息——毕竟我们的目的并不是使图像完全无法辨别,只不过是想让它在丢失掉细节(模糊)而已。
当你时间过后就会发现似乎这个问题不那么容易被解决:只要平均范围取得越大,则该点接受更原理自己位置的像素点的扰动越大,因此区域每大一点,处理后的点失真就更加严重一点。
想到这里我们提出了另一个假设:真实图片上的某一点与其临近点之间的相似关系是存在权重的,这很好用之前的论述理解,信息越密集区域的一个点与越临近自己的点的相关性越大,这些点在进行加权平均时所应乘以的权数(系数)就越大,反之则越小。
数理统计学中,高斯分布(正太分布)是表示最无序时的分布,当我们没有更多条件认为某一点收到距离自己附近的点相似分布时,不妨就认为是随距离的远近呈现 高斯分布。 高斯分布曲线 看起来就像是这样:
6.9.2 CSS blur()
函数
blur()
函数将高斯模糊应用于输出图片,其语法结构为:
blur(radius)
参数 | 描述 |
radius | 模糊的半径,值为<length> 。它定义了高斯函数的标准偏差值,即屏幕上有多少像素相互融合; 因此,较大的值会产生更多模糊。 值为0会使输入保持不变。 该值为空则为0。 |
例如:
<div class="line" > <img class="blur1" src="../assets/img/Jclee.png"> <img class="blur2" src="../assets/img/Jclee.png"> <img class="blur3" src="../assets/img/Jclee.png"> <img class="blur4" src="../assets/img/Jclee.png"> <img class="blur5" src="../assets/img/Jclee.png"> </div> <div class="line" > <p>0</p> <p>1px</p> <p>2px</p> <p>0.3rem</p> <p>1.5rem</p> </div> <style scoped lang="scss"> .line{ display: flex; flex-direction: row; justify-content: center; p{ width: 200px; text-align: center; } } img{ height: 200px; width: 200px; &.blur1{ filter: blur(0); } &.blur2{ filter: blur(1px); } &.blur3{ filter: blur(2px); } &.blur4{ filter: blur(.3rem); } &.blur5{ filter: blur(1.5rem); } } </style>
其效果如下:
6.10 背景滤镜
我们可以直接将 CSS滤镜 应用到背景图片而无需预先使用 Photoshop 对图片进行预处理。要实现为背景添加相关滤镜效果只需要使用backdrop-filter
属性。
backdrop-filter
属性
该属性可以让你为一个元素后面区域添加图形效果(如模糊或颜色偏移)。因为它适用于元素背后的所有元素,为了看到效果,必须使元素或其背景至少部分透明。其语法格式为:
backdrop-filter: <filter-function-list>
其中<filter-function-list>
表示该属性值的CSS类型,表示一个以空格分隔的滤镜函数()或是要应用到背景上的 SVG 滤镜。例如:
/* 关键词值 */ backdrop-filter: none; // 表示没有应用于背景的滤镜。 /* 指向 SVG 滤镜的 URL */ backdrop-filter: url(commonfilters.svg#filter); /* <filter-function> 滤镜函数值 */ backdrop-filter: blur(2px); backdrop-filter: brightness(60%); backdrop-filter: contrast(40%); backdrop-filter: drop-shadow(4px 4px 10px blue); backdrop-filter: grayscale(30%); backdrop-filter: hue-rotate(120deg); backdrop-filter: invert(70%); backdrop-filter: opacity(20%); backdrop-filter: sepia(90%); backdrop-filter: saturate(80%); /* 多重滤镜 */ backdrop-filter: url(filters.svg#filter) blur(4px) saturate(150%); /* 全局值 */ backdrop-filter: inherit; backdrop-filter: initial; backdrop-filter: revert; backdrop-filter: unset;
6.11 与CSS变换(Transition)一起使用
本节的开头我们展示了一个 CSS变换常用于实现二状态动画,有关于CSS变换的内容可以参考博文《深挖基于 CSS 的变换与动画技术》。CSS滤镜的使用过程实际上是定义处理后的状态的过程,已经定义,渲染引擎将元素的原状态变化到一个通过滤镜处理后的状态。很庆幸这个变化的中间状态是可以像宽度、高度等等属性一样,通过transition
属性指定相关值缓慢地呈现出来的。例如:
例如:
<div class="line"> <img class="i1" src="../assets/img/JackLee.png"> <img class="i2" src="../assets/img/JackLee.png"> <img class="i3" src="../assets/img/JackLee.png"> <img class="i4" src="../assets/img/JackLee.png"> </div> <div class="line"> <img class="i5" src="../assets/img/JackLee.png"> <img class="i6" src="../assets/img/JackLee.png"> <img class="i7" src="../assets/img/JackLee.png"> <img class="i8" src="../assets/img/JackLee.png"> </div> <div class="line"> <img class="i9" src="../assets/img/JackLee.png"> <img class="i10" src="../assets/img/JackLee.png"> <img class="i11" src="../assets/img/JackLee.png"> <img class="i12" src="../assets/img/JackLee.png"> </div> <center><p>CSS 滤镜效果展示</p></center> </template> <style lang="scss"> .line{ margin: auto; display: flex; flex-direction: row; align-items: center; justify-content: center; img{ width: 100px; transition: all 0.5s; &.i1:hover{ filter: blur(2px); } &.i2:hover{ filter: brightness(0.4); } &.i3:hover{ filter: contrast(200%);} &.i4:hover{ filter: grayscale(80%);} &.i5:hover{ filter: hue-rotate(90deg);} &.i6:hover{ filter: drop-shadow(16px 16px 20px blue); } &.i7:hover{ filter: invert(75%); } &.i8:hover{ filter: opacity(25%); } &.i9:hover{ filter: saturate(30%); } &.i10:hover{ filter: sepia(60%); } &.i11:hover{ filter: contrast(195%) brightness(16%); } &.i12:hover{ filter: grayscale(125%) blur(3px); } } } </style>