Advance mixin with Less && SCSS- Variable attributes

I had a dilemma 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 than 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.