Skip to content

Instantly share code, notes, and snippets.

@demoive
Last active December 17, 2015 16:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save demoive/5641752 to your computer and use it in GitHub Desktop.
Save demoive/5641752 to your computer and use it in GitHub Desktop.
A LESS mixin to generate vendor-specific (browser-specific/experimental) CSS properties.
.vendorify(@prop, @vals...) {
@property: e('@{prop}');
@values: `'@{arguments}'.replace(/^\[|\]$/g, '').split(', ').splice(1)`;
// v1.6.0 added interpolation allowing us to do this:
-o-@{property}: @values;
-ms-@{property}: @values;
-moz-@{property}: @values;
-webkit-@{property}: @values;
@{property}: @values;
/*
// If prior to v1.6.0, use this:
-less-vendorify: ~` ';\n' +
' -o-' + '@{property}: ' + '@{values};\n' +
' -ms-' + '@{property}: ' + '@{values};\n' +
' -moz-' + '@{property}: ' + '@{values};\n' +
' -webkit-' + '@{property}: ' + '@{values};\n' +
' @{property}: ' + '@{values}'`;
*/
}
@demoive
Copy link
Author

demoive commented May 26, 2013

Test cases

Input

@v1:  none;                                        // display
@v2:  "✓";                                         // content
@v3:  ~"none";                                     // display
@v4:  10px;                                        // width
@v5:  1px 2px 3px 4px;                             // padding
@v6:  @v4 5px;                                     // padding
@v7:  1px solid red;                               // border
@v8:  translate(10px, 10px);                       // transform
@v9:  scale(.5) translate(10px, 10px);             // transform
@v10: url("bg1.png");                              // background-image
@v11: url('bg1.png');                              // background-image
@v12: url(bg2.png) repeat, url(bg3.png) no-repeat; // background

.test-empty              { /* at least one param required: .vendorify(); */ }
.test-prop-no-val        { .vendorify(color); }
.test-simple             { .vendorify(display, @v1); }
.test-simple-as-string   { .vendorify(content, @v2); }
.test-simple-escaped     { .vendorify(display, @v3); }
.test-px                 { .vendorify(padding, @v4); }
.test-px-several         { .vendorify(padding, @v5); }
.test-px-nested          { .vendorify(padding, @v6); }
.test-mixed-type         { .vendorify(border, @v7); }
.test-complex            { .vendorify(transform, @v8); }
.test-complex-several    { .vendorify(color, @v9); }
.test-quoted-double      { .vendorify(background-image, @v10); }
.test-quoted-single      { /* singlue quotes not allowed: .vendorify(background-image, @v11); */ }
.test-compound           { .vendorify(background, @v12); }
.test-compound-several   { .vendorify(background, @v10, @v12); }

Output

.test-empty {
  /* at least one param required: .vendorify(); */
}
.test-prop-no-val {
  -o-color: ;
  -ms-color: ;
  -moz-color: ;
  -webkit-color: ;
  color: ;
}
.test-simple {
  -o-display: none;
  -ms-display: none;
  -moz-display: none;
  -webkit-display: none;
  display: none;
}
.test-simple-as-string {
  -o-content: "✓";
  -ms-content: "✓";
  -moz-content: "✓";
  -webkit-content: "✓";
  content: "✓";
}
.test-simple-escaped {
  -o-display: none;
  -ms-display: none;
  -moz-display: none;
  -webkit-display: none;
  display: none;
}
.test-px {
  -o-padding: 10px;
  -ms-padding: 10px;
  -moz-padding: 10px;
  -webkit-padding: 10px;
  padding: 10px;
}
.test-px-several {
  -o-padding: 1px 2px 3px 4px;
  -ms-padding: 1px 2px 3px 4px;
  -moz-padding: 1px 2px 3px 4px;
  -webkit-padding: 1px 2px 3px 4px;
  padding: 1px 2px 3px 4px;
}
.test-px-nested {
  -o-padding: 10px 5px;
  -ms-padding: 10px 5px;
  -moz-padding: 10px 5px;
  -webkit-padding: 10px 5px;
  padding: 10px 5px;
}
.test-mixed-type {
  -o-border: 1px solid #ff0000;
  -ms-border: 1px solid #ff0000;
  -moz-border: 1px solid #ff0000;
  -webkit-border: 1px solid #ff0000;
  border: 1px solid #ff0000;
}
.test-complex {
  -o-transform: translate(10px, 10px);
  -ms-transform: translate(10px, 10px);
  -moz-transform: translate(10px, 10px);
  -webkit-transform: translate(10px, 10px);
  transform: translate(10px, 10px);
}
.test-complex-several {
  -o-color: scale(0.5) translate(10px, 10px);
  -ms-color: scale(0.5) translate(10px, 10px);
  -moz-color: scale(0.5) translate(10px, 10px);
  -webkit-color: scale(0.5) translate(10px, 10px);
  color: scale(0.5) translate(10px, 10px);
}
.test-quoted-double {
  -o-background-image: url("bg1.png");
  -ms-background-image: url("bg1.png");
  -moz-background-image: url("bg1.png");
  -webkit-background-image: url("bg1.png");
  background-image: url("bg1.png");
}
.test-quoted-single {
  /* singlue quotes not allowed: .vendorify(background-image, @v11); */
}
.test-compound {
  -o-background: url(bg2.png) repeat, url(bg3.png) no-repeat;
  -ms-background: url(bg2.png) repeat, url(bg3.png) no-repeat;
  -moz-background: url(bg2.png) repeat, url(bg3.png) no-repeat;
  -webkit-background: url(bg2.png) repeat, url(bg3.png) no-repeat;
  background: url(bg2.png) repeat, url(bg3.png) no-repeat;
}
.test-compound-several {
  -o-background: url("bg1.png"), url(bg2.png) repeat, url(bg3.png) no-repeat;
  -ms-background: url("bg1.png"), url(bg2.png) repeat, url(bg3.png) no-repeat;
  -moz-background: url("bg1.png"), url(bg2.png) repeat, url(bg3.png) no-repeat;
  -webkit-background: url("bg1.png"), url(bg2.png) repeat, url(bg3.png) no-repeat;
  background: url("bg1.png"), url(bg2.png) repeat, url(bg3.png) no-repeat;
}

@theMikeD
Copy link

"A useless (but harmless) -less-vendorify: ; property is included in the style definition"

Why?

@demoive
Copy link
Author

demoive commented May 26, 2013

Because of the way LESS works, we are unable to simply print out the string generated by the JavaScript code without it being "attached" to an existing property. We get around this by creating the bogus -less-vendorify property (it can be anything), and tricking LESS by assigning the remaining properties as the value of this property. However, we insert semicolons and line breaks so that other properties get created as well.

If you know of a way around this, I'm all ears!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment