CSS 重新认识 !important 肯定有你不知道的

news2024/12/25 2:57:19
  • 重新认识 !important
    • 影响级联规则
      • 与 animation 和 transition 的关系
      • 级联层cascade layer
      • 内联样式
      • !important 与权重
    • !important 与简写属性
    • !important 与自定义变量
    • !important 最佳实践

在开始之前, 先来规范一下文中的用于, 首先看 W3C 中关于 CSS 的一些术语定义吧. 下图来自 W3C

在这里插入图片描述

我们将一个完整的 color: blue; 称为一个声明(declaration), 其中 color 称为属性(property), blue 称为值(value)

重新认识 !important

!important 表示 CSS 声明是「重要」的. !important 改变了 CSS 级联中究竟使用哪个 CSS 声明的规则. 如果一个 CSS 声明不是重要(important)的, 那么就称其为一般(normal)声明.

我们只需要将 !important 加在一个 CSS 声明的值的后面, 要加上至少一个空格, !important 之间可以有空格, 但是通常没有空格

.box {
  border-radius: 10px; /* normal declaration */
  font-size: 18px ! important; /* 可以, 但不推荐 */
  background-color: red !important; /* 可以, 推荐 */
}

影响级联规则

在级联规则中, 有三种常见的样式表, 他们的优先级依次 降低

  • author stylesheets: 最常见的样式表, 由 web 开发人员编写
  • user stylesheets: 大多数浏览器中, 网站的用户可以使用自定义的 user 样式表覆盖网站的样式. 根据浏览器的不同, user 样式表可以直接配置或者通过浏览器扩展添加.
  • user-agent stylesheets: 浏览器默认样式表.

一旦应用了 !important, 优先级就完全反过来. user-agent 所有 !important 样式表优先级大过 user 所有 !important 样式表优先级; 而 user 所有 !important 样式表优先级又大过 author 所有 !important 样式表优先级.

举个例子, 我们可以使用广告拦截器插件拦截页面某个元素. 本来 author 样式表的优先级高于 user 样式表, 但是因为 user 样式表中的 CSS 声明使用了 !important, 所以它的优先级就反过来高过 author 样式表中 !importantCSS 声明.

在这里插入图片描述

因此即便我们在 author 样式表中多加 display: block !important; 仍然无济于事, 元素 display 的计算属性还是 none. 这也就是使用广告拦截器插件拦截页面元素时, 网站开发者是没有能力覆盖插件的 user stylesheets 的原因.

在这里插入图片描述

反转 important 样式表优先级满足了用户的某些特殊要求, 比如要改变浏览器字体大小, 从而覆盖网页开发者编写的样式表. 同样的, user-agent 样式表中 important 声明的优先级更高也会阻止某些恶意插件破环页面功能等.

animationtransition 的关系

首先要注意的是, 在 @keyframes 中的声明不能使用 !important

在这里插入图片描述

所有 important 声明都比 animation 中声明的优先级高. 下面的例子中对 width 设置了 !important, 但是在动画中呢, 需要 width0100px 变化

.box2 {
  width: 100px !important;
  height: 100px;
  background-color: salmon;
  animation: moving linear 2s infinite;
}
@keyframes moving {
  from {
    width: 0;
    height: 0;
  }
  to {
    width: 200px;
    height: 100px;
  }
}

这条规则在 Chrome 109 版本和 Firefox 上的表现符合预期, 即元素的宽度始终为 100px 而不会动态变化, 但是在 Safari 15.6 上就不是啦. 至于为什么 Safari 浏览器表现不同于其他浏览器, 俺也不知道🤷‍♀️, 在开发时需要注意避免.

在这里插入图片描述

transition 优先级高于 important 声明. 当 CSS 属性从一个值变向另一个值时, 这个属性将不会匹配特定的 important 声明.

/* 第一种 */
.box3 {
  background-color: lightblue;
  transition: background-color 1s linear;
}
.box3:hover {
  background-color: red !important;
}

/* 第二种 */
.box3 {
  background-color: lightblue !important;
  transition: background-color 1s linear;
}
.box3:hover {
  background-color: red;
}

从下图中可以看到, 如果 important 添加在在过渡后的声明, 那么过渡正常; 反之添加在过渡前的声明, 则没有过渡.

在这里插入图片描述

如果过渡前后都有 important 呢? 答案是过渡正常发生.
在这里插入图片描述

上述三种情况在 Chrome, FirefoxSafari 表现相同.

级联层(cascade layer)

