1

I'm styling the placeholder text in my <input> tags, and I've discovered some odd behavior.

If I simply put the following, Chrome renders the placeholder text correctly:

:focus::-webkit-input-placeholder {
  position: absolute;
  left: -9000px;
}

However, if I try to include for multiple browsers in the same line, it doesn't display at all:

:focus::-webkit-input-placeholder, :focus:-moz-placeholder, :focus::-moz-placeholder, :focus:-ms-input-placeholder {
    position: absolute;
    left: -9000px; 
}

I'd ideally like to have my SASS look like the below, but I for whatever reason cannot have the different selectors separated by commas.

:focus {
  outline: none;
  &::-webkit-input-placeholder, &:-moz-placeholder, &::-moz-placeholder, &:-ms-input-placeholder {
      // Hide placeholder text on focus
      position: absolute;
      left: -9000px;
  }
}

Is there any SASS syntax to force it to process each selector with its own block, like the below sample?

:focus::-webkit-input-placeholder {
    position: absolute;
    left: -9000px;
}

:focus:-moz-placeholder {
    position: absolute;
    left: -9000px;
}

// etc.
jdotjdot
  • 16,134
  • 13
  • 66
  • 118
  • The reason for that is given here: http://stackoverflow.com/questions/16982449/why-isnt-it-possible-to-combine-vendor-specific-pseudo-elements-classes-into-on – BoltClock Mar 18 '14 at 06:12
  • Thanks, I figured the reason was something along those lines. That's why I'm looking for a SASS-y way around it. – jdotjdot Mar 18 '14 at 06:33
  • possible duplicate of [Placeholder Mixin SCSS/CSS](http://stackoverflow.com/questions/17181849/placeholder-mixin-scss-css) – cimmanon Mar 18 '14 at 12:13

1 Answers1

1

You could easily create a mixin and define the style of all placeholders just once, through a content block passed to the mixin itself, like so:

@mixin placeholder {

    @each $placeholder
        in "::-webkit-input-placeholder",
           ":-moz-placeholder",
           "::-moz-placeholder", 
           ":-ms-input-placeholder" {

        /* for each placeholder in the above list print the browser vendor
           selector, chained with its parent element */

        &#{$placeholder} {
            /* content is replaced with the actual style, passed as a block
               in the mixin inclusion below */

            @content;
        }
    }

}


:focus {
    @include placeholder {
        color: #ccc;
        font-style: italic;
    }
}

This will produce the following output

:focus::-webkit-input-placeholder {
    color: #ccc;
    font-style: italic;
}
:focus:-moz-placeholder {
    color: #ccc;
    font-style: italic;
}
:focus::-moz-placeholder {
    color: #ccc;
    font-style: italic;
}
:focus:-ms-input-placeholder {
    color: #ccc;
    font-style: italic;
}

You can test the sass code on http://sassmeister.com/

Fabrizio Calderan
  • 120,726
  • 26
  • 164
  • 177