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

时间:2019-06-10 19:04:33

标签: html css bootstrap-4 css-selectors operator-precedence

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

.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">

我的愿望是,这种方式应该与引导程序间距类的工作方式相同,当我在lg尺度以下的类上时,我会得到pt-10填充,而在lg或更高尺度上时,会得到pt-lg-0填充。

结果: pt-10始终优先于pt-lg-0类-与屏幕大小无关。

但是,如果我复制pt-lg-0类的引导程序的确切代码,然后将其粘贴到我的自定义文件中(在pt-10定义之前),它将完全按照我的要求工作。

我不明白为什么这会以一种方式而不是另一种方式起作用?似乎可能与!important有关,但我真的不明白为什么。有人可以阐明这一点吗?

1 个答案:

答案 0 :(得分:0)

规则1:从头到尾处理CSS文件

这就是为什么它被称为“层叠样式表”的原因。从上到下的层叠是其自然的顺序。由于您先添加 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在bootstrap.css文件的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;
}

然后,无论样式加载顺序如何,由于ID选择器的特异性较高,填充顶部将为0rem。


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

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

由于第1条规则,因此您的.pt-10始终优先于.pt-lg-0类。


解决方案

要获得所需的内容,只需从自定义类中删除!important

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

这将起作用,因为:

  1. 您的样式是在 bootstrap 之后加载的,并且没有为同一元素定义padding-top,因此您的10rem填充顶部将适用!
  2. 在较大的断点处,由于 bootstrap 中的.pt-lg-0具有!important,因此优先级更高,因此将覆盖您的10rem padding top样式!如果将!important设置为10rem填充顶部样式,则它们将具有相同的特异性。因此,以后定义的任何人都将获胜。

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