【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;
}

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android | 性能优化 之 TraceView工具的使用

上代码&#xff01; 先加权限&#xff1a; <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name"android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> 选择跟踪范围,在开始追踪和结束…

MySQL数据备份操作步骤

常见的数据备份命令 备份命令备份速度恢复速度介绍功能适用场景lvm2快照快快一般、支持几乎热备、速度快一般中小型数据量的备份cp快快物理备份、灵活性低很弱少量数据备份xtrabackup较快较快实现innodb热备、对存储引擎有要求强大较大规模的备份mysqldump慢慢逻辑备份、适用所…

Java学习 - 网络IP地址与子网划分 讲解

IP地址 作用 用于决定数据包最终到达哪个计算机 组成 由32位比特组成&#xff0c;即4个字节这32位可以分为两个部分&#xff0c;称为网络号和主机号同一网段的计算机网络号相同&#xff0c;路由器负责连接不同的网段&#xff0c;而交换机负责连接同一网段中不同的计算机同一…

reidis的内存回收和内存淘汰策略

redis的内存回收 8种内存淘汰策略

RabbitMQ学习总结

目录 一:介绍 二:应用场景 三:工作原理 组成部分说明 消息发布接收流程 四:下载安装 五:环境搭建 创建Maven工程 生产者 消费者 六:工作模式 Work queues Publish/subscribe 生产者 消费者 Routing 生产者 ​编辑消费者 思考 Topics 生产者 匹配…

openppp2 命令行接口详解

openppp2 是一个工作在 OSI/3 Layer 网络通信层的虚拟以太网工具链的开源软件&#xff0c;在查阅本文之前&#xff0c;人们可以查阅以下资料。 开源仓库&#xff1a; liulilittle/openppp2: PPP PRIVATE NETWORK™ 2 VPN Next Generation Reliable and Secure Virtual Etherne…

JavaWeb——SQL简介

1. SQL的介绍 SQL是一门结构化查询语言&#xff0c;就是一门用来操作关系型数据库的数据库语言&#xff1b; 使用SQL语句&#xff0c;可以操作所有的关系数据库&#xff1b; 但是&#xff0c;不同的关系型数据库的SQL操作略有不同&#xff0c;称为“方言”&#xff1b; 2. S…

大模型网信办备案全网最详细说明(付附件)

根据目前公开的国内大模型算法备案统计来看&#xff0c;首批境内深度合成服务算法备案清单&#xff0c;总共通过41家&#xff0c;14家互联网大厂和独角兽企业成功申报算法备案32个&#xff0c;6家新兴互联网公司成功申报算法备案9个&#xff0c;仅占比21.9%。 第二批境内…

springboot学习-图灵课堂-最详细学习

springboot-repeat springBoot学习代码说明为什么java -jar springJar包后项目就可以启动 配置文件介绍 springBoot学习 依赖引入 <properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.target>8</mav…

嵌入式开发二十一:定时器之通用定时器

通用定时器是在基本定时器的基础上扩展而来&#xff0c;增加了输入捕获与输出比较等功能。高级定时器又是在通用定时器基础上扩展而来&#xff0c;增加了可编程死区互补输出、重复计数器、带刹车(断路)功能&#xff0c;这些功能主要针对工业电机控制方面。 本篇博客我们主要来学…

leetcode 二分查找·系统掌握 猜数字大小

题目&#xff1a; 题解&#xff1a; 使用最经典普通二分即可 int guessNumber(int n) {long l0,rn,mid;while(l<r){mid(rl)>>1;if(guess(mid)0)return mid;else if(guess(mid)-1)rmid-1;else lmid1;}return 0;}

MySQL的DML语句

文章目录 ☃️概述☃️DML☃️添加数据☃️更新和删除数据☃️DML的重要性 ☃️概述 MySQL 通用语法分类 ● DDL: 数据定义语言&#xff0c;用来 定义数据库对象&#xff08;数据库、表、字段&#xff09; ● DML: 数据操作语言&#xff0c;用来对数据库表中的数据进行增删改 …

如何有效管理信息技术课堂

有效管理信息技术课堂是确保学生学习效果、维护课堂秩序和提升学生兴趣的关键。以下是一些详细的方法和策略&#xff0c;旨在帮助教师更好地管理信息技术课堂&#xff1a; 一、制定明确的课堂规则 强调课堂纪律&#xff1a;确保学生明确了解并遵守课堂纪律&#xff0c;如准时…

【详细】一步一步实现一个BP神经网络-逐行代码解说

本文来自《老饼讲解-BP神经网络》https://www.bbbdata.com/ ​ 要如何使用代码实现一个BP神经网络呢&#xff1f; 下面跟随笔者&#xff0c;一步一步详细来实现&#xff0c;再对代码进行详细解说。 通过本文可以详细掌握怎么使用matlab来实现一个BP神经网络。 一、一步一步实…

去水印助手,小熊录屏,OldRoll复古胶片相机

我们将带大家了解三款特色应用,软件是经过大佬处理过的&#xff0c;都非常的好用&#xff01;今天分享给大家&#xff01;如果你也喜欢这几款软件不要忘记给博主点击点赞和再看哦&#xff01; 软件获取链接在链接的底部&#xff1a; 一键去水印助手 无论您是在各大社交平台上…

区块链技术:金融市场监管的新篇章

一、引言 随着金融科技的迅猛发展&#xff0c;区块链技术作为其中的佼佼者&#xff0c;正逐渐改变着金融市场的格局。在金融市场监管领域&#xff0c;区块链技术以其独特的优势&#xff0c;为监管机构提供了新的监管思路和手段。本文将深入探讨区块链技术在金融市场监管中的作用…

【机器学习 复习】第3章 K-近邻算法

一、概念 1.K-近邻算法&#xff1a;也叫KNN 分类 算法&#xff0c;其中的N是 邻近邻居NearestNeighbor的首字母。 &#xff08;1&#xff09;其中K是特征值&#xff0c;就是选择离某个预测的值&#xff08;例如预测的是苹果&#xff0c;就找个苹果&#xff09;最近的几个值&am…

18.cobra框架了解

目录 概述举例安装实践实践 概述 github cobra cobra 快速的实现一个命令行客户端&#xff0c;命令行解析工具。 cobra 中的主要概念 -Commands 表示执行运作-Args 执行参数-Flags 这些运作的标识符 举例 git clone 命令 git clone https://github.com/spf13/cobra.git -…

有玩家在2011年的MacBook上成功运行了Windows XP 还安装了触摸屏

我们已经在许多不同的设备上看到过 Windows XP 正在运行。这个古老的操作系统于 2001 年正式推出&#xff0c;现在已经老到其最后一次软件更新是在近十年前。一位好奇的玩家试图在 2011 年的触摸屏 MacBook 上为 Windows XP 打造了一个新家&#xff0c;复古技术探索者 Michael …

绽放光彩的小程序 UI 风格

绽放光彩的小程序 UI 风格