【CSS in Depth 2 精译_084】第 14 章:CSS 蒙版、形状与剪切概述 + 14.1:CSS 滤镜

发布于:2024-12-19 ⋅ 阅读:(8) ⋅ 点赞:(0)

当前内容所在位置(可进入专栏查看其他译好的章节内容)

  • 第四部分 视觉增强技术 ✔️
  • 【第 14 章 蒙版、形状与剪切】 ✔️
    • 14.1 滤镜 ✔️
      • 14.1.1 滤镜的类型 ✔️
      • 14.1.2 背景滤镜 ✔️
    • 14.2 蒙版

《CSS in Depth》新版封面

《CSS in Depth》新版封面

译者按
本篇正式进入全书第四部分的最后一个章节、同时也是新版全新增补的章节——CSS 蒙版、形状与剪切(clipping)。时隔六年有余,CSS 在滤镜特效的设置与处理上取得了长足进步,以前很多假借 JavaScript “曲线救国” 才能实现的页面特效,现在只需要几句 CSS 样式声明便可轻松搞定。当然,这样的 “轻松” 也是建立在对 CSS 全新特性的深刻理解与灵活应用之上的,正如这一章要介绍的全新知识点。一起先睹为快吧!

第 14 章 蒙版、形状与剪切 Masks, shapes, and clipping

本章概要

  • 利用滤镜(filters)来控制元素及其背景的外观
  • 蒙版图片在遮盖元素局部区域中的用法
  • 使用剪切路径(clip paths)重塑元素
  • 设置元素左右浮动的方法
  • 让文字沿图形边缘对齐

上一章介绍了一些有助于增强页面视觉趣味性、激发创意灵感的实用技巧。本章将继续探讨这个话题,首先利用 CSS 提供的多种内置函数(例如模糊设置、颜色去饱和等)来演示几个视觉效果的实现过程;然后介绍蒙版(masks)和剪切路径(clip paths)的用法,并利用它们能够选择性隐藏元素局部区域的强大功能,创建几个有趣的形状;最后是浮动和属性 shape-outside 相关的知识,了解它们在文字环绕中的具体应用,看看文字是怎样紧密围绕某个形状来排列的。

鉴于这些页面特效仅适用于某些特定场景,若要让它们在一个页面内同时生效可能会有些凌乱,因此本章将通过彼此独立的小型案例来逐一演示说明。


14.1 滤镜 Filters

CSS 中的 filter 滤镜属性可以实现元素的模糊设置、色彩偏移或者去饱和等页面特效,其中好几种特效都是现成的;但为了演示 filter 的工作原理,本节先从元素的模糊设置开始介绍。

通过属性 filter 设置的滤镜将对整个元素生效,包括元素内的文字、边框及背景样式等。图 14.1 为某内容板块(类似第 12 章中演示的版本)在设置模糊滤镜前后的效果对比图。其中左侧未设置滤镜,而右侧声明了 filter: blur(3px),即对该板块设置了 3px 的模糊滤镜。

图 14.1 滤镜将对包括其边框、子元素以及背景样式在内的整个元素生效

【图 14.1 滤镜将对包括其边框、子元素以及背景样式在内的整个元素生效】

尽管图 14.1 形象地展示了滤镜的效果,但由于它让文字难以阅读,显然并不能算作滤镜的一个特别理想的应用场景。为此,我将为您演示滤镜在图片中的实际应用。

先新建一个 HTML 文档与样式表,用于存放本章将要介绍的各种示例代码。然后将代码清单 14.1 中的 HTML 标记添加到示例页面。与前面的章节一样,关联的小鸟图片可从示例代码库中获取,详见:https://github.com/cssindepth/css-in-depth-2

代码清单 14.1 带小鸟图片的页面 HTML 标记

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <img src="images/bird.jpg"
      alt="Blue and orange bird perched on a branch"
      width="568" height="379">
  </body>
</html>

应用模糊滤镜后,图片效果将如图 14.2 所示。

图 14.2 模糊滤镜生效后的图片效果

【图 14.2 模糊滤镜生效后的图片效果】

函数 blur() 接受一个参数,即用于描述模糊程度的一个长度值。它表示屏幕上会有多少个像素混合到一起(除像素单位 px 外,emrem 及其他长度单位也是有效的)。若长度值为 0px,则表示没有模糊;只有当参数值大于 0 时才会看到模糊特效,且值越大,模糊效果越显著。

请根据代码清单 14.2 所示的 filter 声明同步更新本地样式表,为图片添加 5px 的模糊特效。

img {
  filter: blur(5px);
}

