【CSS in Depth2精译】1.1.2 行内样式~1.1.3 选择器的优先级

文章目录

      • 1.1.2 行内样式
      • 1.1.3 选择器的优先级
        • 1.1.3.1 优先级的写法
        • 1.1.3.2 关于优先级的思考

1.1.2 行内样式

如果无法通过样式表来源规则解决样式冲突,浏览器则会考察它们是否通过 行内样式 作用于该元素。当使用 HTML 的 style 属性声明样式时,该样式仅对当前元素生效,从而覆盖来自样式表或 <style> 标签的声明。行内样式没有选择器,因为它们直接作用于当前所在元素。

根据示例页头的最终效果,需要将导航菜单中的特色链接(即末尾的 Special 项)设为橙黄色背景,如图 1.6 所示。实现这一效果有很多种方法。先从代码清单 1.4 提供的内联样式开始。

图 1.6 内联样式覆盖了选择器的样式

图 1.6 内联样式覆盖了选择器的样式

想查看实测效果,按以下代码修改样式即可(稍后将撤销这部分更改)。

代码清单 1.4 行内样式

<li><!-- 通过 style 属性设置行内样式 --><a href="/specials" class="featured" style="background-color: orange;">  Specials</a>
</li>

想要在样式表覆盖掉行内样式,需要给样式加一个 !important 标记,将其提升为优先级更高的样式表来源;但要是行内样式也有 !important 标记,那就彻底没戏了。因此最好只在样式表内使用 !important。下面撤销代码清单 1.4 中的样式,来看看更好的实现方式。

1.1.3 选择器的优先级

优先级(Specificity 是 CSS 学习过程中一个容易漏过、但又至关重要的语言特性。不理解样式表来源的概念倒也不妨碍您开发 CSS,因为绝大部分样式都是您自己写的,来源上都属于作者样式;但要是不理解 CSS 的优先级规则,几乎可以肯定是要踩坑的。

如果前面两个规则依旧无法解决样式冲突,浏览器则会进一步考察它们的选择器优先级。譬如,含有两个类名(class names)的选择器,优先级就比仅有一个的高;一个样式声明元素背景为橙黄色,但优先级更高的另一个声明却将其设为茶青色(teal),最终浏览器会用茶青色作背景。

下面举例说明,看看用一个简单的类选择器让特色链接的背景色设为橙黄色是什么效果。更新样式代码如下:

代码清单 1.5 不同优先级的选择器

#main-nav a { /* 更高优先级的选择器 */color: white;background-color: #13a4a4;  /* 茶青色背景 */padding: 5px;border-radius: 2px;text-decoration: none;
}
.featured {  /* 由于优先级较低,橙黄色背景无法覆盖茶青色背景 */background-color: orange;
}

运行后,橙黄色没有生效!所有导航链接仍然是茶青色。怎么回事?因为此时第一个选择器比第二个更具体(more specific)、优先级更高。它由一个 ID 和一个标签名组成;而第二个仅有一个类名。但仅凭选择器的长度还不足以说明问题。

选择器的类型不同,其优先级也不同。例如,ID 选择器的优先级就比类选择器更高。实际上,单个 ID 的优先级比包含任意多个类的选择器都高。类似地,类选择器的优先级也比含有任意多个标签的标签选择器(即 tag selector,也称为类型选择器,亦即 type selector)的优先级更高。

选择器优先级的具体规则如下:

  • 如若一方选择器 ID 数更多,则更多者胜出(即更具体、更明确);
  • 如若 ID 数量一致,则 类数更多 者胜出;
  • 如若上述比较均一致,则 标签名更多 者胜出。

考察以下代码中的选择器(注意不要添加到您的示例页)。它们是按照优先级从低到高的顺序排列的:

代码清单 1.6 具有逐渐增加特异性的选择器

html body header h1 {  /* 4 个标签 */color: blue;
}
body header.page-header h1 {  /* 3 个标签和 1 个类 */color: orange;
}
.page-header .title {  /* 2 个类 */color: green;
}
#page-title {  /* 1 个 ID */color: red;
}

描述最具体的选择器是 #page-title,它有一个 ID,因此标题颜色最终为红色。第二具体的是 .page-header .title ,它有两个类名。如果没有后面的 ID 选择器,则会生效该选择器样式(绿色)。第三个选择器 .page-header .title 比第二个(body header.page-header h1)优先级更高,尽管长度不及第二个。因为两个类比一个类更具体。最后,第一个选择器 html body header h1 只有四个元素类型(即标签名),没有 ID 或类,因此优先级是最低的。