样式表有三种来源(不止三种, 这里只讨论三种), 即 user-agent stylesheets 浏览器默认样式, user stylesheets 通过浏览器配置或浏览器插件添加和 author stylesheets 网页开发人员编写.

对于在级联层外的一般(normal)声明优先级高于在级联层内的一般声明; 如果一般声明在不同级联层中, 那么在最后声明的级联层中的一般声明的优先级最高. 具体规则需要查看 @layer.

看个简单的例子
在这里插入图片描述

如果使用了 !important, 那么优先级就反转了. 先声明的级联层中的 important 声明优先级高于后声明的级联层中的 important 声明, 同时, 所有级联层中的 important 声明优先级高于级联层外的 important 优先级

在这里插入图片描述

内联样式

内联样式就是使用 style attribute 的声明. 内联样式也可以是一般(normal)声明或 important 声明. 内联一般声明的优先级高于所有其他一般声明, 不论其来源. 而内联 important 声明的优先级高于其他所有 important 声明, 不论级联层, 但是 user-agent 样式表的 important 声明, user 样式表的 important 声明和 transitions 高过内联 important 声明.

这里只关注内联 important 声明, 首先第一条, 内联 important 声明的优先级高于其他所有 important 声明, 即便 important 声明在级联层中, 可对照上部分.

在这里插入图片描述

验证第二部分, 内联 important 声明优先级低于 user-agent 样式表的 important 声明
声明和 user 样式表的 important 声明声明. 首先创建一个 button 元素, 然后用浏览器插件屏蔽它, 再增加内联 important 声明
声明, 发现元素仍然被屏蔽.

在这里插入图片描述

第三部分, 就是 transitions 的优先级更高我看浏览器的实际表现与规范中所写不同, 俺也不知道为啥…

在这里插入图片描述

!important 与权重

关于优先级与权重的说法, 我个人认为是不同来源的 CSS 样式表是「优先级」,同一来源的 CSS 规则之间是「权重」.

!important 并不影响 CSS 规则的权重, 但是却有关系. 如果两条 CSS 规则的权重不同, 那么使用 !important 的样式胜出, 与权重无关

<div class="box7" id="box7">Where are you from?</div>
#box7.box7 {
  color: red;      
}
.box7 {
  color: green !important;
}

在这里插入图片描述

如果两个 CSS 规则都是 important 规则, 那么权重高的胜出.

!important 与简写属性

在简写属性中使用 !important 会使简写属性包括的所有属性都变成 !important.

p.smile {
  border-top: 1px solid black;
}
.smile {
  border: 5px solid red !important;
}

虽然 .smile 的权重低于 p.smile, 但是 border 中的 !important 使得 border-top-width 也变成了 important, 所以胜出.

在这里插入图片描述

!important 与自定义变量

:root {
  --custom-bg-color: pink !important;
  --custom-bg-color: skyblue;
}

如果将 !important 添加到 CSS 变量声明中, 只有赋值时 !important 才起作用. 也就是将 pink 复制给变量 --custom-bg-color 时起了作用, 因为如果没有 !important, --custom-bg-color 的值应该是 skyblue.

赋值之后 !important 就从自定义属性上「脱落」了, 使用 var() 函数时并不会传递 !important.

.box8 {
  background-color: var(--custom-bg-color);
  background-color: red;
}

从下图就可以看出, .box8 的背景色是 red, 因为关于背景色的两条 CSS 声明都是一般声明.

在这里插入图片描述

!important 最佳实践

避免使用 !important 覆盖权重. 如果就是想创建 important 声明, 应该在代码中增加注释来解释这样做的原因并且告诉其他开发者不要覆盖 important.

即便要覆盖不在你控制下的高权重的样式, 比如使用 id 选择器的第三方库的样式, 你也不需要使用 !important. 可以考虑在第一个级联层中引入第三方样式文件. 只要第三方样式中不包含 !important, 你自己的样式就会覆盖第三方的样式.

如果真的需要覆盖外部样式表中的 important 样式, 仍然考虑创建一个级联层并在级联层中包含用来覆盖的 CSS 规则, 并将该级联层声明为第一个级联层. 我们来解释一下这个应该怎么做

首先在 index.html 中创建 .box9 元素, 并通过 link 标签引入 index1.css.

<link rel="stylesheet" href="index1.css">
<div class="box9"></div>

index1.css 中编写 .box9 的样式, 并引入 index2.css 作为模拟的外部样式

@layer basement;
@import "./index2.css" layer(basement);

.box9 {
  width: 100px;
  height: 100px;
  background-color: green;
}

下面是 index2.css 的代码

.box9 {
  background-color: blueviolet !important;
}