利用浏览器开发者工具 DevTools5px 的像素值做上下调整,看看模糊设置的强弱对图片效果的影响究竟如何。当参数值较小时,图片内容尚且可以读懂;但参数值越高,图片就越模糊,并逐渐变为一团模糊的色斑(a vague smudge of color)。这对于只需给出图片的大致印象而不必过分关注细节的场合也许会比较有用,稍后我会举例说明。在此之前,先来看看 CSS 都提供了哪些现成的滤镜功能。

14.1.1 滤镜的类型 Types of filters

目前可用的 CSS 滤镜功能共有 10 种,它们中的大多数都是以某种方式操纵颜色:要么通过调整对比度或色彩饱和度,要么通过添加阴影或变更元素的不透明度。

所有现成的滤镜功能描述如表 14.1 所示。与 blur() 类似,表中的滤镜函数都会通过传入的参数调整其特定行为,其中大部分的值均为百分数;当然也支持百分比形式(如 50%)或者小数形式(0.5)。表中所有的百分比参数其实都是可选项,如果不设置该参数,则默认为 100%。建议对照下表在您的示例页上试验每一个滤镜函数,看看都有哪些具体的特效。

表 14.1 滤镜函数用法一览表

函数示例 描述 参数说明
blur(10px) 应用高斯模糊特效 长度值越大,模糊效果越显著。
brightness(150%) 增加或减少亮度 参数值低于 100% 降低亮度;高于 100% 则增加亮度。
contrast(150%) 增加或减少对比度 参数值低于 100% 则降低对比度(使图像变淡);高于 100% 则增加对比度。
drop-shadow(10px 10px 15px black) 新增一个阴影特效,用法与 drop-shadow 属性类似 前两个参数分别表示 x 和 y 偏移量;第三个为模糊程度(可选);第四个为颜色值(可选)。与 drop-shadow 属性不同,该函数不支持扩展半径值和关键字 inset
grayscale(50%) 降低色彩饱和度 参数值介于 0% 到 100% 之间,可生成一个全灰度图像。
hue-rotate(30deg) 偏移每个像素的色调值 参数可以是色轮上代表颜色偏移量的任意角度值。
invert(100%) 用于反转颜色 参数值为 100% 时颜色完全反转;介于 0% 到 100% 之间则以指定强度设置反转效果。
opacity(50%) 设置元素透明效果,用法与 opacity 属性类似 参数值为 0% 时元素完全透明;值为 100% 时则完全不透明。
saturate(150%) 增加或减少色彩饱和度 参数值高于 100% 则增加图片色彩饱和度;低于 100% 则降低饱和度。saturate(25%) 等效于 grayscale(75%)
sepia(100%) 将当前色彩替换为深褐色色调效果 参数值介于 0%100% 之间,用于调节深褐色色调的强度。

此外,还可以同时设置多个滤镜,滤镜函数间用空格进行分隔。例如:filter: blur(5px) sepia(20%),此时各滤镜将按从左至右的顺序依次生效。

当需要针对性地设置一些细节特效时,filter 属性尤为适用。比如说,当鼠标悬停在某个图片上时,想要对图库中的其他所有图片设置一个略带模糊的、或者适当降低色彩饱和度的页面特效,则可以通过代码清单 14.3 给出的样式代码,在 :hover 状态下添加相关滤镜来实现。至于该样式对应的 HTML 页面,如果您愿意尝试的话,我就把它留作练手项目交给您来完成了。

代码清单 14.3:对图库中的图片设置些许滤镜效果

.gallery:hover img {
  filter: blur(2px) grayscale(50%); /* 鼠标悬停到图库上时,给其中的图片添加滤镜特效 */
}

.gallery img:hover {
  filter: none; /* 移除当前悬停图片上的滤镜效果 */
}

.gallery img {
  transition: filter 1s; /* 在 1 秒内逐步开启或关闭滤镜特效 */
}

根据上述代码,只要鼠标悬停到图库上方,滤镜特效就会对图库中的所有图片生效,但当前悬停的那张图片除外。这些滤镜只是出于演示目的才这样设定,在实际的生产应用环境下,可能会做进一步微调:模糊特效可能仅为 1px、灰度滤镜的值也会更低,不一而足。

提示

上述特效还有另一个比较巧妙的实现方案:利用 :has() 选择器在鼠标悬停到某张图片时,选中该图库内不在悬停状态下的所有图片,比如写作:.gallery z:has(img:hover) img:not(:hover)。但是 Firefox 浏览器直到 2023 年底才添加对 :has() 特性的支持,在没有考虑浏览器最新的相关兼容性的前提下,我可能不会采用这种写法。

