深入解析CSS

news/2024/10/8 6:21:57

层叠、优先级和继承

层叠

层叠指的就是这一系列规则

它决定了如何解决css样式规则冲突,是 CSS 语言的基础。

虽然有经验的开发人员对层叠有大体的了解,但是层叠里有些规则还是容易让人误解。

当声明冲突时,层叠会依据三种条件解决冲突:

  1. 样式表的来源:样式是从哪里来的,包括你的样式和浏览器默认样式等。
  2. 选择器优先级:哪些选择器比另一些选择器更重要。
  3. 源码顺序:样式在样式表里的声明顺序。

下图概括展示了规则的用法:

这些规则让浏览器以可预测的方式解决 CSS 样式规则的冲突。

样式表的来源

样式的来源主要分为2中:

  1. 书写的样式表,即作者样式表
  2. 用户代理样式表,即浏览器默认样式

用户代理样式表优先级低,你的样式会覆盖它们

!important 声明

样式来源规则有一个例外标记为重要( important)的声明。 如下所示, 在声明的后面、分号的前面加上!important,该声明就会被标记为重要的声明。

color: red !important;

标记了!important 的声明会被当作更高优先级的来源, 因此总体的优先级按照由高到低排列如下所示:

  1. 作者的!important
  2. 作者样式表
  3. 用户代理样式表

理解优先级

如果无法用来源解决冲突声明,浏览器会尝试检查它们的优先级

理解优先级很重要。

不理解样式的来源照样可以写 CSS,因为 99%的网站样式是来自同样的源。但是如果不理解优先级,就会被坑得很惨。不幸的是,很少有人提及这个概念。

浏览器将优先级分为两部分: HTML 的行内样式选择器的样式

行内样式

如果用 HTML 的 style 属性写样式,这个声明只会作用于当前元素。实际上行内元素属于“带作用域的”声明,它会覆盖任何来自样式表或者<style>标签的样式

行内样式没有选择器,因为它们直接作用于所在的元素。

为了在样式表里覆盖行内声明,需要为声明添加!important,这样能将它提升到一个更高优先级的来源

如果行内样式也被标记为!important,就无法覆盖它了

最好是只在样式表内用!important

选择器优先级

不同类型的选择器有不同的优先级。比如, ID 选择器比类选择器优先级更高

实际上, ID选择器的优先级比拥有任意多个类的选择器都高。同理,类选择器的优先级比标签选择器(也称类型选择器)更高

优先级的准确规则如下:

  1. 如果选择器的 ID 数量更多,则它会胜出(即它更明确)。
  2. 如果 ID 数量一致,那么拥有最多类的选择器胜出。
  3. 如果以上两次比较都一致,那么拥有最多标签名的选择器胜出。

说明:

伪类选择器(如:hover)和属性选择器(如[type="input"])与一个类选择器的优先级相同。

*通用选择器( )和组合器( >、 +、 ~)对优先级没有影响。

如果你在 CSS 里写了一个声明,但是没有生效,一般是因为被更高优先级的规则覆盖了。

很多时候开发人员使用 ID 选择器,却不知道它会创建更高的优先级,之后就很难覆盖它

如果要覆盖一个 ID 选择器的样式,就必须要用另一个 ID 选择器。

优先级标记

一个常用的表示优先级的方式是用数值形式来标记,通常用逗号隔开每个数

比如,“1,2,2”表示选择器由 1 个 ID、 2 个类、 2 个标签组成。优先级最高的 ID 列为第一位,紧接着是类,最后是标签

选择器 ID 标签 标记
html body header h1 0 0 4 0,0,4
body header.page-header h1 0 1 3 0,1,3
.page-header .title 0 2 0 0,2,0
#page-title 1 0 0 1,0,0

有时,人们还会用 4 个数的标记,其中将最重要的位置用 0 或 1 来表示,代表一个声明是否是用行内样式添加的。此时,行内样式的优先级为“1,0,0,0”。它会覆盖通过选择器添加的样式,比如优先级为“0,1,2,0”( 1 个 ID 和 2 个类)的选择器。

关于优先级的思考

优先级容易发展为一种“军备竞赛”。在大型项目中这一点尤为突出。

通常最好让优先级尽可能低,这样当需要覆盖一些样式时,才能有选择空间

源码顺序

层叠的第三步,也是最后一步,是源码顺序。

如果两个声明的来源和优先级相同,其中一个声明在样式表中出现较晚,或者位于页面较晚引入的样式表中,则该声明胜出。

链接样式和源码顺序

