【问题标题】:Placeholder Mixin SCSS/CSS占位符混合 SCSS/CSS
【发布时间】:2013-06-15 10:23:58
【问题描述】:

我正在尝试为 sass 中的占位符创建一个 mixin。

这是我创建的 mixin。

@mixin placeholder ($css) {
  ::-webkit-input-placeholder {$css}
  :-moz-placeholder           {$css}
  ::-moz-placeholder          {$css}
  :-ms-input-placeholder      {$css}  
}

这就是我想要包含 mixin 的方式:

@include placeholder(font-style:italic; color: white; font-weight:100;);

显然这不会起作用,因为所有的冒号和分号都被传递给了 mixin,但是......我真的很想输入静态 css 并像上面一样通过它功能。

这可能吗?

【问题讨论】:

    标签: css sass


    【解决方案1】:

    您正在寻找@content 指令:

    @mixin placeholder {
      ::-webkit-input-placeholder {@content}
      :-moz-placeholder           {@content}
      ::-moz-placeholder          {@content}
      :-ms-input-placeholder      {@content}  
    }
    
    @include placeholder {
        font-style:italic;
        color: white;
        font-weight:100;
    }
    

    SASS 参考有更多信息,可以在这里找到: http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#mixin-content


    从 Sass 3.4 开始,这个 mixin 可以这样写,既可以嵌套也可以非嵌套:

    @mixin optional-at-root($sel) {
      @at-root #{if(not &, $sel, selector-append(&, $sel))} {
        @content;
      }
    }
    
    @mixin placeholder {
      @include optional-at-root('::-webkit-input-placeholder') {
        @content;
      }
    
      @include optional-at-root(':-moz-placeholder') {
        @content;
      }
    
      @include optional-at-root('::-moz-placeholder') {
        @content;
      }
    
      @include optional-at-root(':-ms-input-placeholder') {
        @content;
      }
    }
    

    用法:

    .foo {
      @include placeholder {
        color: green;
      }
    }
    
    @include placeholder {
      color: red;
    }
    

    输出:

    .foo::-webkit-input-placeholder {
      color: green;
    }
    .foo:-moz-placeholder {
      color: green;
    }
    .foo::-moz-placeholder {
      color: green;
    }
    .foo:-ms-input-placeholder {
      color: green;
    }
    
    ::-webkit-input-placeholder {
      color: red;
    }
    :-moz-placeholder {
      color: red;
    }
    ::-moz-placeholder {
      color: red;
    }
    :-ms-input-placeholder {
      color: red;
    }
    

    【讨论】:

    • 完美,正是我需要的。
    • 不知道为什么会恢复,但答案不正确。您需要在每个供应商前缀的开头使用“@”。看看 Dave Hein 的答案,或者更好的是 - 尝试运行此代码,您会发现它不起作用。
    • @RickM 它已被还原,因为您所做的修改无法编译(错误:基本级规则不能包含父选择器引用字符'&'。)。这会创建 OP 正在寻找的确切输出,而您声称“正确”的答案不会。
    • 有趣...您是通过 cli 编译的吗?看起来肯定存在版本冲突,因为我的情况正好相反,从其他回复来看,其他一些回复也是如此。
    • 是的,CLI:通过 Compass 的 Sass 3.3.0.rc.3。使用CodePenSassmeister 仔细检查。如果您希望能够使用 mixin 获得像 input::-webkit-input-placeholder 这样的选择器,& 是必需的,但它会阻止您在根级别使用它。 sassmeister.com/gist/9469073。现在,如果您使用的是 LibSass,那就另当别论了。
    【解决方案2】:

    为什么不这样呢?

    它使用列表、迭代和插值的组合。

    @mixin placeholder ($rules) {
    
      @each $rule in $rules {
        ::-webkit-input-placeholder,
        :-moz-placeholder,
        ::-moz-placeholder,
        :-ms-input-placeholder {
          #{nth($rule, 1)}: #{nth($rule, 2)};
        }  
      }
    }
    
    $rules: (('border', '1px solid red'),
             ('color', 'green'));
    
    @include placeholder( $rules );
    

    【讨论】:

    • 这有点复杂,我正在寻找内容指令,但谢谢!
    【解决方案3】:

    我发现cimmanonKurt Mueller 给出的方法几乎可行,但我需要一个父引用(即,我需要在每个供应商前缀中添加“&”前缀);像这样:

    @mixin placeholder {
        &::-webkit-input-placeholder {@content}
        &:-moz-placeholder           {@content}
        &::-moz-placeholder          {@content}
        &:-ms-input-placeholder      {@content}  
    }
    

    我是这样使用 mixin 的:

    input {
        @include placeholder {
            font-family: $base-font-family;
            color: red;
        }
    }
    

    有了父引用,就会生成正确的 css,例如:

    input::-webkit-input-placeholder {
        font-family: Constantia, "Lucida Bright", Lucidabright, "Lucida Serif", Lucida, "DejaVu Serif", "Liberation Serif", Georgia, serif;
        color: red;
    }
    

    如果没有父引用 (&),则在供应商前缀之前插入一个空格,CSS 处理器将忽略该声明;看起来像这样:

    input::-webkit-input-placeholder {
        font-family: Constantia, "Lucida Bright", Lucidabright, "Lucida Serif", Lucida, "DejaVu Serif", "Liberation Serif", Georgia, serif;
        color: red;
    }
    

    【讨论】:

    • 非常感谢。为了使接受的答案/解决方案发挥作用,您节省了我数小时的反复试验......
    • 值得注意的是,您的选择器现在有点过分了(除非您真的不希望它在输入或选择元素上工作)。添加父选择器会阻止您在没有嵌套的情况下使用 mixin(这是 OP 正在寻找的)。
    • & 是完全必要的。编辑了流行的答案以反映这一点。
    • +1。一些浏览器现在支持官方的::placeholder属性,所以我建议在顶部添加这个:&::placeholder {@content}
    【解决方案4】:

    这是简写语法

    =placeholder
      &::-webkit-input-placeholder
        @content
      &:-moz-placeholder
        @content
      &::-moz-placeholder
        @content
      &:-ms-input-placeholder
        @content
    

    像这样使用它

    input
      +placeholder
        color: red
    

    【讨论】:

    • 老实说,我认为这更难阅读,也不像常规语法那样简洁
    • 我试图把它作为评论,但是太大了。我宁愿使用这种语法,也不能让选择的答案太容易工作。我认为它可能对其他人有用。
    • 这个是最好的,易于理解和实施。
    【解决方案5】:

    为了避免 sass 编译器抛出“Unclosed block: CssSyntaxError”错误,添加一个“;”到@content 的末尾。

    @mixin placeholder {
       ::-webkit-input-placeholder { @content;}
       :-moz-placeholder           { @content;}
       ::-moz-placeholder          { @content;}
       :-ms-input-placeholder      { @content;}
    }
    

    【讨论】:

      【解决方案6】:

      我使用与 NoDirection 所写完全相同的 sass mixin 占位符。我在 sass mixins 集合 here 中找到了它,我对此非常满意。 a text 更多地解释了 mixins 选项。

      【讨论】: