Less:如何从地图中获取整个规则集

Less: how to grab an entire ruleset from within a map

我有一个如下所示的嵌套规则集(映射)。

@typography: {
    @h1: {
        font: roboto;
        font-weight: 300;
        font-size: 9.6rem;
        line-height: 9.6rem;
        text-transform:none;
    }
}

我知道如何检索和输出单个键,例如 [font],但是有什么方法可以返回和输出整个内部规则集吗?

.myclass {
    font: roboto;
    font-weight: 300;
    font-size: 9.6rem;
    line-height: 9.6rem;
    text-transform:none;
}

"Can't work this way currently (v3.9)".

恐怕它不会像现在这样工作(特别是地图本身)。 直觉上是这样的:

#usage {
    @typography[@h1]();
}

但是目前这个功能(级联()[]运算符)还没有实现。

像 "assign a ruleset of interest to a temporary variable and then 'call' it" 这样的 first-guess 解决方法也失败了:

#usage {
    @temp: @typography[@h1];
    @temp(); // error: not callable value
}

(这个居然要算作一个bug——我created一个dedicated ticket)。

这一切都将我们带到下一节:


"Consider using mixin-based maps".

请注意,虽然 "variable-based maps"(又名 DR)现在似乎是一个更 wide-spread 的模式,但 Less 中有 five different methods to define a map(以及无限数量的这些方法排列来定义N-dimensional(又名 "nested")地图)。

每种方法都有其优点和缺点,目前尚不清楚选择哪种方法作为 "go-to" 方法(在较长的 运行 中,倾向于将它们尽可能统一但到目前为止还远非如此)。

现在看看您试图表示的结构 w/o 坚持 "variable -> @variable" 刻板印象。它看起来不像常规的 CSS 规则集:

.typography {
    .h1 {
        font:         roboto;
        font-weight:     300;
        font-size:    9.6rem;
        line-height:  9.6rem;
        text-transform: none;
    }
}

?

这样您就已经有了一个 "mixin-based map",您可以像使用 "variable-based map" 一样使用它。 (实际上 "Maps" 的当前 documentation 也建议两种方法 w/o 强制执行其中一种方法作为 "the primary")。
您需要对该 "CSS" 结构进行的唯一修改是使其内部或外部(或两者)规则集成为参数混合(通过添加 ()),这样规则就不会出现在默认情况下已编译 CSS。

例如像这样:

.typography {
    .h1() {
...

或者像这样:

.typography() {
    .h1 {
...

(另外,如果您更喜欢这些标识符,您可以使用 # 而不是 .)。

现在回到你的use-case(解决方案):

.typography {
    .h1() {
        font:         roboto;
        font-weight:     300;
        font-size:    9.6rem;
        line-height:  9.6rem;
        text-transform: none;
    }
}

#usage-1 {
    // "expand" the set of rules:
    .typography.h1(); // OK
}

#usage-2 {
    // use individual value from the map:
    r: .typography.h1[font]; // OK
}

#usage-3 {
    // iterate through:
    each(.typography.h1(), <...>); // OK
}

// etc.

mixins 最初的发明目的是扩展一组规则,这不足为奇。

要记住 "variable-based" 和 "mixin-based" 地图之间唯一的根本区别(除了当前 limitations/issues 如何使用它们之外)是 "variables (and properties) override""rulesets (and thus mixins) cascade"。这可能会影响一些特定的细节,当你需要你的 CSS 数据被 "external code" customized/modified 时(例如 "theming/subtheming" 等) - 但这是另一个大故事所以我不会在这里深入探讨,但请参阅下一节以获取一些提示。


"Mixins and variables interop".

关于 mixins 的另一重要事项(在 use-case 的上下文中)。

如果我们将变量视为一种抽象的编程事物,即 "an identifier (symbolic name) associated with a value",我们很快就会看到 mixin 就是:a变量

A "mixin"(它的名字)实际上只是一个引用值的标识符,即 -> variable.

它只是标识符字符(前面的 #.)加上对它可以容纳的值类型的限制,这使得它被不同的标题引用,即"mixin" 而不是 "variable"(如 "Less @variable")。

换句话说,当涉及到"I have some data and I need something (i.e. "一个变量")到hold/represent它"时,重要的是不要自动陷入" a 变量(一般意义上)-> @variable" trap.

所以回到 Q,另一个要记住的技巧是知道 mixin 和变量值(特别是如果它是 "ruleset" 值)可以(几乎)自由 assigned/reassigned 到彼此。 IE。基本上,您可以创建一个变量来引用 mixin-based 映射并创建一个 mixin 来引用 variable-based 映射。 这对于克服两种方法的当前 issues/limitations(主要是在使用中)可能很有价值(或者如果您只是更喜欢 @.# "code-look"使用地图的地方)。

这里有一些提示:

// ................
// "Universal" map:

.typography {
    .h1() {
        font:         roboto;
        font-weight:     300;
        font-size:    9.6rem;
        line-height:  9.6rem;
        text-transform: none;
    }


    @h1:  {.typography.h1}; // assign mixin to variable
    .h2() {@h1()}           // assign variable to mixin
    .h3() {.typography.h1}  // assign mixin to mixin
    @h2:  @h1;              // assign variable to variable
}

@typography:  {.typography}; // assign mixin to variable
.graphytypo   {.typography}  // assign mixin to mixin
// etc.

// ................
// Usage:

#usage-1 {
    // use individual values from the map (all roboto):
    1: .typography.h1[font];
    2: .typography[@h1][font];
    3: .typography.h2[font];
    4: .typography.h3[font];
    5: .typography[@h2][font];

    6: @typography[@h1][font]; // <- like your original map

    7: .graphytypo.h3[font];

    // etc.
}

#usage-2 {
    // expand a set of .h1 rules (all the same):
    .typography.h1();
    .typography.h2();
    .graphytypo.h3();
    // etc.
}