Miguel Moura
Miguel Moura

Reputation: 39364

Less > Define variable on constant

I have the following button mixin:

.Button(@type) {

  color: @White; 

  &:hover {color: @White;} // :hover

} // Button

.Button(@type) when (@type = 'Delete') {

  background-color: lighten(@Red, 20%);
  border: 1px solid lighten(@Red, 20%); 

  &:hover {
    background-color: lighten(@Red, 12%);
    border: 1px solid lighten(@Red, 12%); 
  } // :hover

} // Button

.Button(@type) when (@type = 'Search') {

  background-color: lighten(@Blue, 20%);
  border: 1px solid lighten(@Blue, 20%); 

  &:hover {
    background-color: lighten(@Blue, 12%);
    border: 1px solid lighten(@Blue, 12%); 
  } // :hover

} // Button

This is working fine and, as you can see, what changes in each button is the color.

If it possible to have only one Mixin and according to the type define a color variable.

This way I wouldn't need to use so many Button mixin versions ...

Upvotes: 2

Views: 2722

Answers (2)

ScottS
ScottS

Reputation: 72261

Yes, It Can Be Done

It can be folded into a single mixin that uses the @type to switch color values with a creative use of variable variables.

LESS

@White: #fff;
@Red: #f00;
@Blue: #00f;

.Button(@type) {
  //define the variables with the name 
  //of the button you want to pass: Delete, Search, etc.
  //associated to the color variable you desire
  @Delete: @Red;
  @Search: @Blue;
  //set up a generic variable name to use, and
  //then call the color value through a variable variable call (@@)
  @ContrastColor: @@type;

  color: @White;   
  background-color: lighten(@ContrastColor, 20%);
  border: 1px solid lighten(@ContrastColor, 20%); 

  &:hover {
    color: @White;
    background-color: lighten(@ContrastColor, 12%);
    border: 1px solid lighten(@ContrastColor, 12%); 
  } // :hover

} // Button

.deleteClass {
  .Button(Delete);
}

.searchClass {
  .Button(Search);  
}

CSS Output

.deleteClass {
  color: #ffffff;
  background-color: #ff6666;
  border: 1px solid #ff6666;
}
.deleteClass:hover {
  color: #ffffff;
  background-color: #ff3d3d;
  border: 1px solid #ff3d3d;
}
.searchClass {
  color: #ffffff;
  background-color: #6666ff;
  border: 1px solid #6666ff;
}
.searchClass:hover {
  color: #ffffff;
  background-color: #3d3dff;
  border: 1px solid #3d3dff;
}

Upvotes: 2

Aldi Unanto
Aldi Unanto

Reputation: 3682

There is no other way to do that. Guarded mixins in LESS is fixed to you use that format instead of if/else statements. But in your case, I suggest to do this :

//create a mixin for global rules.
.rules(@color){
    background-color: lighten(@color, 20%);
    border: 1px solid lighten(@color, 20%); 

    &:hover {
       background-color: lighten(@color, 12%);
       border: 1px solid lighten(@color, 12%); 
    }
}

And you just only to call .rules mixin to every your css rules.

.Button(@type) when (@type = 'Delete') {
    .rules(@Red);
}

.Button(@type) when (@type = 'Search') {
    .rules(@Blue);
}

This is simpler and no need a lot of space to write the same code. Hope this helps.

Upvotes: 2

Related Questions