css - SASS mixin - 连接/折叠到单个属性?

标签 css sass mixins

我正在尝试编写一个简单的 mixin,它将为传递的属性生成一些跨浏览器代码,但如果您多次调用它,我希望它以某种方式将新值附加到现有属性规则。

例如:

=foo($foo)
   foo: "#{$foo}"

.test
   +foo( test 1 )
   +foo( test 2 )

会产生

.test {
   foo: "test 1";
   foo: "test 2";
}

但我试图让它生成的是:

.test {
   foo: "test 1, test 2";
}

我知道我可以只做 +foo(test 1, test 2),但有时我可能有很多参数,因为基于缩进的 SASS 语法不允许你将 mixin 参数拆分成多行(可悲的是),我想要一种更简洁的方式来使用这个 mixin,而不会在一行中塞满大量参数

最佳答案

Sass 不处理你正在寻找的东西——但你可以使用映射、全局标志和包含包装器来解决它。为什么我会认为以下是反模式。

Demo on codepen

注意!以下内容可能需要一些详细说明,但现在我只添加一些 SCSS(面向更广泛的受众)——我相信您可以将其转换为 Sass

全局变量

首先,我们创建一组全局变量来保存包含的状态和值。

$render-map:();  //  map to hold key value pairs for later render
$render: false;  //  render flag if true we print out render-map
$concat: false;  //  concat flag to trigger value concatenation 

渲染混合

为了处理跟踪渲染内容的繁琐工作,我们创建了一个多用途渲染混合。该 mixin 可以在其他 mixin 内部使用以设置键值,并在选择器内部使用以呈现独特的属性。稍后我们将创建一个小的 mixin 来处理值连接,因为这是不太常见的用例。

@mixin render($args...){
    //  no arguments passed and not in the state of rendering
    //  1) switch to rendering state 
    //  2) include content (nested included)
    //  3) render render-map content
    //  4) before exit disable render state 
    //  5) empty render-map
    @if length($args) == 0 and not $render {
        $render: true !global; // 1
        @content;              // 2   
        @each $key, $value in $render-map { #{$key}:$value; } // 3
        $render: false  !global; // 4
        $render-map: () !global; // 5
    } 

    //  if arguments are passed we loop through keywords to build our render-map  
    //  the keyword key is the same as the passed variable name without the `$`
    //  e.g.   @include render($margin-left: 10px) becomes  margin-left: 10px
    //  1) get keywords
    //  2) loop through keywords
    //  3) look for existing render-map values or use empty list
    //  4) in case we have a concat flag concatinate render-map value
    //  5) in case we don't have a concat flag we overwrite render-map value
    //  6) add key value pair to render-map
    @else {
        $keywords: keywords($args);        // 1
        @each $key, $value in $keywords {  // 2
            $map-value: map-get($render-map, $key) or (); // 3
            @if $concat { $map-value: if($map-value, append($map-value, $value, comma), $value); } // 4
            @else { $map-value: if($value, $value, $map-value); } // 5
            $render-map: map-merge($render-map, ($key: $map-value)) !global; // 6
        }        
    }
}

渲染连接

为了处理值连接,我们为处理全局连接标志的渲染混合创建了一个包装器混合。

注意 render-concat 仅用于在 mixin 中设置键/值对——为什么它不采用内容 block 。

@mixin render-concat($args...){ 
    $concat: true !global;     // set global concat flag for render mixin
    @include render($args...); // pass args on to the render mixin
    $concat: false !global;    // reset global concat flag
}  

用法

@mixin foo($value){
    //  add the passed value to the `foo` key ($ is stripped) of the render-map.    
    @include render-concat($foo: $value);
}


.test {
    //  in order to render our render-map content we wrap our includes
    //  inside a @include render (without any arguments).
    //  note the quoted strings to prevent sass from thinking we are passing lists
    @include render {
        @include foo('test 1');
        @include foo('test 2');
        @include foo('test 3');
    }
}

输出

.test {
  foo: "test 1", "test 2", "test 3";
}

如前所述,使用它时要非常小心......你很容易得到意想不到的输出。

关于css - SASS mixin - 连接/折叠到单个属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43402914/

相关文章:

javascript - 如何在 javascript 中定义 html 类?

css - twitter bootstrap,row-fluid 里面的 row-fluid 有什么问题

android - 如何以正确的方式为移动设备使用 CSS?

css - 在 SASS 中获取设备大小

css - 将鼠标悬停在子元素上,更改父元素的 CSS?

java - 使用 Jackson 序列化 Typed 集合时出错

css - 浏览器打印设置中的默认边距是多少?

css - SCSS : Improve performance

javascript - 使用 Backbone 进行方面编程

javascript - 在 Jade Mixin 中显示中断标签