英文:
If media queries do not affect specificity, how come the style is being applied even when placed on top
问题
我期望颜色是红色。然而,实际上是蓝色,我对此没有解释。在Chrome上测试过。在其他浏览器中颜色是红色。
英文:
With this style
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
div {
@media (min-width: 0px) {
color: blue;
}
color: red;
}
<!-- language: lang-html -->
<div>
hello
</div>
<!-- end snippet -->
I expect the color to be red. However, it's actually blue and I have no explanation for this. Tested on Chrome. The color is red in other browsers.
答案1
得分: 1
以下是翻译好的内容:
这是因为嵌套的@rule
实际上展开为:
@rule {
& {
/* ... */
}
}
.foo {
display: grid;
@media (orientation: landscape) {
grid-auto-flow: column;
}
}
/* 等效于
.foo {
display: grid;
@media (orientation: landscape) {
& {
grid-auto-flow: column;
}
}
}
*/
如果我们将&
选择器添加到color: red
规则中,我们将得到相同的特异性:
div {
@media (min-width: 0px) {
color: blue;
}
& { color: red; }
}
请注意,您的代码目前在非Chromium浏览器中会产生红色输出,因为它们仍不支持CSS嵌套,所以它们只会将这里的@media
规则视为无效规则,并继续解析div
规则。如果要支持所有浏览器,您必须手动展开这些规则:
@media (min-width: 0px) {
div { color: blue; }
}
div {
color: red;
}
英文:
This is because the nested @rule
actually unwraps to
@rule {
& {
/* ... */
}
}
This is explained in this paragraph of the specs, which even contains an example pointing out this case:
> css
> .foo {
> display: grid;
>
> @media (orientation: landscape) {
> grid-auto-flow: column;
> }
> }
> /* equivalent to
> .foo {
> display: grid;
>
> @media (orientation: landscape) {
> & {
> grid-auto-flow: column;
> }
> }
> }
> */
>
And if we do add the &
selector to the color: red
rule, we get the same specificity:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
div {
@media (min-width: 0px) {
color: blue;
}
& { color: red; }
}
<!-- language: lang-html -->
<div>
hello
</div>
<!-- end snippet -->
And note that your code currently produces a red output in non Chromium browsers because they still don't support CSS nesting, so they just treat the @media
rule here as an invalid rule and go on to parse the div
one.
If you want to support all browsers, you have to manually unwrap these rules:
<!-- begin snippet: js hide: true console: true babel: false -->
<!-- language: lang-css -->
@media (min-width: 0px) {
div { color: blue; }
}
div {
color: red;
}
<!-- language: lang-html -->
<div>
hello<!-- will be red everywhere -->
</div>
<!-- end snippet -->
答案2
得分: 1
我将使用另一个示例来说明您的问题:
<!-- 开始代码片段: js 隐藏: false 控制台: true Babel: false -->
<!-- 语言: lang-css -->
div {
& {
color: blue;
}
color: red;
}
<!-- 语言: lang-html -->
<div>
hello
</div>
<!-- 结束代码片段 -->
我们混合了“嵌套规则”和“声明”,规范定义了这种行为,将“嵌套规则”移动到最后。因此,浏览器会将您的代码更改为以下形式:
<!-- 开始代码片段: js 隐藏: false 控制台: true Babel: false -->
<!-- 语言: lang-css -->
div {
color: red;
& {
color: blue;
}
}
<!-- 语言: lang-html -->
<div>
hello
</div>
<!-- 结束代码片段 -->
然后变成这样:
<!-- 开始代码片段: js 隐藏: false 控制台: true Babel: false -->
<!-- 语言: lang-css -->
div {
color: red;
}
div {
color: blue;
}
<!-- 语言: lang-html -->
<div>
hello
</div>
<!-- 结束代码片段 -->
所以,始终从“声明”开始,然后是“嵌套规则”。
英文:
I will use another example to illustrate your issue:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
div {
& {
color: blue;
}
color: red;
}
<!-- language: lang-html -->
<div>
hello
</div>
<!-- end snippet -->
We are mixing "nested rules" and "declarations" and the Specification defines such behavior by moving the "nested rules" at the end.
So the browser will change your code to this:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
div {
color: red;
& {
color: blue;
}
}
<!-- language: lang-html -->
<div>
hello
</div>
<!-- end snippet -->
And then to this:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
div {
color: red;
}
div {
color: blue;
}
<!-- language: lang-html -->
<div>
hello
</div>
<!-- end snippet -->
So always start with the "declarations" then the "nested rules"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论