CSS-0_1 CSS和层叠(样式优先级、内联样式、选择器 用户代理样式)
CSS 的本质就是声明规则
——《深入解析CSS》
文章目录
- CSS
- 层叠和优先级
- 用户代理样式
- 请和用户代理样式和谐相处
- 选择器
- 单选择器的优先级
- 选择器组的优先级
- 关于选择器的其他
- 源码顺序
- 尽可能的选择优先级低的选择器
- 内联样式
- 内联样式和JavaScript
- !important
- 多个 !important
- 碎碎念
- 常用选择器
- 单独选择器
- 组合选择器
CSS
CSS,全称为:Cascading Style Sheets,翻译过来叫 层叠样式表
顾名思义,CSS由 层叠 和 样式表 两部分构成
样式表很好理解,CSS会给引用他的文档内的元素设定各种各样的样式,这些样式通常以键值对的形式出现。这使得CSS看起来就像是一份样式对照表一样,所以叫样式表
但是层叠是什么玩意呢?
层叠,汉语里被用来形容东西都堆在同一个地方的状态
由此可知,CSS的意思是:堆叠在一起作用于同一批元素上的N个样式表
也就是说,CSS的规则是叠加的,元素最终呈现出来的样式是多个CSS样式共同作用的结果。当这些CSS样式之间存在对同一个属性的指定,则需要应用优先级最高的那个,这就是层叠
层叠和优先级
先从最简单的开始,先看这段代码:
<body><h1>我是写在h1里面的文字</h1><p>我是p</p>
</body>
这段代码长这样:

这两段文字并没有紧贴到左上角,不过我们不会因此觉得奇怪,因为我们知道不同的HTML标签就是会展示出不同默认样式。实际上,默认样式这个称呼不标准,这个东西应该叫:用户代理样式
用户代理样式
用户代理(User Agent) ,是指你用来渲染这个HTML文档的计算机程序,最常见的当然就是浏览器了
所以用户代理样式说白了就是你用的那个浏览器给HTML标签的基础样式
这个样式会随着你所使用的浏览器不同呈现出不同的效果,比如上面那个例子是我在 chrome 里运行的效果,如果把浏览器换成 Firefox,她就会变成这样:

请和用户代理样式和谐相处
如你所见,不同的浏览器对同一种标签有不同的处理的方式,因此很多人将用户代理样式看作洪水猛兽,恨不得整个界面都用div+span写成以避开用户代理样式带来的影响
事实上,虽然各个浏览器的用户代理样式不尽相同,但原则上是一致的。h1-h6是加粗后的标题,p标签是带margin的独段文字,button是一个审美落后的按钮。HTML之所以要存在这么多标签,不是为了让浏览器给他们写个完美的用户代理样式,而是为了增强代码的可读性,让维护这段代码的其他人理解这个元素的意义,而不是对着一堆div做解谜游戏
选择器
用户代理样式是无法修改的,不过好在她的优先级是最低的,你写的任何css代码都可以轻易的覆盖她,就像这样:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><h1 class="normal_word">我是写在h1里面的文字</h1><p>我是p</p></body>
</html><style>.normal_word {font-weight: normal;}p {font-size: 4em;}
</style>

我们在style标签中让h1的文字失去的加粗,让p标签中的文字变成了原来的4倍
这种写法,行话叫用 选择器声明样式。由于本文不是主要说明选择器的,所以只在本文最后简单枚举一下常用的选择器
单选择器的优先级
对于 单选择器 来说,优先级遵循以下规律
ID选择器 > 类选择器 = 属性选择器 = 伪类选择器 > 标签选择器 > 通用选择器(*)
用户编写的css规则优先级的本质,其实就是比较所能影响的范围大小。所能影响的范围越小,元素越明确,那他的优先级越高
对单选择器来说:
- ID选择器 因为在同一个页面中id是唯一的,所以id选择器只指定一个元素,优先级最高
- 类选择器、属性选择器和伪类选择器 都是可以改变属性/状态一致的一批元素,所以优先级一致,排第二
- 标签选择器 就更多了,只要是html标签是指定的标签,就都会受到影响,所以优先级更低
- 通用选择器,所有的元素都会受到影响,几乎没有优先级可言
伪元素属于不同赛道的优先级,他必须依赖其他选择器存在,而且也必须用这种方式去指定他的样式,就像这样:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> <div id="d"><h1 class="green_word">我是div1中的文字</h1> </div> </body> </html><style>.green_word::after{display: block;content: "我是伪元素";color: red;}#d{color: green;} </style>
虽然我用id选择器要求div下的所有前景色变成绿色,但是使用类选择器+伪元素的前景色属性优先级还是比他高
选择器组的优先级
但是如果是选择器组,情况看起来就会复杂一点
就像这样:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<div class="normal_word"><h1 id="h">我是div1中的文字</h1>
</div>
</body>
</html><style>.normal_word {font-weight: normal;}.normal_word h1 {color: green;}#h {color: blue;}
</style>

