CSS 预处理器,可以在 @media 查询中定义变量

Posted

技术标签:

【中文标题】CSS 预处理器,可以在 @media 查询中定义变量【英文标题】:CSS pre-processor with a possibility to define variables in a @media query 【发布时间】: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?在这个最简单的示例中不是问题,但在实际项目中,这可以节省大量时间和复制/粘贴。

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

    <html> 上的字体大小设置为基本字体大小 myVar LESS 变量在 rem 而不是 px 中定义为基本字体大小的派生词 使用@media 查询来调整不同媒体的基本字体大小。 可选 将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 变量和类的名称无关紧要。我只能根据您提供的内容来判断,我的观点仍然成立:您是造成维护噩梦的人。如果你把事情简单化太多,你最终会得到过于简单的解决方案。 【参考方案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 行不同的参数。

以上是关于CSS 预处理器,可以在 @media 查询中定义变量的主要内容,如果未能解决你的问题,请参考以下文章

@media 查询:在 W3C CSS 验证服务中出现错误

IE 的 CSS 选择器限制中如何计算媒体查询?

css3的@media

CSS媒体查询和选择器[重复]

实践 HTML5 的 CSS3 Media Queries

基于 CSS3 Media Queries 的 HTML5 应用