compass-sass - 将mixin声明中的变量传递到附加的内容 block 中?

标签 compass-sass sass susy-compass

在 Ruby 中,您可以轻松地将方法内部的变量传递到附加的代码块中:

def mymethod
  (1..10).each { |e| yield(e * 10) } # Passes a number to associated block
end

mymethod { |i| puts "Here comes #{i}" } # Outputs the number received from the method

我想在 SASS mixin 中做同样的事情:

=my-mixin
  @for $i from 1 to 8
    .grid-#{$i}
      @content

+my-mixin
  color: nth("red green blue orange yellow brown black purple", $i)

此代码不起作用,因为 $i 是在 mixin 声明中声明的,并且无法在使用 mixin 的外部看到。 :(

那么......我如何利用在 mixin 声明中声明的变量?

当我使用网格框架和媒体查询时,我非常需要这个功能。目前,我每次需要时都必须复制 mixin 声明中的内容,这违反了 DRY 规则。

更新 2013-01-24

这是一个真实的例子。

我有一个混合断点循环并为每个断点应用一次提供的代码:

=apply-to-each-bp
  @each $bp in $bp-list
    +at-breakpoint($bp) // This is from Susy gem
      @content

当我使用这个 mixin 时,我必须在 @content 中使用这个 $bp 值。它可能是这样的:

// Applies to all direct children of container
.container > *
  display: inline-block

// Applies to all direct children of container,
// if container does not have the .with-gutters class
.container:not(.with-gutters) > *
  +apply-to-each-bp
    width: 100% / $bp

// Applies to all direct children of container,
// if container has the .with-gutters class
.container.with-gutters  > *
  +apply-to-each-bp
    $block-to-margin-ratio: 0.2
    $width: 100% / ($bp * (1 + $block-to-margin-ratio) - $block-to-margin-ratio)
    width: $width
    margin-right: $width * $block-to-margin-ratio

    &:nth-child(#{$bp})
      margin-right: 0

但这不起作用,因为 $bp 的值在 @content 中不可用。

在调用 mixin 之前声明变量将无济于事,因为 @content 在 mixin 被解析之前被解析一次。

相反,每次我需要它时,我都必须做两个丑陋的大腿:
  • 声明一个临时混合,
  • 写循环,违反DRY原则:

  • // Each of the following mixins is mentioned in the code only once.
    =without-gutters($bp)
      width: 100% / $bp
    
    =with-gutters($bp)
      $block-to-margin-ratio: 0.2
      $width: 100% / ($bp * (1 + $block-to-margin-ratio) - $block-to-margin-ratio)
      width: $width
      margin-right: $width * $block-to-margin-ratio
    
      &:nth-child(#{$bp})
        margin-right: 0
    
    // Applies to all direct children of container
    .container > *
      display: inline-block
    
    // Applies to all direct children of container,
    // if container does not have the .with-gutters class
    .container:not(.with-gutters) > *
      @each $bp in $bp-list
        +at-breakpoint($bp) // This is from Susy gem
          +without-gutters($bp)
    
    // Applies to all direct children of container,
    // if container has the .with-gutters class
    .container.with-gutters  > *
      @each $bp in $bp-list  // Duplicate code! :(
        +at-breakpoint($bp)  // Violates the DRY principle.
          +with-gutters($bp)
    

    所以,问题是:有没有办法做到这种 Ruby 风格?

    最佳答案

    Sass 中的变量对它们有作用域。它们仅在创建它们的 block 中可见。如果您希望变量在 mixin 内部和外部都可以访问,则必须在全局范围内定义它:

    $var: 0;
    
    @mixin test {
        $var: $var + 1;
        color: red;
    }
    
    .test {
        $var: 5;
        @include test;
        @debug $var; // DEBUG: 6
    }
    

    只要你不关心$var的状态很长一段时间,这应该可以满足您的目的。

    对于您的示例,这不起作用,因为它看起来像 @content首先处理。您需要的是一个以不同方式编写的 mixin:
    @mixin test($properties...) {
        @for $i from 1 to 8 {
            .grid-#{$i} {
                @each $p in $properties {
                    $list: nth($p, 2);
                    @if length($list) > 1 {
                        #{nth($p, 1)}: nth($list, $i);
                    } @else {
                        #{nth($p, 1)}: $list;
                    }
                }
                @content;
            }
        }
    }
    
    .test {
        @include test(color (red green blue orange yellow brown black purple));
    }
    

    生成的 CSS:
    .test .grid-1 {
      color: red;
    }
    
    .test .grid-2 {
      color: green;
    }
    
    .test .grid-3 {
      color: blue;
    }
    
    .test .grid-4 {
      color: orange;
    }
    
    .test .grid-5 {
      color: yellow;
    }
    
    .test .grid-6 {
      color: brown;
    }
    
    .test .grid-7 {
      color: black;
    }
    

    像这样的 mixin 可以输入任意数量的参数,并且仍然允许您使用 @content如果你希望。

    关于compass-sass - 将mixin声明中的变量传递到附加的内容 block 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14054003/

    相关文章:

    blogs - 内置 SASS/Compass 和 HAML 的博客引擎

    css - SASS中补码和反转的区别?

    javascript - 为什么我的 Owl Carousel 项目是垂直排序而不是水平排序的?

    javascript - Webpack 错误 : You may need an appropriate loader to handle this file type. | @字符集 "UTF-8";

    css - SCSS 和 Susy : Makes boxes extend into grid gutters

    css - rails 错误编译 css Assets

    angularjs - 如何在 JHipster UI 添加 DatePicker

    sass - WebStorm 中的 SCSS 颜色预览

    susy-compass - 全宽 div 内的 Susy 中心内容

    css - 固定宽度侧边栏使用超过 3 个定义的列