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轴是竖直向下的 二、渲染缓冲区 之前的程序添加了这三个函数改善了绘图时闪烁的情况: 小球在"画布“上移动的过程就是我们在调用绘图函数,这个”画布“就是渲染缓冲区,先绘制的内…...

排书 IDA*
原题链接 题目描述 给定 n 本书,编号为 1∼n。 在初始状态下,书是任意排列的。在每一次操作中,可以抽取其中连续的一段,再把这段插入到其他某个位置。我们的目标状态是把书按照 1∼n 的顺序依次排列。求最少需要多少次操作。 输…...

playwright录制脚本原理
Paywright录制工具UI 在上一篇博客中介绍了如何从0构建一款具备录制UI测试的小工具。此篇博客将从源码层面上梳理playwright录制原理。当打开playwright vscode插件时,点击录制按钮,会开启一个新浏览器,如下图所示,在新开浏览器页…...

awk脚本监控
awk脚本监控 使用脚本监控内存,cpu和硬盘的根目录,超过80%提示用户,写成函数库的行,每天早上 的8.50分,执行一次脚本 现在脚本中写需要的内容 cpuu () {aa$(top -b -n 1 |awk NR3 {printf "%.F",$2$4})if …...

Python高压电容导电体和水文椭圆微分
🎯要点 🎯二维热传导二阶偏微分方程 | 🎯调和函数和几何图曲率 | 🎯解潮汐波动方程 | 🎯解静止基态旋转球体流体运动函数 | 🎯水文空间插值 | 🎯流体流动模拟求解器 | 🎯随机算法解…...

微信小程序 引入MiniProgram Design失败
这tm MiniProgramDesign 是我用过最垃圾的框架没有之一 我按照官网的指示安装居然能安装不成功,牛! 这里说明我是用js开发的 到以上步骤没有报错什么都没有,然后在引入组件的时候报错 Component is not found in path “./miniprogram _npm/vant/weapp/button/index” (using…...

Java 8 Date and Time API
Java 8引入了新的日期和时间API,位于java.time包下,旨在替代旧的java.util.Date和java.util.Calendar类。新API更为简洁,易于使用,并且与Joda-Time库的一些理念相吻合。以下是Java 8 Date and Time API中几个核心类的简要概述&…...

pyppeteer模块经常使用的功能,相关操作案例
官方仓库地址:https://github.com/miyakogi/pyppeteer 官方文档地址:API Reference — Pyppeteer 0.0.25 documentation Selenium环境的相关配置比较繁琐,此外,有的网站会对selenium和webdriver进行识别和反爬,因此在…...

nginx+keepalived+tomcat集群实验
如遇星河 | nginx+keepalived高可用集群实验 木子87 | Keepalived+Nginx+Tomcat 实现高可用Web集群 环境 192.168.40.204 tomcat-1 192.168.40.138 tomcat-2 安装tomcat [root@bogon local]# vim /etc/profile 添加环境变量 JAVA_HOME=/usr/local/java PATH=$J…...

vue脚手架 axios的二次封装
目录 01 路由懒加载(重要) 02 axios在脚手架中的使用 03.axios的二次封装 04 组件缓存 01 路由懒加载(重要) 一次性导入会出现严重的问题 : 首屏卡顿 因为main.js中引入了router/index.js router/index.js又使用了import语句 静态的引入了每一个组件 导致了首屏卡顿 所以我…...

人机恋爱新趋势:与AI男友谈恋爱的甜蜜与挑战
"我曾经把ChatGPT当成工具,从未追过星,也没有嗑过CP。没想到,到了36岁,我竟然嗑上了AI男友。Open AI,你赢了。你不仅是最好的AI公司,还是乙女游戏公司。" 转行大龄互联网人,走遍20国…...