注意

伪类选择器(Pseudo-class selectors,如 :hover)以及属性选择器(attribute selectors,如 [type="input"])的优先级与一个类选择器相同。通用选择器(*)和组合器(>+~)对优先级没有贡献。更多选择器类型信息,请参阅附录 A。

如果添加一个 CSS 样式声明但没有生效,往往是由于被优先级更高的样式覆盖了。许多时候开发人员用到了 ID 选择器,却没考虑过这样会创建更高的优先级,后面再想用其他样式覆盖就很难了。覆盖一个使用了 ID 选择器的样式,就只能用另一个 ID 尝试夺回优先级。

这个概念很简单,但如果不理解优先级,就可能始终都想不明白为什么一个样式能生效,而另一个却不能。

1.1.3.1 优先级的写法

优先级的一个常见写法,是用一组由逗号分隔的数字来表示。例如,1,2,2 表示该选择器包含 1 个 ID、2 个类、2 个标签。优先级最高的 ID 排在首位,其次是类,最后是标签。

选择器 #page-header #page-title 有 2 个 ID,没有类、也没有标签,其优先级可以写作 2,0,0;再比如选择器 ul li,有 2 个标签,但既没有 ID 也没有类,优先级就是 0,0,2。表 1.1 给出了代码清单 1.6 中各种选择器的优先级的写法。

表 1.1 各种选择器及其对应的优先级

选择器ID类(Classes)标签(Tags)写法(Notation)
html body header h10040,0,4
body header.page-header h10130,1,3
.page-header .title0200,2,0
#page-title1001,0,0

至此,判定优先级大小的问题就变成了纯数字比较。1,0,0 的优先级要高于 0,2,2,甚至高于 0,10,0(尽管我强烈不推荐写一个含有 10 个类名的选择器),因为第一个数字(代表 ID 数)享有最高的优先级。

业内偶尔也用四位数字来表示优先级。其最高位为 01,表示该声明是否通过 行内样式 进行指定。因为在 CSS 规范的早期版本中,行内样式最初被定义为优先级的一个子集。这样一来,行内样式的优先级写法就成了 1,0,0,0。这将覆盖通过选择器设置的样式,比如优先级像 0,1,2,0(1 个 ID 和 2 个类)的选择器。

1.1.3.2 关于优先级的思考

之前通过类选择器 .featured 设置橙黄色背景没有奏效,因为有个包含 ID 的选择器 #main-nav a 覆盖了原本的类选择器(优先级分别为 1,0,10,1,0)。有很多种方法可以解决这个问题,接下来介绍几种可行方案。

最省事的一个方法是在目标声明中添加 !important。按以下代码更新样式:

代码清单 1.7 试行方案一

#main-nav a {color: white;background-color: #13a4a4;padding: 5px;border-radius: 2px;text-decoration: none;
}
.featured {/* 标为重要声明,以享有更高优先级来源 */background-color: orange !important;  
}

这次生效了,因为 !important 标记将声明提升到了优先级更高的样式表来源。这个方法的确省事,但也很低级。它可能暂时解决了眼前的问题,但也给您的后续开发挖了坑。一旦给多处声明标注了 !important,后面再想覆盖掉这些样式又该如何是好?这时浏览器将再次启用样式表来源规则,进而再启用常规的优先级比较规则,最终在绕了一大圈后又让一切回到了原点。

就没有更好的解决方案了吗?与其考虑绕开选择器优先级,不如因势利导为我所用:何不主动提升选择器的优先级呢?将以下代码更新到您的示例文件中:

代码清单 1.8 试行方案二

#main-nav a { /* 优先级仍然为 1,0,1 */color: white;background-color: #13a4a4;padding: 5px;border-radius: 2px;text-decoration: none;
}
#main-nav .featured { /* 优先级提升为 1,1,0 */background-color: orange; /* 此时 !important 标记已经没用了 */
}

这样改也能生效。此时选择器包含 1 个 ID 和 1 个类,优先级为 1,1,0,比 #main-nav a (优先级 1,0,1)更高,所以最终背景变成了橙黄色。

该方法还有改进空间。与其抬升第二个选择器的优先级,不妨试试降低第一个选择器的优先级。注意到该元素包含一个类:<ul id="main-nav" class="nav">,因此您可以通过类名而非 ID 来选中该元素。按如下代码将选择器 #main-nav 变更为 .nav