类名+标签 的组合让这句话的文字变成绿色,但是 ID选择器 要求这句话的文字变成蓝色
最终的结果显然是ID选择器胜出了
你玩过德州扑克吗?简单来说就是玩家用自己手里的牌凑牌型,然后用凑出的牌型比大小,如果对方手里有比你大的牌型,那你手里的牌点数多大都是输。当双方牌型一样了,那我们就来比谁的点数大
选择器组在比较优先级时候的思路是一样的,选择器组相当于牌型,单选择器相当于点数。先看牌型,如果我有一个id选择器,那即使你手里有一万个类选择器优先级也没有我高
所以上例如果要让文字变成绿色应该这样做:
.normal_word {font-weight: normal;
}.normal_word #h {color: green;
}#h {color: blue;
}
.normal_word #h 的牌型是:类选择器+id选择器,#h 的牌型是 id选择器
id选择器和id选择器互相抵消,前者还有一个类选择器,后者什么都没有了,所以前者胜出,就像这样:

关于选择器的其他
源码顺序
还有一种情况的优先级值得说明一下,那就是当两者的选择器优先级完全一致的时候,写在后面的样式会覆盖前面的样式,就像这样:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<div class="blue_word" id="d"><h1 id="h" class="green_word">我是div1中的文字</h1>
</div>
</body>
</html><style>.blue_word #h {color: blue;}#d .green_word{color: green;}
</style>
两个选择器的都是 id选择器+类选择器,优先级完全一致,此时文字的颜色由写在后面的样式决定
所以他是绿色的:

(把位置对调你就可以得到蓝色的文字)
这个原则更多是用于你在一个页面上引用多个css文件的时候,把针对性越强的内容放在越后面引用,可以保证在选择器优先级一致的情况下应用针对性更强的样式
尽可能的选择优先级低的选择器
这个原则同样是在多个css文件共同工作时体现效力,如果你在前面的css文件中使用优先级太高的样式,会导致后面的针对性样式写起来很别扭
内联样式
你肯定知道,除了上文提到的那种指定元素样式的方式以外,你还可以通过把样式直接声明在元素的 style 属性中以指定这个元素的样式。这种写法我们将其称之为:内联样式
根据上文我们推出来的优先级本质,内联样式的优先级一定是极高的,因为他只能对一个元素生效,所以他比所有的选择器样式优先级都要高
就像这样:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<div class="green_word"><h1 id="d" style="color: purple;">我是div1中的文字</h1>
</div>
</body>
</html><style>h1{color: red;}.green_word *{color: blue;}#d {color: green;}
</style>

我们分别用 标签选择器、类+通用选择器 以及 id选择器指定了文字的不同颜色,但是最终生效的却是元素style属性里面定义的样式。这是内联样式高于所有选择器样式(或者说外部样式)的结果
那你会说了,不对啊,id选择器也是只对一个元素生效,为什么他的优先级没有内联样式高呢?
因为同一个页面里只能有一个ID这个效果,是我们给他加上的,并不是硬性要求,就像这样:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> <h1 id="d">我是div1中的文字</h1><h1 id="d">我是div2中的文字</h1> </body> </html><style>#d {color: green;} </style>
编辑器会提示你这种写法有问题,但是浏览器是接受的
内联样式和JavaScript
在实际开发中,我们经常会遇到使用JavaScript去修改元素样式的情况
这时候如果你用 element.style.…… 的方式去修改样式,其实你是在给这个元素添加内联样式,这会让所有与之相关的选择器失效
如果是针对性很强的JavaScript代码倒是问题不大,可如果考虑到复用性,这会导致所有引用你的JavaScript包的人想要修改这个元素的样式时感到很别扭
所以更优雅的做法应该是定义一个类选择器,然后在JavaScript中去维护这个元素的类列表
!important
有的时候,我们需要无视前面的所有规则,把某一条规则的优先级提到最高,这就是 !important 的领域了
就像这样:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<h1 class="red" style="color: blue">我是写在h1里面的文字</h1>
</body>
</html><style>.red {color: red;}h1 {color: green;}
</style>
很显然,根据前面我们已经讲过的规则,我们会得到一段蓝色的文字,就像这样:

这是因为内联样式优先级最高导致的,可是如果我在h1这个标签选择器的规则中添加 !important,那结果就会截然不同,就像这样:
h1 {color: green !important;
}

