7

In LESS CSS, is it possible to use a namespaced variable in a call to another mixin or as a default value in another mixin? Using the normal syntax, it appears not, but is there an escape sequence or other syntax I can use to achieve the effect I'm looking for?

I'm thinking of code like this:

#namespace {
    @nsColor: #333;
}

.testMixin1(@mixinColor) {
    background-color: @mixinColor;
}

.selector { .testMixin1(#namespace > @nsColor); } 

Or alternatively...

.testMixin2(@anotherMixinColor: #myNamespace > @myColor) {
    background-color: @anotherMixinColor;
}

If not, this severely limits the utility of namespaces. It's like being able to place a variable in object scope but only being able to pass variables in the global scope as a parameter to a function. Basically this would appear to eliminate 90% of the utility of namespaces.

Nathan Piazza
  • 73
  • 1
  • 3
  • See http://stackoverflow.com/questions/8658270/less-css-syntax-error-when-referencing-variable-from-namespace – Christoph Leiter Oct 28 '12 at 11:22
  • I agree with the sentiment - some of the architectural decisions in less are surprising.. it seems like this would be valuable and (you'd think) super easy to implement considering it's written in a language so meticulous about scope. – jrz Feb 28 '15 at 23:41

1 Answers1

7

New Answer: Expand your Mixin with a Guard Expression Check

So as I understand it, you want the namespace to be able to be used as a default value, but without it entering into the global scope at all. I think you need to expand your mixin definition like so:

#namespace {
    @nsColor: #333;
}


.testMixin1(@mixinColor: 'null') {
    .mixin (@a) when (iscolor(@a)) {
       background-color: @a;
    }
    .mixin (@a) when not (iscolor(@a)) {
       #namespace;
       background-color: @nsColor;
    }
    .mixin (@mixinColor);
}

Then call without or with a value:

.testMixin1();
.testMixin1(red);

Outputs (based on whether you set value or not):

background-color: #333333;
background-color: #ff0000;

OR

You can still use a "getter" mixin in your namespace as I originally noted, like so:

#namespace {
    .getNsColor(){@nsColor: #333;} <-- changed here
}  

.testMixin1(@mixinColor: 'null') {
    .mixin (@a) when (iscolor(@a)) {
       background-color: @a;
    }
    .mixin (@a) when not (iscolor(@a)) {
       #namespace > .getNsColor();  <-- changed here
       background-color: @nsColor;
    }
    .mixin (@mixinColor);
}

Original Answer: Bundle the Variable into a Mixin Itself

If you bundle the variable into a mixin itself, then you can access it. So...

#namespace {
    .getNsColor() {@nsColor: #333;}
}

.testMixin1(@mixinColor) {
    background-color: @mixinColor;
}

Then either include it...

One: Globally

#namespace > .getNsColor;
.selector { 
  .testMixin1(@nsColor); 
}

or Two: Locally

.selector { 
  #namespace > .getNsColor;
  .testMixin1(@nsColor); 
}

Both of which will output...

.selector {
  background-color: #333333;
}
ScottS
  • 71,703
  • 13
  • 126
  • 146
  • This doesn't appear to actually solve the problem. It just re-introduces the same variable names back into global scope, in the former case, and in the latter case it still doesn't allow me to set namespaced variables as my defaults, to be overrriden at the time of method invocation. – Nathan Piazza Oct 30 '12 at 22:30
  • @NathanPiazza--I read this line in your question, "to use a namespaced variable in a call to another mixin," which is what I demonstrated above. However, I did miss the fact that you were also seeking a way to set that as a default in your "or as a default value." Let me think on that. – ScottS Oct 30 '12 at 23:57
  • @NathanPiazza--perhaps my new answer meets your needs. – ScottS Oct 31 '12 at 00:55