代码清单 1.9 试行方案三

.nav { /* 将样式表中的 “#main-nav” 全部改为 “.nav” */margin-top: 10px;list-style: none;padding-left: 0;
}.nav li { /* 将样式表中的 “#main-nav” 全部改为 “.nav” */display: inline-block;
}.nav a { /* 第一个选择器的优先级降为 (0,1,1) */color: white;background-color: #13a4a4;padding: 5px;border-radius: 2px;text-decoration: none;
}
.nav .featured { /* 第二个选择器的优先级升至 (0,2,0) */background-color: orange;
}

至此,通过降低选择器的优先级,橙黄色背景的优先级已经足以覆盖掉之前的茶青色背景。

通过这些例子不难发现,优先级的对比容易沦为“军备竞赛”。在大型项目中这一点尤为突出。因此公认的最佳实践是:尽可能让优先级保持低位运行,以便将来需要覆盖样式时,您能有更多回旋的余地。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/29856.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js-promise、async/await

promise&#xff0c;简单就就是回调的一种简化了回调地狱&#xff08;如果多个调用是异步并且有结果依赖&#xff0c;那么就需要写成回调&#xff09;。 async/await&#xff0c;需要成对使用&#xff0c;是对promise的更高级的抽象&#xff0c; 比如 runAsync1() .then(fun…

Win32编程:第一个窗口程序(Part.1)

Win32系统编程是指在Windows操作系统上使用Win32 API进行软件开发的过程&#xff1b;Win32 API是Windows操作系统提供的应用程序接口&#xff0c;允许程序与操作系统进行交互&#xff0c;实现各种功能。 以下是Win32系统编程的基本概念和步骤&#xff1a; 环境准备 开发工具&…

[python学习]--模块管理

在Python中&#xff0c;模块管理是非常重要的&#xff0c;因为它允许你将代码组织成可重用的单元&#xff0c;这些单元可以在其他Python脚本或项目中导入和使用。Python的模块管理包括创建模块、导入模块、使用包&#xff08;packages&#xff09;来组织模块&#xff0c;以及处…

element-plus的form表单组件之checkbox组件

单个checkbox 绑定的响应式的值类型为bool类型&#xff0c;同一个组的checkbox多选其值对应值的数组&#xff0c;类型根据checkbox的value值而来。 label只用来显示具体的值&#xff0c;根据value属性来设置。 element-plus的checkbox提供多种特性。 如单选&#xff0c;多选…

关机充电动画:流程与定制

关机充电动画&#xff1a;流程与定制 基于MTK平台Android 11分析 生成logo.bin 关机充电动画是由一系列的bmp图片组成的&#xff0c;这些图片资源存在于vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo目录下&#xff08;当然不仅保护关机充电动画&#xff0c…

【软件工程】【22.10】p2

关键字&#xff1a; 软件开发基本途径、初始需求发现技术、UML表达事物之间关系、RUP需求获取基本步骤、项目过程建立涉及工作、项目规划过程域的意图和专用目标 判定表、分支覆盖、条件覆盖 三、简答 四、应用 这里条件覆盖有待商榷

Angular 2 数据显示

Angular 2 数据显示 Angular 2 是一个由 Google 维护的开源前端 web 框架,用于构建单页应用程序(SPA)。它以其高效的数据绑定、组件化架构和强大的依赖注入功能而受到开发者的青睐。在 Angular 2 应用程序中,数据显示是核心功能之一,它允许开发者轻松地将数据从组件传递到…

Gone框架介绍28 - 使用goner.IsDefault 将Goner设置为接口的默认实现

gone是可以高效开发Web服务的Golang依赖注入框架 github地址&#xff1a;https://github.com/gone-io/gone 文档地址&#xff1a;https://goner.fun/zh/ 文章目录 使用goner.IsDefault(...)将Goner设置为接口的默认实现从内置组件goner/logrus的构造函数讲起按类型注入的歧义性…

分布式注册中心如何保证数据一致性

分布式注册中心保证数据一致性主要依赖于一些核心的设计原则、技术和策略。以下是一些关键的方法和步骤&#xff1a; 1、使用分布式协调服务 如ZooKeeper、Etcd等&#xff0c;这些服务提供了分布式锁、分布式配置管理等功能&#xff0c;非常适合作为注册中心的数据存储。它们…

Python uWSGI 安装配置

