在 CSS 中嵌套 @media 规则

Posted

技术标签:

【中文标题】在 CSS 中嵌套 @media 规则【英文标题】:Nesting @media rules in CSS 【发布时间】:2012-07-29 14:26:11 【问题描述】:

不同浏览器的支持似乎不同..

查看link

Firefox:黑底白字。

Opera、Chrome、IE9:蓝底黑字。

哪个是正确的,我该如何使其保持一致?

代码

@media screen and (min-width: 480px) 

    body
        background-color:#6aa6cc;
        color:#000;    
    

    @media screen and (min-width: 768px) 

        body
            background-color:#000;
            color:#fff;    
        
    

有趣的是,在条件@import 中嵌套媒体查询似乎确实有效。

例如:

索引.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>Media test</title>
    <link rel="stylesheet" type="text/css" href="importer.css" />
</head>
<body>
    <h1>Why is this not consistent.</h1>
</body>
</html>

importer.css

@import url(media.css) screen and (min-width: 480px);

媒体.css

body 
    background-color: #6aa6cc;
    color: #000;


@media screen and (min-width:768px) 
    body 
        background-color: #000;
        color: #fff;
    

【问题讨论】:

【参考方案1】:

对于那些只想回答“哪些浏览器支持@media 规则的嵌套?”的答案,简短的回答是所有现代浏览器,包括 Firefox、Safari、Chrome(及其衍生产品)和 Microsoft Edge,现在支持@media at-rules 的嵌套,如CSS Conditional 3 中所述。问题中带有嵌套@media at 规则的代码现在应该可以在任何地方正常工作,除了 Internet Explorer(no longer being updated with new features,这意味着任何版本的 IE 都不会支持此功能)。

CSS2.1 中不存在此功能,因为当时只有媒体类型存在,您可以简单地用逗号分组,这就解释了为什么在第一次提出这个问题时对此的支持非常差。

以下是对原始问题的分析,同时考虑到这些历史局限性。


有一些术语混乱需要澄清,以便我们了解到底发生了什么。

您拥有的代码指的是@media 规则,而不是媒体查询——媒体查询本身是@media 标记之后的组件,而规则是由@media 组成的整个代码块、媒体查询以及嵌套在其花括号集中的规则。

当涉及到在 CSS 中使用媒体查询时,这可能会引起许多人的困惑,以及在您的特定情况下,即使 @import 伴随着另一个媒体查询,导入样式表中的 @media 规则也能正常工作。请注意,@media@import 规则中都可能发生媒体查询。它们是相同的东西,但它们被用来以不同的方式限制性地应用样式规则。

现在,这里的实际问题是嵌套的 @media 规则是 not valid in CSS2.1,因为您不能在 @media 规则中嵌套 any at-rules。然而,CSS3 中的情况似乎完全不同。即@media规则可以嵌套的条件规则模块states very clearly,甚至提供了一个例子:

例如,使用这组嵌套规则:

@media print  /* rule (1) */
  /* hide navigation controls when printing */
  #navigation  display: none 
  @media (max-width: 12cm)  /* rule (2) */
    /* keep notes in flow when printing to narrow pages */
    .note  float: none 
  

标记(1)规则的条件对于打印媒体为真,当显示区域(对于打印媒体为页面框)的宽度小于时,标记(2)规则的条件为真或等于 12 厘米。因此,规则“#navigation display: none ”适用于此样式表应用于打印媒体时,规则“.note float: none ”仅适用于样式表应用于打印媒体和宽度页框的长度小于等于 12 厘米。

此外,Firefox 似乎正在遵循此规范并相应地处理规则,而其他浏览器仍在以 CSS2.1 方式处理它。

Syntax module 中的语法尚未更新以反映这一点;它仍然不允许在 @media 规则中嵌套 at 规则,就像 CSS2.1 一样。无论如何,该规范都将被重写,所以我想这并不重要。

基本上,CSS3 允许它(等待重写语法模块),但 CSS2.1 不允许(因为它既不定义媒体查询也不允许嵌套 @media 规则块)。虽然至少有一个浏览器已经开始支持新规范,但我不会说其他浏览器有缺陷。相反,我会说它们只是还没有赶上,因为它们确实符合更旧、更稳定的规范。

最后,@import 工作的原因是@import 能够在媒体查询的帮助下有条件地工作。但是,这与您导入的样式表中的 @media 规则无关。这实际上是两个不同的东西,所有浏览器都这样处理。

要使您的代码在浏览器中一致地工作,您可以使用 @import 语句,或者,由于您的两个规则都使用 min-width,只需删除您的 @media 规则的嵌套:

@media screen and (min-width: 480px) 
    body 
        background-color: #6aa6cc;
        color: #000;
    


@media screen and (min-width: 768px) 
    body 
        background-color: #000;
        color: #fff;
    

【讨论】:

谢谢。有趣的东西。我添加了@import 示例只是为了表明它有效。我总是很惊讶这种东西如何被吹捧为浏览器支持但行为却截然不同。 @James South:确实如此。我还为您的 @import 示例添加了一些解释。重读规范后,我觉得我需要为你复习一遍。 很好,但是 CSS cmets 必须使用 /* ... */ 而不是 // ; // 在您提供的一些示例 CSS 中用于 cmets。 @Albert Wiersch:我自己没有提供 CSS,那真的是 what it originally looked like。你会认为所有事情的规范都会正确。但至少在将近十年之后,他们现在修复了它。

以上是关于在 CSS 中嵌套 @media 规则的主要内容,如果未能解决你的问题,请参考以下文章

CSS 不使用嵌套的 className 规则

如何在`JSS`中实现`CSS`嵌套规则?

Sass @media指令

Sass 嵌套规则

为啥嵌套 CSS 选择器是自下而上应用的? [复制]

在 VueJS 模块中嵌套 SCSS 规则