可以看到此时页面中 .box9 的背景色是紫色, 这是因为如果级联层中的 CSS 声明有 !important 标志, 那么其优先级就会高过外部没有在级联层中的 CSS 声明.

在这里插入图片描述

为了覆盖外部的 important, 我们也必须列用下面的特性: 即先声明的级联层中的 important 优先级高过后声明的级联层中的 important. 于是修改 index1.css.

@layer haha, basement;
@import url(index2.css) layer(basement);

@layer haha {
  .box9 {
    background-color: green !important;
  }
}

.box9 {
  width: 100px;
  height: 100px;
  background-color: green;
}

📖我们先创建了两个没有任何规则的级联层, 然后分别引入外部样式资源, 并在 haha 这个级联层中追加用来覆盖的 CSS. 这里有一个点值得注意 @layer haha, basement;haha 是首先声明的, basement 是其次声明的.

在这里插入图片描述

📖不该加分号的地方不要乱加, 别问我怎么知道的.

谢谢你看到这里😊

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

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

相关文章

微信小程序如何获取用户信息

自我介绍我是IT果果日记&#xff0c;微信公众号请搜索 IT果果日记一个普通的技术宅&#xff0c;定期分享技术文章&#xff0c;欢迎点赞、关注和转发&#xff0c;请多关照。微信小程序用户基本信息有哪些&#xff1f;除了基本信息&#xff0c;微信还会提供openId和unionId&#…

微服务项目简介

项目简介 项目模式 电商模式&#xff1a;市面上有5种常见的电商模式&#xff0c;B2B、B2C、 C2B、 C2C、O2O; 1、B2B模式 B2B (Business to Business)&#xff0c;是指 商家与商家建立的商业关系。如:阿里巴巴 2、B2C 模式 B2C (Business to Consumer), 就是我们经常看到的供…

6个月软件测试培训出来后的感悟 —— 写给正在迷茫是否要转行或去学软件测试的学弟们

本人刚从某培训机构学习结束&#xff0c;现在已经上班一个月了。这篇文章我不会说太多的知识点&#xff0c;或噱人去培训机构学习的话语&#xff0c;仅作为一个普通打工者的身份&#xff0c;来写给那些对于软件测试未来发展、薪资待遇等不清楚的正在为家庭&#xff0c;解决信用…

2023年中国数字化活动行业专题报告

易观&#xff1a;2023年2月&#xff0c;易观发布《2023年中国数字化活动行业专题报告》。报告主要分析了中国数字化活动市场发展背景与现状&#xff0c;数字化活动厂商的主要商业模式及其运作模式&#xff0c;典型案例&#xff0c;未来发展趋势洞察等。同时&#xff0c;易观分析…

网上流量卡可靠吗,网上的这些大流量卡你知道是怎么来的吗?

网上怎么这么多五花八门的流量卡&#xff0c;这些大流量卡是怎么来的你都知道吗&#xff1f;所谓的大流量卡&#xff0c;是因为每个省份为了拉新用户所自行包装的产品&#xff0c;一般是在在基础套餐上增加了一些流量包和充值送话费活动&#xff0c;然后得出来一个产品套餐&…

【动态规划】01背包问题(滚动数组 + 手画图解)

01背包除了可以用形象的二维动态数组表示外&#xff0c;还可以使用空间复杂度更低的一维滚动数组。 目录 文章目录 前言 一、滚动数组的基本理解 二、确定dp及其下标含义 三、确定递推公式 四、确定初始化 五、确定遍历顺序 1.用物品&#xff08;正序&#xff09;遍历背…

【刷题篇】链表(上)

前言&#x1f308;前段时间我们学习了单向链表和双向链表&#xff0c;本期将带来3道与链表相关的OJ题来巩固对链表的理解。话不多说&#xff0c;让我们进入今天的题目吧&#xff01;&#x1f680;本期的题目有&#xff1a;反转单链表、链表的中间结点、合并两个有序链表反转单链…

XCP实战系列介绍09-基于Vehicle Spy进行XCP测量步骤详解

本文框架 1.概述2. 基于SPY进行测量步骤2.1 建立ECU和vspy3通信2.2 DAQ数据设置2.3 测量变量的记录2.3.1 需要记录变量的选择2.3.2 Log保存3. 在MEP中观测变量3.1 添加观测变量3.2 实时更新变量的值1.概述 在介绍了ASAP2 Editor进行A2l文件的生成,及如何使用Vehicle Spy进行X…

点云深度学习系列博客(五): Point Transformer方法概述