你刚开始学习 CSS 时,或许就知道给链接加样式要按照一定的顺序书写选择器。这是因为源码顺序影响了层叠

a:link {color: blue;text-decoration: none;
}
a:visited {color: purple;
}
a:hover {text-decoration: underline;
}
a:active {color: red;
}

书写顺序之所以很重要,是因为层叠。

优先级相同时,后出现的样式会覆盖先出现的样式。
如果一个元素同时处于两个或者更多状态,最后一个状态就能覆盖其他状态。如果用户将鼠标悬停在一个访问过的链接上,悬停效果会生效。如果用户在鼠标悬停时激活了链接(即点击了它),激活的样式会生效。

层叠值

层叠值——作为层叠结果,应用到一个元素上的特定属性的值

浏览器遵循三个步骤,即来源、优先级、源码顺序,来解析网页上每个元素的每个属性。如果一个声明在层叠中“胜出”,它就被称作一个层叠值

元素的每个属性最多只有一个层叠值。

两条经验法则

处理层叠时有两条通用的经验法则。因为它们很有用:

  1. 在选择器中不要使用 ID

    就算只用一个 ID,也会大幅提升优先级。当需要覆盖这个选择器时,通常找不到另一个有意义的 ID,于是就会复制原来的选择器,然后加上另一个类,让它区别于想要覆盖的选择器。

  2. 不要使用!important。

    它比 ID 更难覆盖,一旦用了它,想要覆盖原先的声明,就需要再加上一个!important,而且依然要处理优先级的问题。

这两条规则是很好的建议,但不必固守它们,因为也有例外。

继承

还有最后一种给元素添加样式的方式: 继承

经常有人会把层叠跟继承混淆。

虽然两者相关,但是应该分别理解它们。

如果一个元素的某个属性没有层叠值,则可能会继承某个祖先元素的值。

比如通常会给<bod\y>元素加上 font-family,里面的所有后代元素都会继承这个字体,就不必给页面的每个元素明确指定字体了。

不是所有的属性都能被继承

默认情况下,只有特定的一些属性能被继承,通常是我们希望被继承的那些。它们主要是跟文本相关的属性: color、 font、 font-family、 font-size、font-weight、 font-variant、 font-style、 line-height、 letter-spacing、 text-align、text-indent、 text-transform、 white-space 以及 word-spacing。

还有一些其他的属性也可以被继承,比如列表属性: list-style、 list-style-type、list-style-position 以及 list-style-image。

表格的边框属性 border-collapse 和border-spacing 也能被继承。注意,这些属性控制的是表格的边框行为,而不是常用于指定非表格元素边框的属性。(恐怕没人希望将一个<div>的边框传递到每一个后代元素。)以上为不完全枚举,但是已经很详尽了。

特殊值

两个特殊值可以赋给任意属性,用于控制层叠inheritinitial

使用inherit关键字

有时,我们想用继承代替一个层叠值。这时候可以用 inherit 关键字。

可以用它来覆盖另一个值,这样该元素就会继承其父元素的值

还可以使用 inherit 关键字强制继承一个通常不会被继承的属性,比如边框和内边距。

通常在实践中很少这么做,但是盒模型时,你会看到一个实际用例。

使用initial关键字

有时,你需要撤销作用于某个元素的样式。这可以用 initial 关键字来实现。

每一个 CSS属性都有初始(默认)值

如果将 initial 值赋给某个属性,那么就会有效地将其重置为默认值,这种操作相当于硬复位了该值。

你可能已经习惯了使用 auto 来实现这种重置效果。实际上,用 width: auto 是一样的,因为 width 的默认值就是 auto。

但是要注意, auto 不是所有属性的默认值对很多属性来说甚至不是合法的值

比如border-width: auto 和 padding: auto 是非法的,因此不会生效。

可以花点时间研究一下这些属性的初始值,不过使用 initial 更简单。

说明:声明 display: initial 等价于 display: inline。不管应用于哪种类型的元素,它都不会等于 display: block。这是因为 initial 重置为属性的初始值,而不是元素的初始值。 inline 才是 display 属性的初始值。

简写属性

简写属性是用于同时给多个属性赋值的属性

比如 font 是一个简写属性,可以用于设置多种字体属性。 它指定 了 font-style、 font-weight、 font-size、 font-height 以 及font-family。

简写属性会默默覆盖其他样式

大多数简写属性可以省略一些值,只指定我们关注的值

但是要知道,这样做仍然会设置省略的值,即它们会被隐式地设置为初始值。这会默默覆盖在其他地方定义的样式

比如,如果给网页标题使用简写属性 font 时,省略 font-weight,那么字体粗细就会被设置为 normal。

