使用较少,我正在尝试输出属性的css组合简写值,同时根据作为变量传递的值数量检测作为变量传递的值的类型。
@v1
@v1
和@v2
@v1
、@v2
、@v3
和@v4
对于检测到的每个变量,检查is是否是大于0的数字,如果是,则为每个属性值输出一个rem和px值,因此符合的css可能类似于:
.demobox{
border-width: 10px 20px 0 0;
border-width: 1rem 2rem 0 0;
padding: 0 50px;
padding: 0 2rem;
margin: 20px auto;
margin: 2rem auto;
font-size: 16px;
font-size: 1.6rem;
}
在声明不超过两个值的情况下,这很容易解决,但是如果我需要四个值,嵌套混合和保护的数量就会变得非常复杂。
选择rems的原因是与em相比易于实现,并且可以防止记住必须将字体大小重置为每个父项目的头痛。此外,对于rems和em,旧设备支持问题是可比的,所以我认为px回退效果最好。
这是我目前所处位置的密码笔,但我会尽我所能解释我的工作。
有没有办法简化这个过程?我是新手。我想有一个更简单的方法来检测
谢啦
我有一个参数混合,它输出一个rem
值和px
回退值以及声明的属性
@root-font-size: 10;
.rem(@property, @v1) when (@v1 = @v1){
@px1: @v1 * @root-font-size;
@{property}: ~'@{px1}px';
@{property}: ~'@{v1}rem';
}
这对于快速生成一组css属性的rem和像素回退非常有用
/* call the rem mixin */
.demobox {
.rem(margin, 2);
}
/* output */
.demobox {
margin: 20px;
margin: 2rem;
}
一个非常有用的案例是生成带有回退的font-size
和line-高
值
/* call the font-classes mixin */
.font-classes(@fontsize, @lineheight) {
.rem(font-size, @fontsize);
.rem(line-height, @lineheight);
}
/* output */
.demobox {
font-size: 16px;
font-size: 1.6rem;
line-height: 24px;
line-height: 2.4rem;
}
到目前为止,我可以输出单个值的rem和像素回退,并将. rem
混合嵌套在另一个混合中。
目前,如果我想传递多个值,我必须为每个必需的值调用. rem
混合:
/* call the rem mixin */
.demobox {
.rem(margin-left, 2);
.rem(margin-right, 2);
}
/* output */
.demobox {
margin-left: 20px;
margin-left: 2rem;
margin-right: 20px;
margin-right: 2rem;
}
理想情况下,我希望能够将一个带有属性的两个或四个值传递给. rem
混合。
.demobox {
.rem(margin, 2, 1);
}
正如我之前提到的,对于两个值并检查值类型并不难。这需要一个版本的. rem
混合,并应用gaurd来检查@v2
是否已声明。
这会触发嵌套的. rem-2
混合。
// when there are two values
.rem(@property, @v1, @v2) when (@v1 = @v1) and (@v2 = @v2){
.rem-two(@property, @v1, @v2);
}
. rem-2
有三个版本,每个版本的守卫都不同。
检测@v1
和@v2
是否都是大于0的数字
.rem-two(@property, @v1, @v2) when (@v1 = @v1) and not (@v1 = 0) and (isnumber(@v1)) and (@v2 = @v2) and not (@v2 = 0) and (isnumber(@v2)) {
@px1: @v1 * @root-font-size;
@px2: @v2 * @root-font-size;
@{property}: ~'@{px1}px @{px2}px';
@{property}: ~'@{v1}rem @{v2}rem';
}
检测@v1
和@v2
是否都是大于0的数字
.rem-two(@property, @v1, @v2) when (@v1 = @v1) and not (@v1 = 0) and (isnumber(@v1)) and (@v2 = 0), not (isnumber(@v2)){
@px1: @v1 * @root-font-size;
@{property}: ~'@{px1}px @{v2}';
@{property}: ~'@{v2}rem @{v2}';
}
/* call the rem mixin */
.demobox {
.rem(margin, 2, 1);
}
/* outputs */
.demobox {
margin: 10px 20px;
margin: 1rem 2rem;
}
检测@v1
是否是大于0的数字,@v2
是否是0的值或不是数字
@px2像素回退不是必需的,因此被删除。
.rem-two(@property, @v1, @v2) when (@v1 = @v1) and not (@v1 = 0) and (isnumber(@v1)) and (@v2 = 0), not (isnumber(@v2)){
@px1: @v1 * @root-font-size;
@{property}: ~'@{px1}px @{v2}';
@{property}: ~'@{v2}rem @{v2}';
}
/* call the rem mixin */
.demobox {
.rem(margin, 2, auto);
}
/* outputs */
.demobox {
margin: 10px auto;
margin: 1rem auto;
}
检测@v1
是否都是0值或不是数字,并且@v2
是大于0的数字
@px1像素回退不是必需的,因此被删除。
.rem-two(@property, @v1, @v2) when (@v1 = 0), not (isnumber(@v1)) and (@v2 = @v2) and not (@v2 = 0) and (isnumber(@v2)){
@px2: @v2 * @root-font-size;
@{property}: ~'@{v1} @{px2}px';
@{property}: ~'@{v1} @{v2}rem';
}
/* call the rem mixin */
.demobox {
.rem(margin, 0, 20);
}
/* outputs */
.demobox {
margin: 0 20px;
margin: 0 2rem;
}
由于这两个值版本的混音只有3种可能性,解决这个问题很容易,但是有了3个或4个值,嵌套的混音和守卫的数量就会扩大到涵盖所有可能性。
作为附加示例。我已经重新使用. rem
混合来输出px
和rem
,带有供应商前缀的border-半径
值,以确保它只处理数值,我有警卫来检查传递的值是否是大于0的数字
.prefix(@property, @v1) when (isnumber(@v1)) and (@v1 > 0) {
@px1: @v1 * @root-font-size;
-webkit-@{property}: ~'@{px1}px';
-moz-@{property}: ~'@{px1}px';
@{property}: ~'@{px1}px';
-webkit-@{property}: ~'@{v1}rem';
-moz-@{property}: ~'@{v1}rem';
@{property}: ~'@{v1}rem';
}
/* call prefix mixin */
.demobox{
.prefix(border-radius,5);
}
/* output */
.demobox{
-webkit-border-radius: 50px;
-moz-border-radius: 50px;
border-radius: 50px;
-webkit-border-radius: 5rem;
-moz-border-radius: 5rem;
}
我可以交换警卫来检查值是否为0(因此我可以重置属性),或者它是否是数字以外的任何东西,例如输出前缀框大小。
我问not(isnumber(@v1))
而不是(isstring(@v1))
的守卫的原因是这样我就不必在值“border-box”中添加单引号。
.prefix(@property, @v1) when (@v1 = 0), not (isnumber(@v1)) {
-webkit-@{property}: ~'@{v1}';
-moz-@{property}: ~'@{v1}';
@{property}: ~'@{v1}';
}
/* call prefix mixin */
.demobox {
.prefix(box-sizing, border-box);
}
/* output */
.demobox {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
如果您将传递的参数视为数组(简化的impl.,代码片段中的要求太多而无法在示例中涵盖),则可以简化事情。
// usage
@root-font-size: 10;
div {
.rem(border-radius, 1, margin, 2 auto, padding, 4 5 6 inherit);
}
// impl:
.rem-value_(@p, @v, @u) when (isnumber(@v)) {
@{p}+_: (@v * @u);
}
.rem-value_(@p, @v, @u) when (default()) {
@{p}+_: @v;
}
.rem(@args...) {
.i; .i(@i: length(@args)) when (@i > 0) {
.i((@i - 2));
@property: extract(@args, (@i - 1));
@values: extract(@args, @i);
.j(@property, @values, (1px * @root-font-size));
.j(~'@{property} ', @values, 1rem); // have to use ~'@{property} ' hack to isolate rem and px properties;
}
.j(@p, @v, @u, @j: length(@v)) when (@j > 0) {
.j(@p, @v, @u, (@j - 1));
.rem-value_(@p, extract(@v, @j), @u);
}
}
这个循环非常可怕,但是值输出混合是非常透明和完全可定制的(如果需要,您可以添加更多条件)。