Why is @nav-color not getting set...?
@light: #f5f5f5;
@nav-color: #0ff;
@headerbar: #333;
@dark: #222;
@light: #f5f5f5;
.theme() when (lightness(@headerbar) > 50%) {
@nav-color: @dark;
}
.theme() when (lightness(@headerbar) <= 50%) {
@nav-color: @light;
}
.theme();
Once a variable is declared within a namespace or a mixin, it kind of becomes scoped or accessible only within that namespace only and it's value cannot be access outside of the scope.
Reference from Less Website: Note that variables declared within a namespace will be scoped to that namespace only and will not be available outside of the scope via the same syntax that you would use to reference a mixin (#Namespace > .mixin-name
). So, for example, you can't do the following: (#Namespace > @this-will-not-work
).
Solution 1:
One of the options for this particular case would be to use an unnamed namespace (&
) and call the mixin within it like below:
@light: #f5f5f5;
@nav-color: #0ff;
@headerbar: #333;
@dark: #222;
@light: #f5f5f5;
.theme() when (lightness(@headerbar) > 50%) {
@nav-color: @dark;
}
.theme() when (lightness(@headerbar) <= 50%) {
@nav-color: @light;
}
&{
.theme();
div#sample1{
color: @nav-color;
}
div#sample2{
background-color: @nav-color;
}
}
All the following options are courtesy of [seven-phases-max]'s comment and are added to the answer for completeness sake.
Solution 2: Removing the default value for the @nav-color
variable seems to make the code in question work as-is. This should not create any issues because either one of the .theme()
mixin's guard conditions would always be matched and hence the variable would always get a value assigned.
@light: #f5f5f5;
@headerbar: #333;
@dark: #222;
@light: #f5f5f5;
.theme() when (lightness(@headerbar) > 50%) {
@nav-color: @dark;
}
.theme() when (lightness(@headerbar) <= 50%) {
@nav-color: @light;
}
.theme();
div#sample1{
color: @nav-color;
}
Solution 3:
A completely different approach to solve this problem would be to use the built-in contrast()
function mentioned by seven-phases-max in this answer to totally avoid the mixin and set the variable values directly based on the lightness or darkness of another variable.
Additional Information:
To further illustrate the point, the below would work fine (though it is not exactly what you are after) and would output the correct color because the value for the @nav-color
is set within its scope.
.theme() when (lightness(@headerbar) > 50%) {
@nav-color: @dark;
div#sample3{
border-color: @nav-color;
}
}
.theme() when (lightness(@headerbar) <= 50%) {
@nav-color: @light;
div#sample3{
border-color: @nav-color;
}
}