将Less的mixin转换为SCSS

3

我使用以下的LESS混合器来生成双向语言支持的CSS。

.ltr(@ltrRules) {
  body[dir="ltr"] & ,
  body[dir="rtl"] *[dir="ltr"] & , 
  body[dir="rtl"] *[dir="ltr"]&    { @ltrRules(); }
}

.rtl (@rtlRules) {
  body[dir="rtl"] & , 
  body[dir="ltr"] *[dir="rtl"] & , 
  body[dir="ltr"] *[dir="rtl"]&    { @rtlRules(); }
}

.bidi(@ltrRules,@rtlRules) {
  .ltr(@ltrRules);
  .rtl(@rtlRules);
}

这些稍后会像这样使用:
// padding
// ------------------------------------------
.padding-start(@p) { 
  .bidi(
   { padding-left: @p } ,
   { padding-right: @p }
  )
}

.padding-end(@p) { 
  .bidi(
   { padding-right: @p } ,
   { padding-left: @p }
  )
}

这样,当我最终写下这段话时:
div.myclass { 
   .padding-start(10px) 
}

我希望得到一组规则,如果
在从左到右的上下文中,将其样式设置为 padding-left: 10px ; 如果
在从右到左的上下文中,则将其样式设置为 padding-right: 10px 。

我现在正在尝试将其转换为SCSS,并已经得到了以下结果:

@mixin ltr {
  body[dir="ltr"] & ,
//body[dir="rtl"] *[dir="ltr"]&      
  body[dir="rtl"] *[dir="ltr"] & { @content }
}


@mixin rtl {
  body[dir="rtl"] & , 
//body[dir="ltr"] *[dir="rtl"]&    
  body[dir="ltr"] *[dir="rtl"] & { @content}
}


/*
@mixin bidi($ltrRules,$rtlRules) {
  @include ltr(@include ltrRules);
  @include rtl(@include rtlRules);
}
*/

@mixin bidi-padding-start($p) { 
   @include ltr { 
    padding-left: $p; 
   } 
   @include rtl { 
    padding-right: $p; 
   }
}

但是我仍然有几个问题:

1)如果我在rtl和ltr mixin中取消中间选择器的注释,那么我会得到以下错误:Invalid CSS after "[dir="ltr"]": expected "{", was "&". "&" may only be used at the beginning of a compound selector. 我可以不使用此规则,但我宁愿不这样做......我希望它能编译

.myclass {
   @include padding-start(10px)
}

into:

body[dir="rtl"] .myclass , 
      body[dir="ltr"] *[dir="rtl"] .myclass , 
      body[dir="ltr"] *[dir="rtl"].myclass  

2) 我找不到一种实现@mixin bidi的方法,因为我找不到一种将两个内容块传递给mixin的方法。

有人能帮忙进行迁移吗?

1个回答

4

目前,SASS的功能仅限于将单个@content块传递到@mixin中。在GitHub问题上有一个功能请求讨论,但它已关闭,看起来从未实现。

在那个讨论中,有人提出了一种解决方法,可以有效地使用@extend。它通过使用%placeholders来允许您引用临时规则集。然而,它似乎有点hacky,并且需要测试更复杂的规则集和更深层次的嵌套。

@mixin ltr {
  body[dir="ltr"] & ,
//body[dir="rtl"] *[dir="ltr"]&      
  body[dir="rtl"] *[dir="ltr"] & { @content }
}


@mixin rtl {
  body[dir="rtl"] & , 
//body[dir="ltr"] *[dir="rtl"]&    
  body[dir="ltr"] *[dir="rtl"] & { @content}
}

@mixin bidi {
  @content;
  @include ltr {
    @extend %ltr !optional;
  }

  @include rtl {
    @extend %rtl !optional;
  }
}

@mixin padding-end($p) {
  @include bidi {
    @at-root { 
      %ltr {
        padding-right: $p;
      }
      %rtl {
        padding-left: $p;
      }
    }
  }
}

.test {
  @include padding-end(5px);
}

另一种更易读的选择可能是在 bidi 的位置明确调用两个 mixins。可以编写一个脚本来执行此迁移。

@mixin padding-end($p) { 
    @include rtl {
        padding-left: $p;
    }

    @include ltr {
        padding-right: $p;
    }
}

1
谢谢,我想我会坚持使用这两个包含文件。 :) 我认为LESS版本更好,更易于使用。 - epeleg
1
哎呀,我喜欢你在LESS中最初的实现方式,看起来很干净! - miir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接