了解特异性:在不使用 !important 的情况下实现所需的选择器结果 [重复]

Posted

技术标签:

【中文标题】了解特异性:在不使用 !important 的情况下实现所需的选择器结果 [重复]【英文标题】:Understanding specificity: achieving desired selector outcomes without using !important [duplicate] 【发布时间】:2016-10-09 07:35:35 【问题描述】:

我正在尝试理解 CSS 中的特异性

我目前的理解是特异性与继承非常相似,但在某些方面更具体地定义。

Mozilla Specificity Definition:

特异性是浏览器决定哪些 CSS 属性值与元素最相关并因此将被应用的方法。特异性基于由不同种类的 CSS 选择器组成的匹配规则。

当前任务是:

重构 .active a.copyright 的 CSS 声明,以便可以删除 !important 规则。

CSS

.main li a 
  color: #7ab2c1;

.active a 
  color: #826c55 !important;

.primary p 
  font-size: 12px;

.copyright 
  font-size: 10px !important;

以及相关的HTML

<nav class="main">
  <ul class="group">
    <li class="active"><a href="#">Home</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</nav>

[...]

<footer class="primary">
      <p><a href="#">Sign up</a> for our newsletter, it's a racket!</p>
      <p class="copyright">Copyright &copy; Sven's Snowshoe Emporium. All Rights Reserved.</p>
</footer>

谁能指导我完成重构过程,帮助我掌握基本概念?

【问题讨论】:

一些一般指导:***.com/a/35657646/3597276 重构 CSS ,可以根据你的实际标记制作......也分享你的 html @DaniP 好的。只是看看并尝试minimal reproducible example它。例如。砍掉它而不会丢失任何东西。 您可能还想研究 CSS 特异性计算器,例如 specificity.keegan.st。它向您展示了如何计算任何规则的特异性。 或者这里更容易理解css-tricks.com/specifics-on-css-specificity 【参考方案1】:

一个类的特异性为 10。一个元素的特异性为 1。

因此,首先:

.main li a 选择器的特异性为 12。 .active a 选择器的特异性为 11

因为它们都针对相同的元素,并且前者具有更高的特异性,所以后者输掉了元素样式的战斗。

第二种情况:

.primary p 选择器的特异性为 11。 .copyright 选择器的特异性为 10。

再次,因为它们都针对相同的元素,并且前者具有更高的特异性,后者在设计元素的战斗中失败了。

!important annotation 胜过所有的特异性。因此,应用了这个,.active a.copyright 重新获取元素。

如果您想删除!important,这是正确的做法,因为这里没有必要,您可以改为提高选择器的特异性。

ID 的特异性为 100。这样可以快速将选择器的优先级提高。

这里有一些例子:

.main li a       color: #7ab2c1;   /* previous winner; specificity 12 */
.main .active a  color: #ff0000;   /* added class selector; specificity now 21 */
.primary p       font-size: 12px;  /* previous winner; specificity 11 */
#copyright       font-size: 8px; /* switched to ID selector; specificity now 100 */
<nav class="main">
  <ul class="group">
    <li class="active"><a href="#">Home</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</nav>
<footer class="primary">
  <p><a href="#">Sign up</a> for our newsletter, it's a racket!</p>
  <p id="copyright">Copyright &copy; Sven's Snowshoe Emporium.
                    All Rights Reserved.</p>
</footer>

参考资料:

How do I give a CSS class priority over an id? CSS Specificity CSS Specificity: Things You Should Know Relationship between !important and CSS specificity

【讨论】:

另一篇关于特异性值从何而来的好文章:sixrevisions.com/css/css-specificity 我最终以另一种方式完成了挑战(否则看起来像是在作弊),但你的答案最终是我提到最多的一个,所以这是我接受的那个。谢谢。 @PeterDavidCarter-Poulsen,不客气。很高兴我能帮助你。关于“作弊”,那就是使用!important。使用选择器来提高特异性是一种合适的方法。祝你好运!【参考方案2】:

您可以将.copyright 更改为很多东西,但以下两个之一对我来说似乎最合乎逻辑:

.primary .copyright

p.copyright

具体应该做什么,是看看你的选择器有多具体,并决定是否应该遵循该规则。

媒体查询内部的 CSS 比外部完全相同的 CSS 更具体 ID 比类更具体 html body section p.special.selected:hoverp 更具体 等

