当前位置: 首页 > news >正文

【CSS in Depth 2 精译】1.5 渐进式增强

文章目录

    • 1.5 渐进式增强
      • 1.5.1 利用层叠规则实现渐进式增强
      • 1.5.2 渐进式增强的选择器
      • 1.5.3 利用 `@supports()` 实现特性查询
        • 启用浏览器实验特性

1.5 渐进式增强

要用好 CSS 这样一门不断发展演进中的语言,其中一个重要的因素就是要与时俱进,及时了解哪些功能是新鲜出炉的,尤其是那些仅有部分常见浏览器支持的新功能,提前了解是很有必要的。

CSS 同时支持向前与向后兼容的精心设计,让样式代码能够同时在旧新两大类浏览器中流畅运行。只需稍加考虑,这些前沿特性就能在您的 CSS 中得以完美呈现,即便它们尚未对所有用户开放。

为此,可以给旧版浏览器设计一套可接受(但功能较少)的 CSS 样式;而把那些只能在最新版浏览器中呈现的新特性放到新的 CSS 图层(layer)上。这么一来您的样式代码就是面向未来的,随着升级浏览器的用户越来越多,这些新功能新特性也将逐步登台亮相。这种实现方案就叫做 渐进式增强(progressive enhancement

想知道一项特定功能的浏览器版本支持情况,请查看 https://caniuse.com 或 MDN 相关文档 https://developer.mozilla.org/en-US/docs/Web。

由于在互联网早期浏览器更新迭代的速度较慢,一些开发人员就总认为那些全新的 CSS 特性几年内都难登大雅之堂。但时至今日,所有主流浏览器都是基业常青的,其新版本的更新发布不仅频繁,而且往往是自动进行的。一些新功能仅仅只需数月就能将浏览器的支持率从 0% 拉升至 80%。之后便会因为用户延迟更新或者囿于公司政策而使更新速度放缓。但无论如何,只要没有明确需求要支持旧版浏览器,新特性通常都会在得到主流浏览器支持后的一两年内稳定下来。

利用适当的渐进式增强配置,您甚至可以即刻小试牛刀,无需恭候多时——尽管也得看该功能的具体适配情况,以及您希望尝试新特性的迫切程度。

1.5.1 利用层叠规则实现渐进式增强

启用渐进式增强最简单的办法是将其构建到层叠规则之中。当浏览器遇到无法解析的样式声明,会直接忽略。考察如下样式代码:

aside {background-color: #333333; /* 设置一个既安全又普遍支持的十六进制颜色值 */background-color: #333333aa; /* 使用更新的十六进制编码格式覆盖上一个值 */
}

因为第二个样式声明出现在第一个之后,利用前面介绍的层叠规则,就能断定这些元素的背景色层叠值最终花落谁家。

第二个声明使用了一个相对较新的八位的十六进制颜色编码格式(第 7 位和第 8 位数指定了一个 alpha 通道值,表示部分透明)。该语法在大多数浏览器中均有效,仅有部分旧版浏览器不支持,例如 Internet Explorer 浏览器。因此,如果用户恰巧用的是 IE 浏览器,该样式就会被忽略,层叠值为第一个样式声明的值。尽管该用户无法获得带透明效果的完整体验,但至少还能看到一个完全可用的版本。当前页面不会因此而“崩溃”或抛出错误;浏览器也会继续解析其余 CSS 并丢弃未能识别的样式声明。

从调试的角度来看,这样的处理似乎有些奇特,因为 CSS 从不抛出任何错误。但这恰恰是 CSS 正常运行的一个重要组成部分,也是为了实现渐进式增强的最终目标而精心设计的。

1.5.2 渐进式增强的选择器

渐进式增强的实施并不仅限于新的属性或新的样式值语法层面,还可以体现在新的选择器上。浏览器如果支持该语法就能正常渲染,否则将忽略整个规则集。

还有一个重要细节需要特别注意:当规则集有多个选择器时,只要任何一个选择器不被支持或无效,浏览器渲染时将忽略整个规则集。例如以下样式代码:

input.invalid,
input:user-invalid {border: 1px solid red;
}

本书撰稿时,伪类 :user-invalid 还是 CSS 的一个新增特性(更多详细信息,请参阅 附录 A)。落后几个版本的浏览器或许理解 input.invalid 的含义,但由于无法理解 :user-invalid,即使第一个选择器匹配成功,这些样式也同样不会生效。

要启用这样的新选择器,最好的办法是将它们分开书写:

input.invalid {border: 1px solid red;
}
input:user-invalid {border: 1px solid red;
}

这将不可避免地引入冗余样式,但也是当下最好的解决方案了。在使用新的伪类、伪元素或者属性选择器时,请务必牢记这一点(请参阅 附录 A)。

遇到上面列举的几个简单情况,尚且只需要重复几行样式代码;但偶尔也会遇到需要重复大段 CSS 的情况。这种情况下,一些开发人员为了尽量避免样式冗余很可能会选择一直等下去,直到浏览器对该选择器的支持情况令人满意后,才会谨慎启用新的功能特性。

1.5.3 利用 @supports() 实现特性查询

前面提到的分而治之的方法,足以应对因启用新特性而对现有样式的影响较小的情况;但偶尔也会遇到给支持新特性的浏览器定制多套不同样式声明的复杂情况。此时就可以利用 CSS 的 特性查询(feature query 技术,根据浏览器是否支持某个功能特性来定制化开发更大规模的样式效果。

特性查询的写法类似:

@supports (display: grid) {}

注意,@supports 规则后面有一个带括号的样式声明。如果浏览器能识别该声明(本例即为网格布局),则后面大括号内的所有规则集都会生效,否则予以忽略。

也就是说,您可以提供一套旧的样式布局(如浮动布局)留待备用。这些样式未必是最理想的方案,甚至不得不做出一些让步,但足以满足实际需求。然后再利用特性查询,让完整版的网格布局样式在页面生效。

网格布局方案目前已在所有现代浏览器中得到广泛支持,但以前却并非如此。用它来演示 @supports 的用法再好不过。如图 1.15 所示,在示例页面添加一组超链接,并将其布局到一个小型网格中:

图 1.15 定义在 @supports 代码块内的一组链接网格

图 1.15 定义在 @supports 代码块内的一组链接网格

首先,将如下 HTML 代码添加到页面标题和页脚之间的 <main> 元素中:

代码清单 1.24 添加到页面的一组超链接

<p>Try some of our newest coffees:</p>
<div class="coffees"><a href="/coffees/costa-rica">Costa Rica</a><a href="/coffees/ethiopia">Ethiopia</a><a href="/coffees/guatamala">Guatemala</a><a href="/coffees/kenya">Kenya</a><a href="/coffees/mexico">Mexico</a>
</div>

接着添加样式,将其设置为网格布局。首先,给旧版浏览器提供一套回退样式;然后利用特性查询,再提供一套完整功能的网格布局版本。代码如下:

代码清单 1.25 利用功能查询来实现渐进式增强

.coffees {margin: 20px 0;
}
.coffees a {/* 为旧版浏览器提供一套回退样式 */display: inline-block;min-width: 300px;padding: 10px 15px;margin-right: 10px;margin-bottom: 10px;color: black;background-color: transparent;border: 1px solid gray;border-radius: 5px;
}@supports (display: grid) { /* 仅对能识别网格布局的浏览器生效如下样式 */.coffees {/* 为现代浏览器定义网格布局 */display: grid;grid-template-columns: 1fr 1fr 1fr;gap: 10px;}.coffees a {/* 覆盖干扰当前网格布局的回退样式 */margin: unset;min-width: unset;}
}

上述代码中,备用方案和其他基本样式(如颜色)位于特性查询代码块外,因此将对所有浏览器生效。在不支持网格布局的浏览器中打开示例页面,会看到类似网格布局的备用样式效果;而所有基于网格布局的相关样式都在特性查询代码块内,因此仅在浏览器支持网格布局时才会生效。

本书第 5 章还会进一步深入考察网格布局,如果对上述代码不熟悉也无须担心。

试想一下要是没有 @supports 代码块,最终样式会有何不同;甚至可以临时注释掉里面的样式,在现代浏览器中查看样式回退的效果,再酌情调整。

@supports 规则可用于查询各种 CSS 特性的支持情况:使用 @supports (mix-blend-mode: overlay) 可以查询混合模式(blend mode)的支持情况(详见本书第 11 章);使用 @supports (color: color-mix(in oklab, red, white)) 还能查询 color-mix 特性的支持情况(详见本书第 13 章)。

CSS 特性查询还支持以下几种写法:

  • @supports not(<declaration>)——仅当目标声明不受支持时,生效特性查询块中的特定样式规则;
  • @supports (<declaration>) or (<declaration>)——支持任一目标声明,则生效对应的样式规则;
  • @supports (<declaration>) and (<declaration>)——同时支持两个目标声明,则生效相应的样式规则;
  • @supports selector(<selector>)——仅当浏览器能识别目标选择器时,生效相应的样式规则(例如 @supports selector(:user-invalid)

有了渐进式增强的解决方案,您可以实现跨浏览器为所有用户提供定制化的用户体验,甚至包括今后的浏览器。一个新的 CSS 语法特性,放到能识别的浏览器内就能渲染,无法识别的也自然不会渲染。Web 设计师兼教育家 Jen Simmons 半开玩笑地称它为“量子 CSS”(Quantum CSS):对于一个 CSS 特性,“可以同时拥有启用和不启用、生效和不生效两种状态”(“use it and not use it at the same time. It works and it doesn’t work at the same time”)。

CSS 的这种语言特性又被称为 CSS 的 弹性机制(resilience。CSS 这门语言(以及类似的 HTML 语言)是高容错设计理念的产物。随着将来 CSS 新功能的不断涌现,您可以充分利用它来扩充自己的工具箱。

启用浏览器实验特性

W3C 联盟与浏览器厂商一道共同制定并开发了 CSS 规范。这也意味着在 CSS 规范最终确定之前,一些浏览器可能就已经开始支持某项特性功能的研发了。为了防止正处在生产环境中的网站贸然引入尚待稳定的 CSS 样式效果,这些实验性功能仅对有意在浏览器设置中启用它们的开发人员开放。这样也有利于在规范最终确定前进行早期实验和效果反馈。如果您也想接触这些实验性功能,知道如何开启它们也是至关重要的。

在 Chrome 和 Opera 中,可以通过启用一个标志开关(flag)来完成该操作。在 Chrome 的地址栏内输入 chrome://flags 并按 Enter 键跳转;Opera 浏览器则跳转至 opera://flags。然后下翻或搜索找到“实验性网络平台功能”(Experimental Web Platform Features),并单击启用该选项。

如果习惯用 Firefox 浏览器,则需要下载并安装 Firefox 开发者版本(https://www.mozilla.org/en-US/firefox/developer/)或 Firefox Nightly 版本(https://nightly.mozilla.org/)。如果习惯用 Safari 浏览器,则需要安装 Safari 技术预览版(Safari Technology Preview)或 Webkit Nightly Builds 版本。

相关文章:

【CSS in Depth 2 精译】1.5 渐进式增强

文章目录 1.5 渐进式增强1.5.1 利用层叠规则实现渐进式增强1.5.2 渐进式增强的选择器1.5.3 利用 supports() 实现特性查询启用浏览器实验特性 1.5 渐进式增强 要用好 CSS 这样一门不断发展演进中的语言&#xff0c;其中一个重要的因素就是要与时俱进&#xff0c;及时了解哪些功…...

k8s集群master故障恢复笔记

剔除故障节点 kubectl drain master故障节点 kubectl delete node master故障节点 kubeadm reset rm -rf /etc/kubernetes/manifests mkdir -p /etc/kubernetes/pki/etcd/ 从master其他节点拷 scp /etc/kubernetes/pki/ca.crt ca.key sa.key sa.pub front-proxy-ca.crt …...

昇思25天学习打卡营第5天|网络构建

一、简介&#xff1a; 神经网络模型是由神经网络层和Tensor操作构成的&#xff0c;mindspore.nn提供了常见神经网络层的实现&#xff0c;在MindSpore中&#xff0c;Cell类是构建所有网络的基类&#xff08;这个类和pytorch中的modul类是一样的作用&#xff09;&#xff0c;也是…...

Python开发日记--手撸加解密小工具(2)

目录 1. UI设计和代码生成 2.运行代码查看效果 3.小结 1. UI设计和代码生成 昨天讨论到每一类算法设计为一个Tab&#xff0c;利用的是TabWidget&#xff0c;那么接下来就要在每个Tab里设计算法必要的参数了&#xff0c;这里我们会用到组件有Label、PushButton、TextEdit、Ra…...

一文看懂TON链

一、背景与起源 The Open Network (TON) 的故事起始于2018年&#xff0c;当时全球知名的即时通讯软件Telegram计划推出自己的区块链平台及加密货币Gram&#xff0c;旨在构建一个既安全又高速的分布式网络&#xff0c;用以支持下一代去中心化应用程序(DApps)和数字资产。然而&a…...

(南京观海微电子)——TFT LCD压合技术

TFT-LCD TFT-LCD open cell后段制程主要指的是将驱动IC和PCB压合至液晶板上&#xff0c;这个制程主要由三个步骤组成&#xff1a; 1.ACF (Anisotropic Conductive Film)的涂布。 在液晶板需要压合驱动IC的地方涂布ACF&#xff0c;ACF又称异方性导电胶膜&#xff0c;特点是上下…...

神经网络实战1-Sequential

链接&#xff1a;https://pytorch.org/docs/1.8.1/generated/torch.nn.Sequential.html#torch.nn.Sequential 完成这样一个网络模型 第一步新建一个卷积层 self.conv1Conv2d(3,32,5)#第一步将33232输出为32通道&#xff0c;卷积核5*5 注意一下&#xff1a;输出通道数等于卷积…...

Java中如何优化数据库查询性能?

Java中如何优化数据库查询性能&#xff1f; 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将深入探讨在Java中如何优化数据库查询性能&#xff0c;这是…...

从0开发一个Chrome插件:用户反馈与更新 Chrome 插件

前言 这是《从0开发一个Chrome插件》系列的第二十二篇文章,也是最终篇,本系列教你如何从0去开发一个Chrome插件,每篇文章都会好好打磨,写清楚我在开发过程遇到的问题,还有开发经验和技巧。 专栏: 从0开发一个Chrome插件:什么是Chrome插件?从0开发一个Chrome插件:开发…...

Failed to establish a new connection: [WinError 10061] 由于目标计算机积极拒绝,无法连接

在进行参数化读取时发现一个问题&#xff1a; 发现问题&#xff1a; requests.exceptions.ConnectionError: HTTPConnectionPool(hostlocalhost, port8081): Max retries exceeded with url: /jwshoplogin/user/update_information.do (Caused by NewConnectionError(<url…...

基于Java作业管理系统设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;…...

使用Kafka框架发送和接收消息(Java示例)

Kafka是一个开源的分布式流处理平台&#xff0c;以其在大数据和实时处理领域的广泛应用而闻名。以下是Kafka的关键特性以及它在消息传输方面的优势&#xff1a; 高吞吐量与低延迟&#xff1a;Kafka能够每秒处理数百万条消息&#xff0c;具有极低的延迟&#xff0c;这使得它非常…...

高可用电商支付架构设计方案

高可用电商支付架构设计 在现代电商业务中&#xff0c;支付过程是其中至关重要的一环&#xff0c;一个高可用、安全稳定的支付架构不仅可以提高整个系统的可靠性和扩展性&#xff0c;降低维护成本&#xff0c;还可以优化用户体验&#xff0c;增加用户黏性。 本文将提出一种高…...

PriorityQueue详解(含动画演示)

目录 PriorityQueue详解1、PriorityQueue简介2、PriorityQueue继承体系3、PriorityQueue数据结构PriorityQueue类属性注释完全二叉树、大顶堆、小顶堆的概念☆PriorityQueue是如何利用数组存储小顶堆的&#xff1f;☆利用数组存储完全二叉树的好处&#xff1f; 4、PriorityQueu…...

python 字符串驻留机制

偶然发现一个python字符串的现象&#xff1a; >>> a 123_abc >>> b 123_abc >>> a is b True >>> c abc#123 >>> d abc#123 >>> c is d False 这是为什么呢&#xff0c;原来它们的id不一样。 >>> id(a)…...

express+vue 在线五子棋(一)

示例 在线体验地址五子棋&#xff0c;记得一定要再拉个人才能对战 本期难点 1、完成了五子棋的布局&#xff0c;判断游戏结束 2、基本的在线对战 3、游戏配套im(这个im的实现&#xff0c;请移步在线im) 下期安排 1、每步的倒计时设置 2、黑白棋分配由玩家自定义 3、新增旁观…...

AI 大模型企业应用实战(06)-初识LangChain

LLM大模型与AI应用的粘合剂。 1 langchain是什么以及发展过程 LangChain是一个开源框架&#xff0c;旨在简化使用大型语言模型构建端到端应用程序的过程&#xff0c;也是ReAct(reasonact)论文的落地实现。 2022年10月25日开源 54K star 种子轮一周1000万美金&#xff0c;A轮2…...

JavaScript的学习之旅之初始JS

目录 一、认识三个常见的js代码 二、js写入的第二种方式 三、js里内外部文件 一、认识三个常见的js代码 <script>//写入js位置的第一个地方// 控制浏览器弹出一个警告框alert("这是一个警告");// 在计算机页面输入一个内容&#xff08;写入body中&#xff…...

DataStructure.时间和空间复杂度

时间和空间复杂度 【本节目标】1. 如何衡量一个算法的好坏2. 算法效率3. 时间复杂度3.1 时间复杂度的概念3.2 大O的渐进表示法3.3 推导大O阶方法3.4 常见时间复杂度计算举例3.4.1 示例13.4.2 示例23.4.3 示例33.4.4 示例43.4.5 示例53.4.6 示例63.4.7 示例7 4.空间复杂度4.1 示…...

[Spring Boot]Netty-UDP客户端

文章目录 简述Netty-UDP集成pom引入ClientHandler调用 消息发送与接收在线UDP服务系统调用 简述 最近在一些场景中需要使用UDP客户端进行&#xff0c;所以开始集成新的东西。本文集成了一个基于netty的SpringBoot的简单的应用场景。 Netty-UDP集成 pom引入 <!-- netty --…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...