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

news2025/1/22 15:58:33

文章目录

      • 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.coloradmin.cn/o/1837547.html

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

相关文章

kaggle notebook和jupyter notebook读取csv

kaggle本地比赛用打开notebook的示例代码可以获取当前比赛的文件数据路径&#xff0c;进而后续直接复制读取 jupyter notebook读取csv 直接下载数据集到电脑上&#xff0c;并用本地路径读取就行。

ElasticSearch学习篇13_《检索技术核心20讲》进阶篇之LSM树

背景 学习极客实践课程《检索技术核心20讲》https://time.geekbang.org/column/article/215243&#xff0c;文档形式记录笔记。 内容 磁盘和内存数据读取特点 工业界中数据量往往很庞大&#xff0c;比如数据无法全部加载进内存&#xff0c;无法支持索引的高效实时更新&…

QT day04

一、思维导图 二、登录界面优化 代码&#xff1a; 界面&#xff1a; *{background-color: rgb(255, 255, 255); }QFrame#frame{border-image: url(:/Logo/shanChuan.jpg);border-radius:15px; }#frame_2{background-color: rgba(110, 110, 110, 120);border-radius:15px; }Q…

ionic 项目通过 android studio 打开报错 capacitor.settings.gradle 文件不存在

问题出现 原因分析 在程序相应的目录上面&#xff0c;没有找到对应的配置文件&#xff0c;但是这个文件不是我们自己生成的&#xff0c;而是通过 ionic 编译之后生成。 处理方案 先执行 ionic build&#xff0c;将 ionic 项目打包出来然后执行 npx cap sync 再使用 Android…

【小白专用 已验证24.6.18】C# SqlSugar操作MySQL数据库实现增删改查

【小白专用24.6.18】C# SqlSugar&#xff1a;连接数据库实现简单的&#xff0c;增、删、改、查-CSDN博客 SqlSugar .Net ORM 5.X 官网 、文档、教程 - SqlSugar 5x - .NET果糖网 SqlSugar项目创建 通过NuGet包管理器搜索SqlSugar&#xff08;MySql还要安装MySql.Data、Newton…

C++ | Leetcode C++题解之第165题比较版本号

题目&#xff1a; 题解&#xff1a; class Solution { public:int compareVersion(string version1, string version2) {int n version1.length(), m version2.length();int i 0, j 0;while (i < n || j < m) {long long x 0;for (; i < n && version1[…

HTML+CSS+PHP实现网页留言板功能(需要创建数据库)

话说前头&#xff0c;我这方面很菜滴。这是我网页作业的一部分。 1.body部分效果展示&#xff08;不包括footer&#xff09; 2、代码 2.1 leaving.php&#xff08;看到的网页&#xff09; <!DOCTYPE html> <html lang"en"> <head> <met…

Flask之模板

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 目录 一、模板的基本用法 1.1、创建模板 1.2、模板语法 1.3、渲染模板 二、模板辅助工具 2.1、上下文 2.2、全局对象 2.3、过滤器 2.4、测试…

低市值Pow赛道解析,探寻百倍潜力项目

随着铭文的火爆出圈&#xff0c;比特币减半的到来&#xff0c;关于Pow赛道的讨论也在变得火热&#xff0c;不少投资机构都将Pow赛道作为2024年分析的重点。Pow赛道又来已久&#xff0c;不少项目的市值都超过10亿美元&#xff0c;而对于大多数投资者来说&#xff0c;低市值高回报…

Mp3文件结构全解析(一)

Mp3文件结构全解析(一) MP3 文件是由帧(frame)构成的&#xff0c;帧是MP3 文件最小的组成单位。MP3的全称应为MPEG1 Layer-3 音频 文件&#xff0c;MPEG(Moving Picture Experts Group) 在汉语中译为活动图像专家组&#xff0c;特指活动影音压缩标准&#xff0c;MPEG 音频文件…

