A placeholder mixin - for Less and Scss

I had a tricky predicament at work today - wanting to extend the boss framework with a placeholder styling attribute.

After a lengthy twitter discussion with loads of people (most telling me to move to Scss!) I eventually figured out and solved it!

With my recent love of Coderwall emerging, I wrote it all up on there, but have also included below.


I had a dilema today - I wanted to create a mixin which has variable properties, with Less being our pre-processor of choice, it wasn't as easy as first anticipated.

Edit: I have added the SCSS alternative below

Less #

Styling the placeholder attribute in CSS requires no less that 4 vendor prefixed properties. This can be a pain to try and remember them. I wanted to create a mixin for our less library so that we could style it with a simple class.

However, the problem arose when I wanted to leave the mixin open to be able to pass in whatever I wanted - imagined it working much like a PHP function passing in an array:

.mixin(@styles) {
    a {@styles}
}
section {
    .mixin(color: red; background: blue;);
}

Unfortunately, it didn't work as expected. I reached out for help on twitter and luckily, some friends came to the rescue. After much back and forth, (and with a little bit of help from Joao we came up with this solution:

.colormixin(@color:false) when not (@color=false){color: @color;}
.stylemixin(@style:false) when not (@style=false){
    .style(@style) when (@style=italic) {font-style: @style;}
    .style(@style) when (@style=bold) {font-weight: @style;}
    .style(@style);
}
.placeholder(@color: false, @style: false){
    &::-webkit-input-placeholder {
        .colormixin(@color);
        .stylemixin(@style);
    }
    &:-moz-placeholder {
        .colormixin(@color);
        .stylemixin(@style);
    }
    &::-moz-placeholder {
        .colormixin(@color);
        .stylemixin(@style);
    }
    &:-ms-input-placeholder {
        .colormixin(@color);
        .stylemixin(@style);
    }
}

This allows you to specify a color and then either bold or italic.This can be modified and extended, but for the near-future I can only see these being needed. If you want to just make it bold you can do the following:

input {
    .placeholder(false, bold);
}

You can see it in action on Codepen. Suggestions and changes most welcome!

SCSS #

With the help of Hugo, we've managed to develop the SCSS version of the Mixin:

@mixin placeholder($contents...) {
  $prefixes: ':-webkit' '-moz' ':-moz' '-ms';
  @each $prefix in $prefixes {
    &:#{$prefix}-input-placeholder {
      @each $content in $contents{
        $property: nth($content, 1);
        $value: nth($content, 2);
        #{$property}: unquote($value);
      }
    }
  }
}

With usage being:

input {
  @include placeholder(color red, font-style italic);
}

As with the other one, a Codepen was created to demonstrate the code.

Mike Street

Written by Mike Street

Mike is a front-end developer from Brighton, UK. He spends his time writing, cycling and coding. You can find Mike on Twitter.