代码之家  ›  专栏  ›  技术社区  ›  epeleg

将较少的混合器转换为SCS

  •  2
  • epeleg  · 技术社区  · 6 年前

    我使用以下较少的mixin来生成用于bidi使用的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) 
    }
    

    我会得到一套规则 div.myclass 具有 padding-left:10px 如果div处于从左到右的上下文中,或者 padding-right:10px 如果div处于从右向左的上下文中。

    我现在正试图将其转换为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混合中的中间选择器的注释,则会出现以下错误: Invalid CSS after "[dir="ltr"]": expected "{", was "&". "&" may only be used at the beginning of a compound selector. 没有这个规则我可以活下去,但我宁愿不。。。我希望它能编译

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

    进入:

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

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

    有人能帮忙迁移吗

    1 回复  |  直到 6 年前
        1
  •  3
  •   miir    6 年前

    目前,SASS的功能仅限于传递单个 @content 阻止进入a @mixin . 在上进行了功能请求讨论 github issue 但它已经关闭了,看起来它从未实现。

    在那次讨论中 suggested a workaround 有效地与 @extend . 它通过使用 %placeholders 允许您引用临时规则集。然而,它似乎有点粗糙,需要测试更复杂的规则集和更深的嵌套。

    @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);
    }
    

    对于未来的开发人员来说,另一个更具可读性的选项可能只是显式地调用两个mixin来代替 bidi . 可以编写脚本进行此迁移。

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