本例中还用到了一个 transition 属性,以实现滤镜特效的延时开启或关闭,否则特效的切换会在一瞬间触发。因为我发现如果不设置过渡,突如其来的样式变化会令我分心,无法专注于当前图片——这正是我竭力避免的情况。过渡相关的知识我们还没学,下一章会重点介绍。

14.1.2 背景滤镜 Backdrop filter

偶尔也需要在某些内容后设置滤镜,而不是直接将其作用于内容本身。要实现这样的效果,可以使用另一个属性:backdrop-filter。该属性的值可以是前面介绍过的所有滤镜函数。

当需要将文字放到某个背景图片前方时,背景滤镜(backdrop filter) 会非常有用。选用恰当的滤镜可以在增强文字可读性的同时,又不致于完全遮挡住后面的图片内容。背景滤镜的一个典型应用如图 14.3 所示。

图 14.3 背景滤镜可用于遮挡半透明元素后面的内容

【图 14.3 背景滤镜可用于遮挡半透明元素后面的内容】

在本例中,背景图片位于某元素内。该元素又包含一个添加了模糊特效 blur() 的背景滤镜、且背景色为半透明白色的 div 元素。与前面讲的 filter 属性不同的是,本例中的模糊特效并没有对文字内容生效,即便 div 容器带有边框,该特效也不会对容器边框生效;相反,它只会影响到容器背后的内容,让图片可以透过 div 元素渲染出来。

该页面的 HTML 标记如代码清单 14.4 所示。请根据提供的示例代码同步更新本地示例页面。

代码清单 14.4:背景滤镜效果的示例页 HTML 标记

<div class="box">
  <div class="box__content">
    <h1>Common Kingfisher</h1>
    <p>
      The Common Kingfisher is a bird native found in Europe, Asia, and
      north Africa. It has bright blue plumage with an orange belly.
    </p>
  </div>
</div>

样式方面,背景图片将设置在 box 元素上,而背景滤镜样式 backdrop-filter 则在容器 box__content 上声明。此外还需要一些内边距、外边距来排列元素。具体样式代码详见代码清单 14.5。请将它们同步更新到本地样式表中。

代码清单 14.5 背景滤镜示例样式代码

.box {
  padding: 30px;
  background-image: url(images/bird.jpg);
  background-size: cover;
  background-position: center 30%;
}
.box__content {
  max-inline-size: 500px;
  margin-inline: auto;
  padding: 50px 30px 70px;
  border-radius: 10px;
  background-color: oklch(100% none none / 0.3); /* 即半透明的白色 */
  -webkit-backdrop-filter: blur(10px); /* 供应商前缀(用于 Safari 浏览器) */
  backdrop-filter: blur(10px); /* 启用背景滤镜的模糊特效 */
}