Python uWSGI 安装配置 1. 引言 uWSGI是一个高性能的HTTP服务器,它实现了WSGI、uwsgi和HTTP等协议。它是用C编写的,旨在提供高性能和低资源消耗的Web服务。uWSGI广泛应用于Python Web应用程序,如Django、Flask等。本文将介绍如何在Python环境中安装和配置uWSGI。 2. 安装…

openEuler2203SP1自定义镜像,ks自动化安装

需求&#xff1a; 1、legacy启动 2、/boot分区1G&#xff0c;剩余给/ 3、创建root密码和一个普通用户 4、最小化安装&#xff08;选上development、legacy-unix、security-tools、standard&#xff09; 5、关闭firewalld、selinux 6、增加安装vim、ntpdate、iptables、ex…

SpringBoot配置第三方专业缓存技术jetcache方法缓存方案

jetcache方法缓存 我们可以给每个方法配置缓存方案 JetCache 是一个基于 Java 的缓存库&#xff0c;支持多种缓存方案和缓存策略&#xff0c;主要用于提升应用程序的性能和响应速度。它提供了多种缓存模式和特性&#xff0c;可以根据需求选择合适的缓存方案。 JetCache 的主…

认识QML

为什么使用Qt Quick&#xff1f; Qt4的设计用于满足开发者在主流桌面操作系统上有一套表现一致的窗口组件可以 使用。如今Qt的使用者面临了新的问题&#xff0c;他们需要提供可触碰交互的用户界面以满 足软件界面需求&#xff0c;并在主流桌面操作系统和移动操作系统上实现这些…

问题解决:局域网下多台电脑实现共享打印机

看了很多篇解决措施&#xff0c;都没有解决&#xff0c;自己鼓弄了好久&#xff0c;终于解决了&#xff0c;如下步骤所示&#xff0c;实测好用。 首先先保证本电脑已打开网络共享 其次关闭防火墙&#xff08;有时会出现奇怪问题&#xff0c;最好关闭&#xff09; 接着访问IP…

Scikit-Learn支持向量机回归

Scikit-Learn支持向量机回归 1、支持向量机回归1.1、最大间隔与SVM的分类1.2、软间隔最大化1.3、支持向量机回归1.4、支持向量机回归的优缺点2、Scikit-Learn支持向量机回归2.1、Scikit-Learn支持向量机回归API2.2、支持向量机回归初体验2.3、支持向量机回归实践(加州房价预测…

TikTok账号养号的流程分享

对于很多刚开始运营TikTok的新手小白来说&#xff0c;都会有一个同样的疑问&#xff0c;那就是&#xff1a;TikTok到底需不需要养号&#xff1f;这里明确告诉大家是需要养号的&#xff0c;今天就把我自己实操过的养号经验和策略总结出来&#xff0c;分享给大家。 一、什么是Ti…

国产24位I2S输入+192kHz立体声DAC音频数模转换器CJC4344

CJC4344是一款立体声数模转换芯片&#xff0c;内含插值滤波器、multi bit数模转换器、输出模拟滤波器。CJC4344系列支持大部分的音频数据格式。CJC4344基于一个带线性模拟低通滤波器的四阶multi-bitΔ-Σ调制器&#xff0c;而且本芯片可以通过检测信号频率和主时钟频率&#xf…

【面试八股总结】Redis数据结构及底层实现

一、五种基本数据结构 Redis 提供了丰富的数据类型&#xff0c;常见的有五种数据类型&#xff1a;String&#xff08;字符串&#xff09;&#xff0c;Hash&#xff08;哈希&#xff09;&#xff0c;List&#xff08;列表&#xff09;&#xff0c;Set&#xff08;集合&#xff0…

负载均衡(DR)

负载均衡&#xff08;DR&#xff09; 1.实验环境 准备三台机器网络使用NAT模式DR模式要求DIP与RIP必须在同一个王段及广播域关闭防火墙与selinux 2.分发器配置 #安装分发器并启动 [rootlocalhost ~]# yum -y install ipvsadm [rootlocalhost ~]# systemctl start ipvsadm #上…

华为鸿蒙 adb

安卓应用程序安装在鸿蒙手机上&#xff0c;使用adb开启服务失败 查找原因后&#xff1a; 1. 鸿蒙有自己的adb&#xff0c;叫hdc 文档中心 2. 可以打个鸿蒙的apk&#xff0c;调用hdc 3. 可以尝试降低应用android api版本&#xff0c;使adb在鸿蒙系统中可以使用