有一大堆规则可以让您的选择器在每个部分都“加分”。点数越多,越具体。经过大量的练习,你可以不假思索地写出凌驾于规则之上的 CSS。

【讨论】:

谢谢,我要看看 cmets 中链接的其他资源,花时间阅读这个答案,可能小睡一下,甚至适当的睡眠(现在已经很晚了英国),然后再回来看看我能解决什么问题,然后希望我能够接受答案。【参考方案3】:

在此示例中,您尝试使选择器设置您希望覆盖的属性不太具体。这样一来,您就不必再去覆盖它们了。

我们来看看

.main li a 
  color: #7ab2c1;

.active a 
  color: #826c55 !important;

.main li a 非常具体:它选择了类名中带有main 的元素内一个li 内的所有锚标记。你怎么能不那么具体?根据您的标记,

.main a 
  color: #7ab2c1;

不太具体,仍然适用,并且会被您的.active 选择器覆盖,因为它具有相同的特异性(一个类+一个元素)。 nav a 甚至普通的 a 也可以用作选择器,具体取决于您希望该规则应用多少(或多少)。

现在,让我们看看页脚。

.primary p 
  font-size: 12px;

.copyright 
  font-size: 10px !important;

我们如何才能使第一个选择器不那么具体?怎么改成

p 
  font-size: 12px;

您的.copyright 选择器更具体,并且会覆盖它(但是,所有p 元素在任何地方都会有一个默认的font-size 12px,这可能不是您想要的)。

我们可以将其限制在页脚:

.primary 
  font-size: 12px;

这会将font-size 属性限制为仅页脚元素,并允许您使用后续规则覆盖它。

一般来说,您会尝试基于specificity values 进行重构,以使您想要覆盖的内容具有可能的最小特异性值。您可以通过使用最通用的选择器来做到这一点,这些选择器会应用您想要的规则,而不会将这些规则应用到不应该有它们的元素

【讨论】:

谢谢,我要看看 cmets 中链接的其他资源,花时间阅读这个答案,可能小睡一下,甚至适当的睡眠(现在已经很晚了英国),然后再回来看看我能解决什么问题,然后希望我能够接受答案。 关于特异性的 CSS 技巧文章已在多个答案中多次发布,应该会让您走上正确的道路。【参考方案4】:

基本上使用html标签作为选择器会增加少量特异性,使用类会增加中等特异性,使用ID会增加大量特异性,使用!important胜过一切。

.main li a 选择器使用 1 个 class + 2 个 html 标签,而 .active a 只使用 1 个 class + 1 个 html 标签。前者比后者更具特异性,但使用 !important 会覆盖这一点并强制应用后者样式。

要消除对!important 的需求,您需要a) 减少.main li a 中的特异性量或b) 增加.active a 中的特异性量。我会推荐选项 a 并将选择器更改为 .main a。这与.active a 具有相同的特异性,但由于CSS 的级联性质,最后出现的样式将被应用,不需要!important

在第 2 个场景中的原理相同 - .primary p 有 1 个类 + 1 个 html 标签,而 .copyright 只有 1 个类。在这种情况下,我会选择选项 b 并将选择器更改为 .primary .copyright。 2 个类比 1 个类 + 1 个 html 标记更具特异性,并且无需!important 即可应用样式。

最终的 CSS:

.main a 
  color: #7ab2c1;

.active a 
  color: #826c55;

.primary p 
  font-size: 12px;

.primary .copyright 
  font-size: 10px;

【讨论】:

谢谢,我要看看 cmets 中链接的其他资源,花时间阅读这个答案,可能小睡一下,甚至适当的睡眠(现在已经很晚了英国),然后再回来看看我能解决什么问题,然后希望我能够接受答案。

以上是关于了解特异性:在不使用 !important 的情况下实现所需的选择器结果 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何使用私钥/公钥在不提供密码的情况下登录 ssh 服务器-imported-openssh-key

如何在不使用 import_url 的情况下将特定文件导入新创建的 Gitlab 项目?

我无法使用“!important”规则注入样式[重复]

Sass @import 使用前导下划线

如何在不需要 rxjs-compat 的情况下只导入 RxJS 6 中使用的运算符,如旧的 RxJS?

在不了解 TypeScript 的情况下使用 cordova-plugin-playlist