注意,上述代码声明了两次背景滤镜:第一次添加了 -webkit 浏览器前缀(vendor prefix,接着不带该前缀又声明了一次。鉴于 Safari 浏览器只支持 backdrop-filter 带前缀的写法,这里也只能包含两种写法。

关于浏览器前缀 Vendor prefixes

浏览器前缀是浏览器过去在实现新的或实验性的 CSS 特性时采用的一种技术。现在浏览器已经不再通过该技术来添加新的功能特性了,取而代之的是启用 Web 实验性平台特性标记(即 Experimental Web Platform Features flags,具体操作详见第 1 章内容)。该标记可以有效防止开发者在开发过程中依赖一些或将引入重大变更的、尚不稳定的新特性。

浏览器前缀现在很少使用了。不过一些浏览器尚未提供个别样式属性非前缀版本的支持,比如本章涉及的这几个属性:backdrop-filter 和某些 mask-* 开头的属性。它们在 SafariChrome 浏览器中解析时都需要添加 -webkit 前缀。您可能还会遇到其他类似的浏览器前缀,例如 -moz(用于 Firefox 浏览器)、-o(用于旧版的 Opera 浏览器)以及 -ms(用于 Internet Explorer 以及旧版的 Edge 浏览器)等。

如果确实需要引入浏览器前缀的写法,可以考虑通过一些自动化工具来实现,例如 Autoprefixer,可从 https://autoprefixer.github.io/ 获取。此外,CSS 预处理器 Lightning CSS(详见:https://lightningcss.dev/)也提供了类似功能。我现在都不怎么用这些工具了,毕竟当前需要添加浏览器前缀屈指可数。但如果必须考虑前缀、却又不想死记硬背这些属性对应的特定浏览器前缀,使用这些工具就会大有帮助。

译注

不得不说,像 Safari 浏览器这样在示例代码中被作者点名批评的情况还是比较罕见的。带着几分幸灾乐祸到 Can I Use 网站一查,才发现这个当时饱受作者诟病的不兼容问题,在本书出版不到三个月的时间内就收到了来自 Safari 官方立行立改的深刻 “检讨”(还得是这种方式整改起来最为彻底,哈哈)。如下图所示,backdrop-filter 特性功能已于今年九月在 Safariv18.0 版本中正式移除了浏览器前缀写法,目前已得到各主流浏览器厂商的全面支持:

补图:目前各大浏览器厂商已经对 backdrop-filter 背景滤镜提供了全面支持(截至 2024 年 12 月 18 日)

【补图:目前各大浏览器厂商已经对 backdrop-filter 背景滤镜提供了全面支持(截至 2024 年 12 月 18 日)】

背景滤镜在小型界面元素的开发中可能会非常有用,例如通知类消息组件或者应用级控制按钮等。

以上示例用的都是静态定位(static positioning),此时父元素的背景内容可以透过滤镜渲染出来。同样的背景特效也可以应用在设置了固定定位或绝对定位、彼此间相互堆叠的页面元素场景中。



关于《CSS in Depth》(中译本书名《深入解析 CSS》)

第 1 版 第 2 版
读者评分 原版:4.7(亚马逊);中文版:9.3(豆瓣) 原版:5.0(亚马逊);中文版:暂无,待出版
出版时间 原版:2018 年 3 月;中文版:2020 年 4 月 原版:2024 年 7 月;中文版:暂无,待出版
原价 原版:$44.99;中文版:¥139.00 原版:$59.99;中文版:暂无,待出版
现价 原版:$36.49;中文版:¥52.54 起步 原版:$52.09;中文版:暂无,待出版
原版国内预订 起步价 ¥461.00 起步价 ¥750.00

本专栏为该书第 2 版高分译文专栏,全网首发,精译精校,持续更新,计划今年内完成全书翻译,敬请期待!!!

目前已完结的章节(可进入本专栏查看详情,连载期间完全免费):

  • 第一章 层叠、优先级与继承(已完结)
    • 1.1 层叠
    • 1.2 继承
    • 1.3 特殊值
    • 1.4 简写属性
    • 1.5 CSS 渐进式增强技术
    • 1.6 本章小结
  • 第二章 相对单位(已完结)
    • 2.1 相对单位的威力
    • 2.2 em 与 rem
    • 2.3 告别像素思维
    • 2.4 视口的相对单位
    • 2.5 无单位的数值与行高
    • 2.6 自定义属性
    • 2.7 本章小结
  • 第三章 文档流与盒模型(已完结)
    • 3.1 常规文档流
    • 3.2 盒模型
    • 3.3 元素的高度
    • 3.4 负的外边距
    • 3.5 外边距折叠
    • 3.6 容器内的元素间距问题
    • 3.7 本章小结
  • 第四章 Flexbox 布局(已完结)
    • 4.1 Flexbox 布局原理
    • 4.2 弹性子元素的大小
    • 4.3 弹性布局的方向
    • 4.4 对齐、间距等细节处
    • 4.5 本章小结
  • 第五章 网格布局(已完结)
    • 5.1 构建基础网格
    • 5.2 网格结构剖析 (上)
      • 5.2.1 网格线的编号(下)
      • 5.2.2 网格与 Flexbox 配合(下)
    • 5.3 两种替代语法
      • 5.3.1 命名网格线
      • 5.3.2 命名网格区域
    • 5.4 显式网格与隐式网格(上)
      • 5.4.1 添加变化 (中)
      • 5.4.2 让网格元素填满网格轨道(下)
    • 5.5 子网格(全新增补内容)
    • 5.6 对齐相关的属性
    • 5.7 本章小结
  • 第六章 定位与堆叠上下文(已完结)
    • 6.1 固定定位
      • 6.1.1 创建一个固定定位的模态对话框
      • 6.1.2 在模态对话框打开时防止屏幕滚动
      • 6.1.3 控制定位元素的大小
    • 6.2 绝对定位
      • 6.2.1 关闭按钮的绝对定位
      • 6.2.2 伪元素的定位问题
    • 6.3 相对定位
      • 6.3.1 创建下拉菜单(上)
      • 6.3.2 创建 CSS 三角形(下)
    • 6.4 堆叠上下文与 z-index
      • 6.4.1 理解渲染过程与堆叠顺序(上)
      • 6.4.2 用 z-index 控制堆叠顺序(上)
      • 6.4.3 深入理解堆叠上下文(下)
    • 6.5 粘性定位
    • 6.6 本章小结
  • 第七章 响应式设计(已完结)
    • 7.1 移动端优先设计原则(上篇)
      • 7.1.1 创建移动端菜单(下篇)
      • 7.1.2 给视口添加 meta 标签(下篇)
    • 7.2 媒体查询(上篇)
      • 7.2.1 深入理解媒体查询的类型(上篇)
      • 7.2.2 页面断点的添加(中篇)
      • 7.2.3 响应式列的添加(下篇)
    • 7.3 流式布局
    • 7.4 响应式图片
    • 7.5 本章小结
  • 第八章 层叠图层及其嵌套
    • 8.1 用 layer 图层来操控层叠规则(上篇)
      • 8.1.1 图层的定义(上篇)
      • 8.1.2 图层的顺序与优先级(下篇)
      • 8.1.3 revert-layer 关键字(下篇)
    • 8.2 层叠图层的推荐组织方案
    • 8.3 伪类 :is() 和 :where() 的用法
    • 8.4 CSS 嵌套的使用
      • 8.4.1 嵌套选择器的使用
      • 8.4.2 深入理解嵌套选择器
      • 8.4.3 媒体查询及其他 @规则 的嵌套
    • 8.5 本章小结
  • 第九章 CSS 的模块化与作用域
    • 9.1 模块的定义
      • 9.1.1 模块和全局样式
      • 9.1.2 一个简单的 CSS 模块
      • 9.1.3 模块的变体
      • 9.1.4 多元素模块
    • 9.2 将模块组合为更大的结构
      • 9.2.1 模块中多个职责的拆分
      • 9.2.2 模块的命名
    • 9.3 CSS 的作用域
      • 9.3.1 CSS 作用域的就近原则
      • 9.3.2 划定作用域的边界
      • 9.3.3 CSS 中的隐式作用域
      • 9.3.4 关于 CSS 作用域与层叠图层
    • 9.4 CSS 模式库
    • 9.5 本章小结
  • 第十章 CSS 容器查询
    • 10.1 容器查询的一个简单示例
      • 10.1.1 容器尺寸查询的用法
    • 10.2 深入理解容器
      • 10.2.1 容器的类型
      • 10.2.2 容器的名称
      • 10.2.3 容器与模块化 CSS
    • 10.3 与容器相关的单位
    • 10.4 容器样式查询的用法
      • 10.4.1 将模块与所在容器解耦
      • 10.4.2 减少重复代码
    • 10.5 本章小结
  • 第 11 章 颜色与对比
    • 11.1 通过对比进行交流
      • 11.1.1 模式的建立
      • 11.1.2 还原设计稿
    • 11.2 颜色的定义
      • 11.2.1 色域与色彩空间
      • 11.2.2 CSS 颜色表示法(RGB、Hex、HSL、HWB、LAB/OKLAB、LCH/OKLCH)
    • 11.3 利用 OKLCH 处理颜色(上篇)
      • 11.3.4 从页面其他颜色衍生出新颜色(下篇)
    • 11.4 思考字体颜色的对比效果
    • 11.5 本章小结
  • 第 12 章 CSS 排版与间距
    • 12.1 间距设置
      • 12.1.1 使用 em 还是 px
      • 12.1.2 对行高的深入思考
      • 12.1.3 行内元素的间距设置
    • 12.2 Web 字体
    • 12.3 谷歌字体
    • 12.4 @font-face 的工作原理
      • 12.4.1 字体格式与回退处理
      • 12.4.2 同一字型的多种变体形式
    • 12.5 性能因素考量
      • 12.5.1 font-display 属性解析
      • 12.5.2 可变字体的用法
    • 12.6 调整字间距,提升可读性
      • 12.6.1 正文的字间距
      • 12.6.2 标题、小元素和间距
    • 12.7 本章小结
  • 第 13 章 渐变、阴影与混合模式
    • 13.1 渐变
      • 13.1.1 使用多个颜色节点(上)
      • 13.1.2 颜色插值方法(中)
      • 13.1.3 径向渐变(下)
      • 13.1.4 锥形渐变(下)
    • 13.2 阴影
      • 13.2.1 利用渐变和阴影打造立体感
      • 13.2.2 使用扁平化设计创建元素
      • 13.2.3 创建混合风格的按钮外观
    • 13.3 混合模式
      • 13.3.1 为图片上色
      • 13.3.2 混合模式的类型
      • 13.3.3 图片纹理的添加
      • 13.3.4 融合混合模式的用法
    • 13.4 本章小结
  • 附录
    • 附录A:CSS 选择器参考
    • 附录B:CSS 预处理器简介