我正在创建一个显示账户交易的视图,我想对交易类型/状态进行彩色编码。我还想展示一个图例来解释颜色代码。
我想要一个这样结构的最终结果:
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时代。也就是说,我知道,但我想避免这个有效的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,并使其正确地在选择器插值中工作?
选项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函数添加.
。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中引入。
看起来在任何一种情况下都可以为整行上色?如果是这样的话,一个简单的选择器嵌套将减少重复,并且可以说更容易阅读:
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文件中将这些样式作为mixin应用。例如,如果你需要在代码的其他部分使用相同的颜色值,你可以更抽象地定义颜色,并以不同的方式应用它们:
.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 Ruleset,以比字符串插值更干净的语法来完成同样的事情。最初的问题并不能真正保证这种复杂程度,但它对断点之类的东西很有用:
.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;
});