【问题标题】:CSS pre-processor with a possibility to define variables in a @media queryCSS 预处理器,可以在 @media 查询中定义变量
【发布时间】:2012-12-17 19:47:30
【问题描述】:

目前,我使用 LESS 作为我的主要 CSS 预处理器。我有(而且我相信很多人都有这种需要)在@media 查询中定义变量,例如:

@media screen and (max-width: 479px) {
    myVar: 10px;
}
@media screen and (min-width: 480px) and (max-width: 767px) {
    myVar: 20px;
}
@media screen and (min-width: 768px) {
    myVar: 30px;
}

.myElement {
    padding: @myVar;
}

由于编译性质,这在 LESS 中不起作用(@myVar 仅在每个特定 @media 的范围内定义,而不是全局定义)。即使我在媒体查询之前全局定义了@myVar,它也不会根据媒体查询进行更新,并且.myElement无论如何都会获得该初始值。

所以,问题是,是否有可能在任何其他 CSS 预处理器中实现这一点,或者我们注定要在每个媒体查询中覆盖 .myElement?在这个最简单的示例中不是问题,但在实际项目中,这可以节省大量时间和复制/粘贴。

编辑: 不是解决方案,而是我的特定项目的解决方法

  1. <html> 上的字体大小设置为基本字体大小
  2. myVar LESS 变量在 rem 而不是 px 中定义为基本字体大小的派生词
  3. 使用@media 查询来调整不同媒体的基本字体大小。
  4. 可选REM unit polyfill 用于尚不支持rem (http://caniuse.com/#search=rem) 的浏览器。这在 IE 8 及更低版本中不起作用,但不是因为缺乏对 rem - it doesn't support media queries 的支持。因此,无论如何,IE8 及以下版本都会获得全尺寸无媒体查询样式表。

代码sn-p:

@myVar: .77rem; // roughly 10px, 20px and 30px respectively

html { font-size: 13px }
@media screen and (min-width: 480px) and (max-width: 767px) {
    html { font-size: 26px }
}
@media screen and (min-width: 768px) {
    html { font-size: 39px }
}

.myElement {
    padding: @myVar;
}

这里是一个JSBin,其中包含更广泛的示例,它将不同字体大小的元素与不同的测量块混合在一起。

简单灵活,满足我的需求。希望对其他人有所帮助。

【问题讨论】:

  • 我认为这在任何 CSS 编译器中都是不可能的。编译器必须为您生成@media ... { .myElement { padding: ... } } 。尽管这很有可能,但这将无法控制您。为什么不直接在 @media ... { ... } 查询中包含 .myElement {...} 或使用在其中导入的 mixins(以减少重复)?
  • @try-catch-finally,重复的问题在于维护。如果我有相当多的媒体查询甚至更多元素,取决于媒体查询相关变量,这将是一场维护噩梦。
  • 如果这是您对媒体查询所做的事情的一个示例,那么您就是导致维护噩梦的人。根据浏览器的宽度,您的填充有不同的 px 值?请改用百分比。
  • @cimmanon,我很欣赏你的意见,但你认为我并没有真正使用 'myVar' 和 '。 myElement' 在真实的代码中,你呢?我认为这不是很聪明。如果我举一个真实的例子,这个问题将是不可读的。感谢您的宝贵时间。
  • @spliter 变量和类的名称无关紧要。我只能根据您提供的内容来判断,我的观点仍然成立:您是造成维护噩梦的人。如果你把事情简单化太多,你最终会得到过于简单的解决方案。

标签: css less media-queries sass


【解决方案1】:

让我更直接地回答这个问题:

“是否有可能在任何其他 CSS 预处理器中实现这一点,或者我们 注定要覆盖每个媒体查询中的.myElement?”

答案实际上存在于问题中。因为 LESS(和其他类似工具)是一个“预处理器”,所以@media 在编译时对它没有任何意义,因为它不会查看浏览器的媒体状态来进行预处理。 @media 状态仅在预处理之后 相关,此时任何@someVariable 都已被计算。这就是为什么您尝试做的事情行不通的原因。您的 @myVar 只能作为 CSS 样式表中的单个值输出,并且该输出发生在 @media 评估浏览器状态之前。

因此,它与媒体查询的“全局”或“本地”范围无关,而是 LESS 使用变量将代码编译为 CSS 的事实,而支付费用的是 CSS(而不是 LESS)关注@media查询信息。

有关使用 LESS 构建媒体查询的进一步讨论,以使它们都在一起而不是分散在整个代码中,请参阅this question

【讨论】:

  • 感谢@ScottS 的详细解释。我确实使用了问题中提到的解决方法,但无论如何您的回答都准确地回答了这个问题。因此我接受它。
  • @media 在编译时对它没有任何意义”:这不太正确,LESS 执行 bubbling for @media queries
  • @Flimm:关于“冒泡”是正确的,但我所说的“没有任何意义”的上下文并不是指 LESS 如何预处理 @media 在最终 css 中的位置,而是指以下内容关于“浏览器的媒体状态”的因果子句对 LESS 预处理毫无意义。 LESS 在编译时没有读取浏览器的媒体状态,因此 @media 本身没有不同的值,因此不能用于分配要在 LESS 编译期间使用的变量(如问题所示)。
  • 好的,但是LESS编译器不需要读取浏览器的状态,它是could be done like this
  • @Flimm:有很多方法可以设置变量(我相信有些人会发现你的链接很有用)。但问题具体是关于设置一个使用 outside 的变量 @media 块只需通过 @media 引用进行该变量的设置,这样就不必“覆盖 .myElement在每个媒体查询中”(根据 OP)。也就是说,他不希望在他的最终 css 中有一堆 @media.myElement 的重新定义。我的答案是解释 为什么 LESS 配置无法生成他想要的 css。
【解决方案2】:

您可以将其重构为将媒体查询放入变量中,然后在元素中使用它们。

例子:

@phone: ~"screen and (max-width: 479px)";
@tablet: ~"screen and (min-width: 480px) and (max-width: 767px)";
@desktop: ~"screen and (min-width: 768px)";

.myElement {
  @media @phone { padding: 10px; }
  @media @tablet { padding: 20px; }
  @media @desktop { padding: 30px; }
}

产生:

@media screen and (max-width: 479px) {
  .myElement {
    padding: 10px;
  }
}
@media screen and (min-width: 480px) and (max-width: 767px) {
  .myElement {
    padding: 20px;
  }
}
@media screen and (min-width: 768px) {
  .myElement {
    padding: 30px;
  }
}

整个使媒体查询成为嵌入变量中的未解析文字并不完全漂亮,但也有助于标准化媒体查询。

而且它有助于提高可读性,因为.myElement 的所有三个行为都包含在一个定义中,并且没有在其他地方更改(可能是完全不同的文件),这使得“调试”变得困难。

【讨论】:

  • OP 听起来他想为大量元素使用这种模式。这将引入 很多 的 CSS 膨胀:每次在某物上设置填充时 3 次媒体查询。
  • 谢谢西蒙娜。看起来很有趣。但不完全是我需要的。我真的需要根据媒体查询设置变量,而不是正在调整的类。我有很多不同的类取决于同一个变量,正如@cimmanon 指出的那样,它会非常容易导致 CSS 膨胀。
【解决方案3】:

怎么样:

@media screen and (max-width: 479px) {
    .myElement(10px);
}

@media screen and (min-width: 768px) {
    .myElement(30px);
}


.myElement(@myVar) {
    .myElement {
        padding: @myVar;
    }
}

【讨论】:

  • 谢谢巴拉兹。这确实有助于减少维护麻烦。但是,这仍然意味着根据变量将每个元素复制/粘贴到每个媒体查询中
  • ... 你也可以像 .variableRules(@var1, @var2...) {...} 这样只做一个 mixin,然后你只需要插入 1 行不同的参数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-05
  • 2011-07-09
  • 1970-01-01
  • 2012-10-24
  • 2015-07-27
  • 1970-01-01
  • 2010-11-15
相关资源
最近更新 更多