【问题标题】:How to pass multiple class names to a mixin in LESS如何将多个类名传递给LESS中的mixin
【发布时间】:2018-03-24 23:38:12
【问题描述】:

我正在创建一个显示帐户交易的视图,并且我想对交易类型/状态进行颜色编码。我还想展示一个解释颜色代码的图例。

我想要一个结构如下的最终结果:

HTML

<table id="transactions">
  <thead>
    <tr>
      <th colspan="2">
        Transactions
      </th>
    </tr>
  </thead>
  <tbody>
    <tr class="credit">
      <td>A credit</td>
      <td>$1.00</td>
    </tr>
    <tr class="debit paid">
      <td>A paid debit</td>
      <td>($2.00)</td>
    </tr>
    <tr class="debit unpaid">
      <td>An unpaid debit</td>
      <td>($3.00)</td>
    </tr>
  </tbody>
</table>
<hr/>
<table id="legend">
  <thead>
    <tr>
      <th colspan="3">
        Legend
      </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td class="credit">Credit</td>
      <td class="debit paid">Paid</td>
      <td class="debit unpaid">Unpaid</td>
    </tr>
  </tbody>
</table>

CSS

table#transactions > tbody > tr.credit {
  color: limegreen;
}

table#legend > tbody > tr > td.credit {
  color: limegreen;
}

table#transactions > tbody > tr.debit.paid {
  color: goldenrod;
}

table#legend > tbody > tr > td.debit.paid {
  color: goldenrod;
}

table#transactions > tbody > tr.debit.unpaid {
  color: crimson;
}

table#legend > tbody > tr > td.debit.unpaid {
  color: crimson;
}

(CodePen)

请注意,“借方”使用两个类名,以将它们与贷方区分开来。

显然那里有一些冗余,我试图将其重构为这个(无效的)LESS 代码:

.transaction-status(@class, @color) {
  table#transactions > tbody > tr@{class} {
    color: @color;
  }

  table#legend > tbody > tr > td@{class} {
    color: @color;
  }  
}

.transaction-status(.credit, limegreen);
.transaction-status(.debit.paid, goldenrod);
.transaction-status(.debit.unpaid, crimson);

一种可能的解决方法是重新调整事物,使不同的事务类型具有一个唯一的类名,但这感觉就像穿越到 IE6 时代。 IE。我知道,但想避免这个有效的 LESS,它看起来如此接近,但到目前为止:

.transaction-status(@class, @color) {
  table#transactions > tbody > tr.@{class} {
    color: @color;
  }

  table#legend > tbody > tr > td.@{class} {
    color: @color;
  }  
}

.transaction-status(credit, limegreen);
.transaction-status(debit-paid, goldenrod);
.transaction-status(debit-unpaid, crimson);

我尝试引用类名,但即使这使第一个 LESS 示例编译,引号也会传递给输出 CSS。那么,有没有办法将“标识符”以外的东西作为参数传递给 LESS mixin,并让它在选择器插值中正确工作?

【问题讨论】:

  • 为什么不能使用. 在选择器中的那个而不是参数?
  • 为了防止这种特殊情况,也可以使用appended parent selector技巧,尽管这种方法有其缺点,而且并不总是很好闻。
  • 顺便说一句。我总是想知道为什么每个人都更喜欢table#legend &gt; tbody &gt; tr &gt; td.debit.unpaid 而不是table .debit.unpaid(你没有其他表格,这些单元格颜色相反,是吗?)。
  • @seven-phases-max:其实我觉得追加父选择器的方式也很好。
  • @seven-phases-max 可能只有我戴着眼罩。我有一些其他可重用(OOCSS-ish)的表格样式需要如此精确,所以这种方法在我的脑海中被烧毁了。感谢您的建议,我不知道 &amp; 是这样工作的。

标签: html css less less-mixins


【解决方案1】:

选项 1:

正如您所提到的,一种选择是在引号内传递值。但是完成后,您需要确保在使用它们执行选择器插值之前将其删除。这可以通过使用~()e() 内置函数来完成。它们都会从输入值中去掉引号。完成此操作后,其值没有引号的临时变量可用于选择器插值,如下所示:

.transaction-status(@class, @color) {
    @className: ~"@{class}";
    table#transactions > tbody > tr@{className} {
        color: @color;
    }

    table#legend > tbody > tr > td@{className} {
        color: @color;
    }  
}

.transaction-status(".credit", limegreen);
.transaction-status(".debit.paid", goldenrod);
.transaction-status(".debit.unpaid", crimson);

选项 2:(我认为有点绕)

您还可以使用... 选项传入任意数量的类(请注意,这需要对传递输入的顺序稍作更改),然后将其转换为字符串并使用替换功能添加.replace 函数是必需的,因为转换后的字符串格式为 class1 class2(空格分隔符)。

.transaction-status(@color, @class...) {
    @className: e(replace("@{class}" , " " , ".", 'g' )); 
    /* arguments: input string, pattern to match, replacement value, regex flags */
    table#transactions > tbody > tr.@{className} {
        color: @color;
    }

    table#legend > tbody > tr > td.@{className} {
        color: @color;
    }   
}

.transaction-status(limegreen, credit);
.transaction-status(goldenrod, debit, paid);
.transaction-status(crimson, debit, unpaid);

注意:选项 2 仅适用于 Less v.1.7.0 及更高版本,因为 replace 函数仅在 v1.7.0 中引入。

【讨论】:

  • 我想我是在寻找~ 方法,我尝试使用它但不断收到错误,并认为该语法可能已被弃用。谢谢。
【解决方案2】:

看起来无论哪种情况,您都可以为整行着色?如果是这样,选择器的简单嵌套将减少重复,并且可以说更容易阅读:

table#transactions, table#legend {
    & > tbody > tr {
      &.credit {
        color: limegreen;
      }

      &.debit.paid {
        color: goldenrod;
      }

      &.debit.unpaid {
        color: crimson;
      }
    }
  }
}

但这并不能让您在代码的其他部分轻松地重用这些类/颜色组合,而这正是您可能想做的事情。我会更像这样定义你的颜色类:

.trans-status {
  &.credit {
    color: limegreen;
  }

  &.debit.paid {
    color: goldenrod;
  }

  &.debit.unpaid {
    color: crimson;
  }
}

然后您可以更精确地应用适当的类:

<tr>
  <td>An unpaid debit</td>
  <td class="trans-status debit unpaid">($3.00)</td>
</tr>

这是使用这种方法的示例的一个分支:

https://codepen.io/anon/pen/mxMLPG

使用这种方法的另一个好处是,您还可以将这些样式作为混入应用到您的 Less 文件中。例如,如果您需要在代码的其他部分使用相同的颜色值,您可以更抽象地定义颜色,并以不同的方式应用它们:

.status {
  .success {
    color: limegreen;
  }

  .confirmed {
    color: goldenrod;
  }

  .warning {
    color: crimson;
  }
}

.negative-balance {
  .status.warning;
}

#rewards-points {
  .status.success;
}

还值得注意的是,如果您确实需要将规则/mixin 传递给其他 mixin,Less 1.7.0 及更高版本支持Detatched Rulesets 以使用清洁器完成同样的事情语法比字符串插值。最初的问题并不真正保证这种复杂程度,但它对于断点之类的东西很有用:

.break(@min-width; @max-width; @rules) {
  @media only screen and (min-width:@min-width) 
    and (max-width: @max-width){
    @rules();
  }
}

.break(0px, 480px, {
  font-size: 10px;
  padding: 8px;
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-27
    • 1970-01-01
    相关资源
    最近更新 更多