首页 > 其他分享 >深入解析CSS

深入解析CSS

时间:2024-05-06 15:33:23浏览次数:18  
标签:优先级 样式 深入 样式表 层叠 解析 选择器 CSS 属性

层叠、优先级和继承

层叠

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

它决定了如何解决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(水平,垂直)的顺序来的。

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

标签:优先级,样式,深入,样式表,层叠,解析,选择器,CSS,属性
From: https://www.cnblogs.com/niehao/p/18175098

相关文章

  • HTML & CSS – Styling Scrollbar
    前言Scrollbar能styling的东西不多,但有时候不得不styling。这里记入我自己在项目中修改过的scrollbar经历。 GmailScrollbar Gmail的scrollbar就改过style。   ......
  • 光AP测试用例参数解析
    光AP测试用例wireshark抓包/log(射频功率、频宽、协议类型、信道)【概要】AC修改射频配置后,使用wireshark和aplog确认配置成功下发并同步到AP【步骤】Ap后台使用命令【syswan2lanon】映射,wireshark抓以太网包显示频宽:AC下发“configurationupdatarequest”包配置,其中,“message......
  • 深入了解Appium:Capability 高级配置技巧解析
    简介Appium的除了基础的Capability设置,还提供了许多辅助配置项,用于优化自动化测试。这些配置项旨在执行基础配置之外的附加操作。例如:指定设备别名、设备ID或是设置超时时间等,虽然这些不是必需的选项,但是为了实现更高效的测试,通常也建议依据测试的情况适当的添加。xcuites......
  • 【动画进阶】巧用 CSS/SVG 实现复杂线条光效动画
    最近,群里在讨论一个很有意思的线条动画效果,效果大致如下:简单而言,就是线条沿着不规则路径的行进动画,其中的线条动画可以理解为是特殊的光效。本文,我们将一起探索,看看在不使用JavaScript/Canvas的基础上,使用纯CSS/SVG的方式,我们可以如何大致的还原上述的线条动画效果。基于......
  • CSS mask 与 切图艺术
    一、“切图”的局限性传统的“切图”简单暴力,但往往缺少适应性。适应性一般有两种,一是尺寸自适应,二是颜色可以自定义。举个例子,有这样一个优惠券样式关于这类样式实现技巧,之前在这篇文章中有详细介绍:CSS实现优惠券的技巧不过这里略微不一样的地方是,两个凹陷处都是平滑处理......
  • 使用 CSS columns 布局来实现自动分组布局
    最近在项目中碰到这样一个布局,有一个列表,先按照4*2的正常顺序排列,当超过8个后,会横向重新开始4*2的布局,有点像一个个独立的分组,然后水平排列,如下图中序号是 dom 序列,所以其实这这样的一个顺序很多同学可能会想到给子元素分组(通过 JS将原数组拆分组合成一个二维数......
  • 深入学习和理解Django模板层:构建动态页面
    title:深入学习和理解Django模板层:构建动态页面date:2024/5/520:53:51updated:2024/5/520:53:51categories:后端开发tags:Django模板表单处理静态文件国际化性能优化安全防护部署实践第一章:模板语法基础Django模板语法介绍Django模板语法是一种简洁而......
  • CSS 盒模型
    在css中,所有元素都被一个个的"box"包围着,理解这些盒子的基本原理,是实现用css实现精准布局,处理元素排列的关键.标准盒模型盒子模型的组成元素:content:内容区padding:内天成border:边框margin:外边距在标准盒模型中,盒的width/height指......
  • Blazor流程编排的艺术:深入Z.Blazor.Diagrams库的使用与实践
        为现代网页应用开发提供动力的其中一个重要方面就是前端框架的强大功能与灵活性。而在.NET生态中,Blazor以其独特的工作方式和优势逐渐获得了开发者们的青睐。今天,在这篇文章中,我将带你深入探索一个基于Blazor的优秀库——Z.Blazor.Diagrams,我们将了解它是如何帮助开发......
  • Sxstrace.exe 是 Windows 操作系统提供的一个工具,用于跟踪和分析应用程序的依赖项解析
    sxstrace|MicrosoftLearnSxstrace.exe是Windows操作系统提供的一个工具,用于跟踪和分析应用程序的依赖项解析过程。该工具可以帮助用户诊断应用程序启动或运行时出现的依赖项错误或加载问题。在Windows中,许多应用程序依赖于共享组件和库文件,如动态链接库(DLL)。当应用......