I have a page template which has a branding class on the body
element:
<body class="brand-africa">
<h1>Africa</h1>
</body>
Using the following Less, I can use a variable for the brand colour and apply it to the color
of a CSS selector:
@brand-default: #649d84;
@brand-africa: #df6f20;
@brand-nz: #444;
.brand-color {
.brand-default & {
color: @brand-default;
}
.brand-africa & {
color: @brand-africa;
}
.brand-nz & {
color: @brand-nz;
}
}
h1 {
.brand-color;
}
This works well, but sometimes I want to apply the color to another CSS declaration - such as background-color
, and to do this with the above code I'd need to duplicate the .brand-color
mixin to instead apply background-color
.
Ideally I'd like the mixin to return a variable - I know it's possible, but I can't work out how to use the classname to determine the returned value.
Well, no, you can't use class name to determine a variable or a return value. So it's usually done in reverse, for example like this:
@brand-default: #649d84;
@brand-africa: #df6f20;
@brand-nz: #444444;
h1 {
.brand-colors();
}
h2 {
.brand-colors(background-color);
}
.brand-colors(@property: color) {
.color(default);
.color(africa);
.color(nz);
.color(@name) {
.brand-@{name} & {
@value: 'brand-@{name}';
@{property}: @@value;
}
}
}
Or like this:
@brand-default: #649d84;
@brand-africa: #df6f20;
@brand-nz: #444444;
h1 {
.brand-colors({
color: @color;
});
}
h2 {
.brand-colors({
background-color: @color;
});
}
.brand-colors(@style) {
.brand-color(default);
.brand-color(africa);
.brand-color(nz);
}
.brand-color(@name) {
.brand-@{name} & {
@value: ~'brand-@{name}';
@color: @@value;
@style();
}
}
Or even like this:
.brand(default) {@{color}: #649d84}
.brand(africa) {@{color}: #df6f20}
.brand(nz) {@{color}: #444444}
h1 {
.brand-colors();
}
h2 {
.brand-colors(background-color);
}
.brand-colors(@color: color) {
.-(default);
.-(africa);
.-(nz);
.-(@name) {
.brand-@{name} & {
.brand(@name);
}
}
}
Or something in between. Or... oh wait, there's whole family of methods for this stuff (incl. various combinations), see for example:
- https://stackoverflow.com/a/23660124
- How to thematize in lesscss
- https://stackoverflow.com/a/20072967
- etc.
Usually list/array/loop based methods are more compact, though personally I prefer something dumb like this:
.themed({
h1 {
color: @color;
}
h2 {
background-color: @color;
}
});
.themed(@styles) {
.-(default, #649d84);
.-(africa, #df6f20);
.-(nz, #444444);
.-(@name, @color) {
.brand-@{name} {
@styles();
}
}
}