【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,一经查实,立即删除!

相关文章

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

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

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需求获取基本步骤、项目过程建立涉及工作、项目规划过程域的意图和专用目标 判定表、分支覆盖、条件覆盖 三、简答 四、应用 这里条件覆盖有待商榷

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

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

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

看了很多篇解决措施&#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…

C语言中的内存动态管理

1.为什么有动态内存管理 int a20;//开辟4个字节 int arr[10]{0};//开辟40个字节 上述的代码有两个特点 1.开辟空间的大小是固定的。 2.数组在申明的时候已经固定了大小&#xff0c;无法更改。 这样写代码不够灵活&#xff0c;所以c语言中引入了动态内存管理&#xff0c;让程序…

Springboot整合Kafka消息队列服务实例

一、Kafka相关概念 1、关于Kafka的描述 Kafka是由Apache开源&#xff0c;具有分布式、分区的、多副本的、多订阅者&#xff0c;基于Zookeeper协调的分布式处理平台&#xff0c;由Scala和Java语言编写。通常用来搜集用户在应用服务中产生的动作日志数据&#xff0c;并高速的处…

Milvus 2.4 向量库安装部署

1、linux 已有docker环境 2、安装fio命令 yum install -y fio 2、mkdir test-data fio --rwwrite --ioenginesync --fdatasync1 --directorytest-data --size2200m --bs2300 --namemytest ctrlc 3、lscpu 4、docker -v 6、安装docker compose组件 yum -y install python3-…

Maven下载安装、环境配置(超详细)(包括Windows、IDEA)

目录 一、引言 二、下载和安装 Maven &#xff08;1&#xff09;首先保证 Java 的环境是正常的。 1、电脑桌面上右击 " 此电脑 "&#xff0c;点击属性。 2、点击高级系统设置。 3、点击环境变量。 4、找到系统变量中的 Path。 5、点击新建&#xff0c;然后把…

深度剖析ElasticSearch分页原理与深分页问题|ES深分页问题|ES分页原理剖析

文章目录 ES分页|Paginate search resultsES深分页的问题一页获取数据量太大&#xff0c;报错分页深度太大&#xff0c;报错官方解释 其他解决方案Search after解决两个问题 有没有深分页查询的必要性&#xff1f;search after & PIT的使用方式1.创建pit2.首次查询3.之后的…

【C++】#20,#21

#20类和对象 #include <iostream>using namespace std;class Box{public: //公有 double length; //ctrle复制本行 double width;double height;void getVolume(){ //方法带&#xff08;&#xff09; cout<<"盒子体积为&#xff1a;"<<le…

我在高职教STM32——LCD液晶显示(1)

大家好&#xff0c;我是老耿&#xff0c;高职青椒一枚&#xff0c;一直从事单片机、嵌入式、物联网等课程的教学。对于高职的学生层次&#xff0c;同行应该都懂的&#xff0c;老师在课堂上教学几乎是没什么成就感的。正因如此&#xff0c;才有了借助 CSDN 平台寻求认同感和成就…

十、数据结构(图的基础)

文章目录 什么是图图的分类图算法的复杂度 图的模拟怎么储存一个图邻接矩阵&#xff1a;邻接矩阵的定义方式优劣分析 邻接表优劣分析实现代码 链式前向星实现代码优劣分析 图的遍历某个点的连通性拓扑排序1.拓扑排序的概念2.图的入度和出度3.基于 B F S BFS BFS的拓扑排序复杂度…

uniapp公用返回组件

uniapp写一个公用的头部组件&#xff0c;包含home和返回。 页面中的引用 2.在components文件夹下&#xff0c;新建一个navBar.vue <template><view class"view-wrap"><view :style"{ height: barHeight }"></view><view cla…

web前端之vue一键部署的shell脚本和它的点.bat文件、海螺AI、ChatGPT

MENU 前言vite.config.ts的配置deploy文件夹的其他内容remote.shpwd.txtdeploy.bat 前言 1、在src同级新建deploy.bat文件&#xff1b; 2、在src同级新建deploy文件夹&#xff0c;文件夹中新建pwd.txt和remote.sh文件&#xff1b; 3、配置好后&#xff0c;直接双击deploy.bat文…