Spring事务 和 事务传播机制

这里的 事务 和之前 MySQL的事务 一样&#xff0c;都是表示将⼀组操作封装成⼀个执⾏单元&#xff08;封装到⼀起&#xff09;&#xff0c;要么全部成功&#xff0c;要么全部失败。 Spring 中事务的实现 1. 编程式事务&#xff08;手动档&#xff09;。 package com.example.…

图论之岛屿系列

图论之岛屿系列 形成模板进行学习&#xff0c;加快学习效率 深度优先遍历 # 可以直接改原始grid的采用直接改的方案来完成修改&#xff0c;减少了内存开支 def dfs(self, grid, i, j):if i < 0 or j < 0 or i > len(grid) or j > len(grid[0]) or grid[i][j] &…

无引擎底层游戏开发(1):EasyX图形库引入 + 跟随鼠标移动的小球

来自bilibili up主的Voidmatrix的视频教程&#xff1a;【从零开始的C游戏开发】 一、图形库引入 EasyX在国内文档最多&#xff0c;而且功能函数齐全&#xff0c;最适合入门。 环境配置&#xff1a;vs2022 &#xff08;官网下载免费版&#xff09; 百度搜EasyX官方&#xff0…

AI搜索工具,提升你的工作效率

当我们需要查询某个内容的时候&#xff0c;除了可以通过搜索引擎来查找&#xff0c;还可以通过AI搜索工具来查找。AI搜索工具会智能的从网络信息中查找答案并整理后给我们结果。除了搜索结果&#xff0c;AI搜索工具还可以用来帮我们创作内容&#xff0c;比如你需要写一篇文章&a…

【博弈】843. 猜猜这个单词

本题涉及知识点 博弈 LeetCode843. 猜猜这个单词 给你一个由 不同 字符串组成的单词列表 words &#xff0c;其中 words[i] 长度均为 6 。words 中的一个单词将被选作秘密单词 secret 。 另给你一个辅助对象 Master &#xff0c;你可以调用 Master.guess(word) 来猜单词&…

Harbor本地仓库搭建003_Harbor常见错误解决_以及各功能使用介绍_镜像推送和拉取---分布式云原生部署架构搭建003

首先我们去登录一下harbor,但是可以看到,用户名密码没有错,但是登录不上去 是因为,我们用了负债均衡,nginx会把,负载均衡进行,随机分配,访问的 是harbora,还是harborb机器. loadbalancer中 解决方案,去loadbalance那个机器中,然后 这里就是25机器,我们登录25机器 然后去配置…

CentOS 7x 使用Docker 安装oracle11g完整方法

1.安装docker-ce 安装依赖的软件包 yum install -y yum-utils device-mapper-persistent-data lvm2添加Docker的阿里云yum源 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo更新软件包索引 yum makecache fast查看docker…

MacOS - command not found: brew

问题描述 command not found: brew 原因分析 没有安装 Homebrew&#xff0c;安装后即可使用~ 解决方案 打开终端&#xff0c;输入&#xff1a;/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"&#xff0c;点击回车 在弹出…

FlinkCDC介绍及使用

CDC简介 什么是CDC&#xff1f; cdc是Change Data Capture(变更数据获取)的简称。核心思想是&#xff0c;监测并捕获数据库的 变动(包括数据或数据表的插入&#xff0c;更新以及删除等)&#xff0c;将这些变更按发生的顺序完整记录下来&#xff0c;写入到消息中间件以供其它服…

归并排序 (递归实+非递归)

前言 归并排序是一种逻辑很简单&#xff0c;但是实现有点难度的排序&#xff0c;尤其是非递归&#xff0c;对于区间的把握更是需要一点逻辑的推导&#xff0c;但是没有关系&#xff0c;轻松拿捏 归并排序gif 归并排序单趟实现 1&#xff0c;创建tmp数组&#xff0c; 2&#xff…