为什么新的自定义 class 优先于先前加载文件中不同名称的 class?

Why does a new custom class take precedence over a differently named class from a previously loaded file?

我正在使用从 CDN 加载的 Bootstrap 4。我添加了一个新的 class 定义为:

.pt-10 { padding-top: 10rem !important; }

css 文件按以下顺序加载到 html 文档中:

<link href="bootstrap cdn css...">
<link href="my file">

在下面的 html 代码中,我定义了这样一个元素:

<div class="pt-10 pt-lg-0">

我的愿望是这应该以相同的方式工作 bootstrap 间距 classes 工作,当我在 classes 下面时我得到 pt-10 填充lg 比例,和 pt-lg-0 在 lg 和更高时填充。

结果:pt-10 始终优先于 pt-lg-0 class - 与屏幕尺寸无关。

但是如果我复制 bootstrap 的 pt-lg-0 class 的确切代码并将其粘贴到我的自定义文件中(在 pt-10 定义之前),它就可以正常工作如我所愿。

我不明白为什么这对一种方式有效而对另一种方式无效?似乎它可能与 !important 有关,但我真的不明白为什么。有人可以阐明这一点吗?

规则 #1:CSS 文件从上到下处理

这就是它被称为“层叠样式 Sheet”的原因。从上到下层叠是它的自然顺序。由于您在自定义文件后包含 bootstrap 文件,因此您的自定义样式将获胜。

例如:

// Bootstrap declaration
.pt-0 {
    padding-top: 0 !important;
}

// Your custom styles
.pt-10 {
    padding-top: 10rem !important;
}

他们都申请了属性padding-top,他们都申请了!important。所以后面加载的样式会赢!

只是想澄清一下:以下工作只是因为同样的原因:.pt-lg-0 在文件中的定义晚于 .pt-5 的定义。

<div class="pt-5 pt-lg-0">...</div>

.pt-5 在 bootstrap.css 文件的第 8185 行定义,.pt-lg-0 在第 9157 行定义。


规则 #2:具有更高特异性的选择器获胜

如果有多个选择器应用于同一个元素属性,则优先级高的选择器获胜。

例如,如果您的布局如下所示:

<div id="test-container" class="container">
    <div class="pt-10 pt-lg-0">
        ...
    </div>
</div>

你有这样的风格:


.container#test-container .pt-10 {
    padding-top: 0rem !important;
}

.container .pt-10 {
    padding-top: 5rem !important;
}

.pt-10 {
    padding-top: 10rem !important;
}

那么无论样式加载顺序如何,padding top 都为0rem,因为ID选择器具有更高的特异性。


规则 #3:媒体查询没有特异性!

您认为顶部填充会重置为 0,因为您可能认为 bootstrap 在大断点处有 padding-top: 0rem !imporant?它不会。事实上,媒体查询中的规则并不优先于同一样式表中的其他样式规则。

因此,由于 规则 #1.[=30,您的 .pt-10 始终优先于 .pt-lg-0 class =]

解决方案

要获得您想要的,只需从您的自定义 class:

中删除 !important
.pt-10 {
    padding-top: 10rem;
}

这会起作用,因为:

  1. 您的样式在 bootstrap 之后加载,并且没有为同一元素定义 padding-top,因此您的 10rem 填充顶部将适用!
  2. 在大断点处,因为 bootstrap 中的 .pt-lg-0 具有 !important,它具有更高的优先级,因此将覆盖您的 10rem 填充顶部风格!如果你把 !important 放在你的 10rem padding top 样式中,那么它们将具有相同的特异性。因此,谁定义得晚谁就赢。

演示: https://jsfiddle.net/davidliang2008/9sqn4xch/16/