明明是刚刚那段代码中优先级最低的标签选择器的样式,被应用了
这就是 !important 标识的作用,他可以无视所有规则,要求指定的这条规则优先级提升到最高
多个 !important
那你会说了,既然如此,那如果 !important 也层叠了,那怎么办呢?就像这样:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<h1 class="red" style="color: blue !important;">我是写在h1里面的文字</h1>
</body>
</html><style>.red {color: red;}h1 {color: green !important;}
</style>
不只是标签选择器了,现在连内联选择器也有 !important 了
还记得我们前面提到过的“牌型理论”吗?我们现在把 !important 也当作一个牌型,最大的牌型。所以抵消掉之后,内联样式>标签选择器,所以我们会得到一段蓝色的文字
结果也印证了我们的猜想:

碎碎念
讲完了,最后整理一下CSS的层叠优先级
- 首先,CSS样式分两种,一种叫
用户代理样式,一种是作者样式- 用户代理样式是浏览器自带的样式,他的优先级永远比你写的作者样式优先级低
作者样式又分有两种,一种是通过选择器选中元素进行指定的外部样式,一种是直接写在元素内的style属性里的内联样式- 内联样式优先级默认比外部样式优先级高
- 外部样式之间则通过比较选择器的优先级来决定谁的优先级更高
- 伪元素属于另一个优先级赛道的选择器
- 当选择器优先级
完全一致的时候,应用哪个样式由书写顺序决定 - 当你想要无视一切优先级规则强制应用一个样式时,可以使用 !important
常用选择器
单独选择器
| 形式 | 选择器名 | 选择范围 |
|---|---|---|
| * | 通用选择器 | 选择所有元素 |
| p | 元素选择器 | 选择所有指定元素 |
| .className | 类选择器 | 选择所有class属性中包含className的元素 |
| #ID | ID选择器 | 选择所有id属性为ID的元素 |
| *[attr=value] | 属性选择器 | 选择所有attr属性为value的元素 |
| p:hover | 伪类选择器 | 选定所有p元素的hover状态 |
| p::after | 伪元素选择器 | 选定所有p元素后面的逻辑元素(没有实体的) |
组合选择器
| 形式 | 选择器名 | 选择范围 |
|---|---|---|
| A,B | 选择器列表(分组选择器) | 选中所有A和所有B |
| A B | 后代选择器 | 选中A内的所有B |
| A>B | 直接后代选择器 | 选中A内的所有直接子代B |
| A~B | 兄弟选择器 | 选择同个父元素下所有排在A后面的同级B(无论是否紧挨A) |
| A+B | 接续兄弟选择器 | 选择同个父元素下紧挨在A后面的同级B |
万分感谢您看完这篇文章,如果您喜欢这篇文章,欢迎点赞、收藏。还可以通过专栏,查看更多与【CSS笔记】有关的内容
相关文章:
CSS-0_1 CSS和层叠(样式优先级、内联样式、选择器 用户代理样式)
CSS 的本质就是声明规则 ——《深入解析CSS》 文章目录 CSS层叠和优先级用户代理样式请和用户代理样式和谐相处 选择器单选择器的优先级选择器组的优先级关于选择器的其他源码顺序尽可能的选择优先级低的选择器 内联样式内联样式和JavaScript !important多个 !important 碎碎念…...
科技赋能冷链园区:可视化带来全新体验
应用图扑可视化技术,冷链园区能够更加直观地监控和管理资源,优化运作流程,提高运营效率与服务质量。...
高通安卓12-安卓系统定制2
将开机动画打包到system.img里面 在目录device->qcom下面 有lito和qssi两个文件夹 现在通过QSSI的方式创建开机动画,LITO方式是一样的 首先加入自己的开机动画,制作过程看前面的部分 打开qssi.mk文件,在文件的最后加入内容 PRODUCT_CO…...
高中数学:数列-解数列不等式问题的常用放缩技巧(重难点)
一、放缩技巧 技巧1 例题 证明:Sn<1 解: 变形 解: 由于第一种情况,我们证明了Sn<1,n≥1,是从第一项就开始放缩的。 发现,无法精确到 3 4 \frac{3}{4} 43 这时&am…...
[图解]企业应用架构模式2024新译本讲解17-活动记录1
1 00:00:01,070 --> 00:00:04,180 下一个我们要说的就是 2 00:00:04,190 --> 00:00:06,740 活动记录模式了 3 00:00:07,640 --> 00:00:11,210 同样是数据源架构模式 4 00:00:12,300 --> 00:00:18,480 里面的一个,活动记录 5 00:00:18,490 --> 00…...
[C++深入] --- malloc/free和new/delete
1 new运算符的拓展 1.1 自由存储区与堆的概念 在C++中,内存区分为5个区,分别是堆、栈、自由存储区、全局/静态存储区、常量存储区。 自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。 new操作符从自由存储区(free st…...
Spcok测试代码抛异常场景
测试代码抛异常场景 class ExceptionSpec extends Specification {def validateService new ValidateService()Unrolldef "验证UserInfo"() {when: "调用校验方法"validateService.validateUser(user)then: "捕获异常并设置需要验证的异常值&qu…...
【漏洞复现】脸爱云一脸通智慧管理平台 SystemMng 管理用户信息泄露漏洞(XVE-2024-9382)
0x01 产品简介 脸爱云一脸通智慧管理平台是一套功能强大,运行稳定,操作简单方便,用户界面美观,轻松统计数据的一脸通系统。无需安装,只需在后台配置即可在浏览器登录。 功能包括:系统管理中心、人员信息管理中心、设备…...
新手如何入门Web3?
一、什么是Web3? Web3是指下一代互联网,它基于区块链技术,致力于将各种在线活动变得更加安全、透明和去中心化。Web3是一个广义的概念,涵盖了包括数字货币、去中心化应用、智能合约等在内的多个方面。它的主要特点包括去中心化、…...
React.FC`<ChildComponentProps>`解释
代码场景 ParentComponent.tsx import React, { useState } from react; import ChildComponent from ./ChildComponent;function ParentComponent() {const [childData, setChildData] useState<string>();const handleChildData (data: string) > { // 可以直接…...
2024-06-24力扣每日一题
链接: 503. 下一个更大元素 II 题意 循环数组,找出每个元素的往后最近且大于它的元素 解: 今天没试暴力啊,大概率是过不了的 思路就是先找到最大的数,最大数的结果肯定是-1,然后倒着遍历数组…...
pyhon模块以及常用的第三方模块
import my_info as info print(info.name) info.show()from my_info import * print(name) show() pyhon中包的导入 import admin.my_admin as ad # 包名.模块名 admin是包名,my_admin是模块名print(ad.name) print(ad.info())from admin import my_admin as ad # …...
shell脚本—快速修改centos网络配置
shell-文本中自行修改想要的配置 #!/bin/bash# 网卡名称 eth"eth0"# IP 地址 ipaddr"192.168.1.100"# 子网掩码 netmask"255.255.255.0"# 网关 gateway"192.168.1.1"# 写入配置文件 echo "BOOTPROTOstatic" > /etc/sysc…...
线程池概念、线程池的不同创建方式、线程池的拒绝策略
文章目录 💐线程池概念以及什么是工厂模式💐标准库中的线程池💐什么是工厂模式?💐ThreadPoolExecutor💐模拟实现线程池 💐线程池概念以及什么是工厂模式 线程的诞生是因为,频繁的创…...
示例:WPF中如何绑定ContextMenu和Menu
一、目的:开发过程中,有些模块的右键ContextMenu菜单是需要动态显示的,既是根据不同条件显示不同的菜单,很多是通过代码去生成ContextMenu的MenuItem,本文介绍通过绑定的方式去加载ContextMenu,Menu菜单栏的…...
区块链小故事
大灰狼与小白兔 一天兔子妈妈出门了,在大门上安装了一个区块链的门把手,这个门把手只有兔子妈妈、小兔子、以及另一个客人都同意的时候,才会开门,有一天客人a的钥匙丢了,被大灰狼捡到了,大灰狼于是去开门&…...
Java | Leetcode Java题解之第167题两数之和II-输入有序数组
题目: 题解: class Solution {public int[] twoSum(int[] numbers, int target) {int low 0, high numbers.length - 1;while (low < high) {int sum numbers[low] numbers[high];if (sum target) {return new int[]{low 1, high 1};} else i…...
项目训练营第三天
项目训练营第三天 注册登录测试 前面我们编写了用户注册、登录的逻辑代码,每编写完一个功能模块之后,我们都要对该模块进行单元测试,来确保该功能模块的正确性。一般情况下使用快捷键Ctrl Shift Insert,鼠标左击类名可以自动生…...
计算机组成原理 | CPU子系统(1)基本概述
基本结构模型 运算与缓存部件 数据寄存部件 PSW不是很清楚 存储器是什么?属于那个结构里? 时序处理部件 cpu是大脑,控制器是神经元 ①通过硬件产生控制信号 ②通过软件产生控制信号 外频(系统时钟信号),…...
无引擎游戏开发(2):最简游戏框架 | EasyX制作井字棋小游戏I
一、EasyX中的坐标系 不同于数理中的坐标系,EasyX中的y轴是竖直向下的 二、渲染缓冲区 之前的程序添加了这三个函数改善了绘图时闪烁的情况: 小球在"画布“上移动的过程就是我们在调用绘图函数,这个”画布“就是渲染缓冲区,先绘制的内…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...



