在Less mixin中导入动态路径

时间:2015-08-11 07:00:34

标签: import less media-queries

我正在重写我的Less css结构以提高可扩展性。我正在寻找一种架构,为每个模板的每个媒体查询加载模板。

最好,我想在mixin中加载它。当前的mixin看起来像这样(但不允许特定的组件加载) `

/**
 * Progressive enhancing overrides (mobile first)
 *
 * Mobile loads "mobile.less"
 * Wide mobile loads "mobile.less" and "widemobile.less"
 * Tablet loads "mobile.less", "widemobile.less" and "tablet.less"
 * etc.
 */
.progressive-enhancement() {
  // Mobile layout
  @media only screen {
    @import (less) "../template/mobile";
  }

  (...)
}

所以我正在寻找的是这样的(不工作):

.progressive-enhancement(@component: main) {
  // Mobile layout
  @media only screen {
    @import (less) "../template/@{component}/mobile";
  }

  (...)
}

然而,这不起作用,导致声称@component未定义的错误。

我认为问题是Less在调用混合之前尝试进行导入,而没有在该阶段定义@component。

有没有办法动态地使用@import和mixin提供的变量?

提前致谢。

2 个答案:

答案 0 :(得分:1)

是的,这是不可能的。并且,是的,这是因为由于懒惰评估原则,Less必须以某种“打字”顺序而不是“从上到下”的顺序(大致是导入 - > mixins - >变量等)来评估语言实体(有一些内部的解决方法可以处理某些特定的事情,除了这个例外,但这些例外永远不会是任何东西,只有kludge。)

至于您的具体用例,乍一看最简单的解决方法是使用导入而不是mixins,并让组件指定自己的名称:

// progressive-enhancement.less:

@media only screen {
    @import "@{component}/mobile";
}

// etc.

然后为每个组件提供“root”文件:

// ../template/button.less:
& {
    @component: button;
    @import (multiple) "progressive-enhancement.less";
}

// ../template/toolbar.less:
& {
    @component: toolbar;
    @import (multiple) "progressive-enhancement.less";
}

最后在您的主文件中,您只需导入它们:

// main.less:
@import "../template/button";
@import "../template/toolbar";

(显然文件名及其实际位置可根据您的喜好进行调整)。

答案 1 :(得分:0)

我回答了我自己的问题,所以我可以使用一些格式来显示我的解决方法。

我有这个目录结构:

less/
- components/
  - navbar/
    - mobile.less
    - tablet.less
  (...)
- config/
  - defaults.less
- lib/
  - grid.less
  - mediaqueries.less
  (...) 
- template/
  - base.less
  - mobile.less
  - widemobile.less
  - tablet.less
  (...)
- main.less

main.less文件导入所需的库(例如mediaqueries.less)。这些提供混合使用(例如,渐进增强())。 mediaqueries库有多个mixin来处理模板加载。请参阅docblock:

/**
 * Progressive enhancing overrides (mobile first)
 *
 * Mobile loads "mobile.less"
 * Wide mobile loads "mobile.less" and "widemobile.less"
 * Tablet loads "mobile.less", "widemobile.less" and "tablet.less"
 * etc.
 */

此外,main.less还包括模板/ base.less,用于常见样式,字体加载,自定义混合等。

由于mediaqueries库不可能以一种很好的方式处理组件。这个逻辑被移到了他们的文件中。例如。 mobile.less:

(...)
/**
 * Imports
 */
@import (less) "../components/navbar/mobile.less";
@import (less) "../components/postslist/mobile.less";
@import (less) "../components/footer/mobile.less";
(...)

每当我需要覆盖某个媒体查询的规则时,可以对其他文件进行额外的导入(遗憾的是没有自动加载)。例如。 tablet.less

(...)
/**
 * Imports
 */
@import (less) "../components/navbar/tablet.less";
@import (less) "../components/postslist/tablet.less";

请注意,页脚与移动设备保持不变。

这个解决方案可能比@ seven-phases-max提供的解决方案更冗长,但我认为它更清晰,因为变量不需要被滥用作为参数。