Last active
December 17, 2015 16:49
-
-
Save demoive/5641752 to your computer and use it in GitHub Desktop.
A LESS mixin to generate vendor-specific (browser-specific/experimental) CSS properties.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.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}'`; | |
*/ | |
} |
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;
}
"A useless (but harmless) -less-vendorify: ; property is included in the style definition"
Why?
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
This is an attempt for a simplistic solution to do what is more easily possible in SCSS, but in LESS. Since LESS doesn't support the usage of variables in properties - a.k.a interpolation - (see issue 698 and 36), there have been other solutions, such as this one. However, I have found them to be buggy or unnecessarily complicated.
To avoid creating separate mixins for each property (such as less-mixins or elements), I created this solution. Check out the usage samples below or (try it out yourself).
Things to note
Values with single quotes are not permitted so if a value needs to be quoted, us double quotes
If on version prior to v1.6.0, a useless (but harmless)
-less-vendorify: ;
property is included in the style definitionIt blindly uses the property suffix with all vendor-specific prefixes, so it would not work well for properties where vendors have different suffixes, for example:
or