在上一篇博客《注意力机制原理概述》中&#xff0c;我们介绍了注意力机制的基本原理以及一些技术细节。基于注意力机制的深度学习模型在起初设计时&#xff0c;针对的是NLP问题。包括词元分析&#xff0c;翻译等语言处理任务&#xff0c;注意力机制能够训练超大规模数据&#x…

活动星投票午间修身自习室制作在线投票投票制作网页

“午间修身自习室”网络评选投票_免费小程序投票推广_小程序投票平台好处手机互联网给所有人都带来不同程度的便利&#xff0c;而微信已经成为国民的系统级别的应用。现在很多人都会在微信群或朋友圈里转发投票&#xff0c;对于运营及推广来说找一个合适的投票小程序能够提高工…

SpringBoot整合(三)SpringBoot发送邮件

使用SpringBoot发送邮件 邮件发送其实是一个非常常见的需求&#xff0c;用户注册&#xff0c;找回密码等地方&#xff0c;都会用到&#xff0c;Spring Boot 中对于邮件发送&#xff0c;提供了相关的自动化配置类&#xff0c;使得邮件发送变得非常容易。 1、前置工作 目前国内…

[SSD固态硬盘技术 9] FTL详解

了解硬件特性有助于我们针对特性进行进一步的探索与优化。为了使闪存成为存储数据的友好介质&#xff0c;我们需要一种机制&#xff1a;将更新的信息写入新的空页&#xff0c;然后将 所有后续读取请求转移到其新地址确保新编程的页面均匀分布在所有可用闪存中&#xff0c;以便均…

【Python入门第五天】Python 变量

创建变量 变量是存放数据值的容器。 与其他编程语言不同&#xff0c;Python 没有声明变量的命令。 首次为其赋值时&#xff0c;才会创建变量。 实例 x 10 y "Bill" print(x) print(y)运行实例 变量不需要使用任何特定类型声明&#xff0c;甚至可以在设置后更改…

Jupyter 使用Anaconda 虚拟环境内核

Anaconda 虚拟环境中使用Jupyter Notebook 安装好Anaconda之后&#xff0c;进入Anaconda Prompt&#xff0c;创建虚拟环境&#xff0c;env_name是创建的环境的名字。 conda creat -n env_name python3.9等虚拟环境搭建好之后&#xff0c;激活环境。 conda activate env_name…

网络流与图(一)

线性规划问题是运筹学最基本的问题&#xff0c;我们已经学过不少的解决方法&#xff0c;今天继续学习针对线性规划问题的另一种高效算法——网络流问题&#xff08;network flow problem&#xff09;1网络流模型为了更好介绍该算法来龙去脉&#xff0c;与以往一样&#xff0c;从…

MongoDB 删除文档

MongoDB 删除文档 MongoDB remove() 、deleteMany()、deleteOne()函数是用来移除集合中的数据。 remove()删除文档 remove() 方法的基本语法格式如下所示&#xff1a; db.collection.remove(<query>,<justOne> ) 如果你的 MongoDB 是 2.6 版本以后的&#xff0c…

filter及backdrop-filter属性详解

filter属性详解 filter 属性定义了元素(通常是<img>)的可视效果(例如&#xff1a;模糊与饱和度)。 filter: none | blur() | brightness() | contrast() | drop-shadow() | grayscale() | hue-rotate() | invert() | opacity() | saturate() | sepia() | url();下面运用…

聚观早报 |字节开展类ChatGPT研究;特斯拉前AI负责人将加入OpenAI

今日要闻&#xff1a;字节开展类ChatGPT研究&#xff1b;丰田汽车第三财季净利润同比下降8.1% 特斯拉前AI负责人将加入OpenAI&#xff1b;快手&#xff1a;正在开展大规模语言模型研究&#xff1b;劳斯莱斯CEO称客户希望更多电动汽车 字节开展类ChatGPT研究 北京时间 2 月 9 日…

零代码做分析报表的bi软件才是好软件

有些数据分析软件对IT的依赖比较重&#xff0c;在制作报表的过程中需要用到SQL&#xff0c;这就导致了IT人员懂技术不懂业务&#xff0c;业务人员懂业务不懂技术&#xff0c;数据分析做来做去总是差点什么的局面。要是遇到了IT部门相对较弱的情况&#xff0c;还会加重IT负担&am…

字符串函数能有什么坏心思?

&#x1f680;write in front&#x1f680; &#x1f4dd;个人主页&#xff1a;认真写博客的夏目浅石. &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f4e3;系列专栏&#xff1a;夏目的C语言宝藏 &#x1f4ac;总结&#xff1a;希望你看完之…