理解简写值的顺序

简写属性会尽量包容指定的属性值的顺序

可以设置 border: 1px solid black 或者border: black 1px solid,两者都会生效。

这是因为浏览器知道宽度、颜色、边框样式分别对应什么类型的值

但是有很多属性的值很模糊

在这种情况下,值的顺序很关键。理解这些简写属性的顺序很重要。

上、右、下、左

当遇到像 margin、 padding 这样的属性,还有为元素的四条边分别指定值的边框属性时,开发者容易弄错这些简写属性的顺序。这些属性的值是按顺时针方向,从上边开始的。

记住顺序能少犯错误。它的记忆口诀是 TRouBLe: top(上)、 right(右)、 bottom(下)、 left(左)。

水平、垂直

还有一些属性只支持最多指定两个值,这些属性包括 background-position、 box-shadow、 text-shadow(虽然严格来讲它们并不是简写属性)。

这些属性值的顺序跟 padding 这种四值属性的顺序刚好相反。比如, padding: 1em 2em 先指定了垂直方向的上/下属性值,然后才是水平方向的右/左属性值,而 background-position: 25% 75%则先指定水平方向的右/左属性值,然后才是垂直方向的上/下属性值。

虽然看起来顺序相反的定义违背了直觉,原因却很简单:这两个值代表了一个笛卡儿网格。笛卡儿网格的测量值一般是按照 x, y(水平,垂直)的顺序来的。

技巧:如果属性需要指定从一个点出发的两个方向的值,就想想“笛卡儿网格”
如果属性需要指定一个元素四个方向的值,就想想“时钟”。

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

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

相关文章

宝塔面板如何删除一个站点

我们一般的网站都是PHP+MySQL开发的,所以删除站点,就要先删数据库,再删网站目录 注意:一点要确保无用的再删 删除站点目录 十年开发经验程序员,离职全心创业中,历时三年开发出的产品《唯一客服系统》一款基于Golang+Vue开发的在线客服系统,软件著作权编号:2021SR146260…

AnsysEM安装教程(Linux)

前期准备 解压相关安装文件 unzip Crack.zip将安装iso文件挂载到/mnt/AnsysEM目录下 sudo mkdir /mnt/AnsysEm sudo mount Ansys.Electronics.2021.R1.Linux64.iso /mnt/AnsysEM/ -o loop转到/mnt/AnsysEM/目录下,打开Readme文件查看安装步骤教程 创建AnsysEM安装目录 sudo mk…

百舸实践之「埋点数据深度治理与应用」 | 京东云技术团队

一、背景 随着公司和业务的不断发展,百舸平台也从单一内容投放转向了以流量和数据为基础的流量运营模式。在这个转变过程中,数据深度治理与应用的重要性尤为凸显,在数据深度治理过程中,需要将用户行为数据、投放素材以及投放效果三者紧密的串联起来。数据深度治理和应用,一…

【进阶篇】基于 Redis 实现分布式锁的全过程

这一篇文章拖了有点久,虽然在项目中使用分布式锁的频率比较高,但整理成文章发布出来还是花了一点时间。在一些移动端、用户量大的互联网项目中,经常会使用到 Redis 分布式锁作为控制访问高并发的工具。目录前言一、关于分布式锁二、RedLock 红锁(不推荐)三、基于 setIfAbs…

pdf.js源码解析-渲染的时序分析

首先来一张总结的图,也就是pdf.js在解析和渲染pdf的一个时序图,下图:首先要明白,pdf.js在渲染pdf的时候是做分层渲染,也就是时间展现的内容是通过canvas进行绘制的,而我们通过鼠标进行选择时候的内容是通过dom进行普通渲染,也就是 <div>123</div> 这样的普通…

权威SAFe大规模敏捷企业级内训及SAFe敏捷认证

​ SAFe – Scaled Agile Framework是目前全球运用最广泛的大规模敏捷框架,也是成长最快、最被认可、最有价值的规模化敏捷框架,目前全球SAFe认证专业人士已达80万人,福布斯100强的70%都在实施SAFe。本课程是一个2天的 SAFe权威培训课程,在课程中,学员将系统地学习大规模敏…

ping ip、域名、端口

一、pingping baidu.com ping 192.168.9.9 综上所诉,ping命令的时候格式为(注意ping后面需要跟上一个空格) ①ping IP地址或主机域名 ②ping IP地址或主机域名+命令参数 ③ ping 命令参数+IP地址或主机域名 ping命令参数说明查看ping命令帮助 ping /? 输入上面的命令,我们…