HiveBrain v1.2.0
Get Started
← Back to all entries
snippetcssMinor

How can I reduce this .less call to one line per image

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thiscanimagelinepercallreduceonelesshow

Problem

How can I simplify this .less code to require less repetition (i.e., so that I can have many buttons with normal, rollover, and pressed states without using 3 lines for each button):

.SBtnM(@urlprefix, @width, @height, @urlsuffix) {
        width: @width;
        height: @height;
        background-image: url(%("%s_%s.png", @urlprefix,@urlsuffix));
}

@url1prefix : 'chrome://xtoolbar/skin/img1';
toolbarbutton > .btnCSS1 {.SBtnM(@url1prefix, 42px, 24px,'normal');}
toolbarbutton:hover > .btnCSS1 {.SBtnM(@url1prefix, 42px, 24px, 'rollover');}
toolbarbutton[checked="true"] > .btnCSS1 {.SBtnM(@url1prefix, 42px, 24px, 'pressed');}


Ideally, I would want to be able to use a one-liner to handle all 3 states. E.g., something like this:

.SBtnM(@urlprefix, @width, @height) {
    //Magic Happens.  This part may become more complicated
}

.btnCSS1 {.SBtnM('chrome://xtoolbar/skin/img1', 42px, 24px);}


Output, for reference:

toolbarbutton > .btnCSS1 {
  width: 42px;
  height: 24px;
  background-image: url("chrome://xtoolbar/skin/img1_normal.png");
}
toolbarbutton:hover > .btnCSS1 {
  width: 42px;
  height: 24px;
  background-image: url("chrome://xtoolbar/skin/img1_rollover.png");
}
toolbarbutton[checked="true"] > .btnCSS1 {
  width: 42px;
  height: 24px;
  background-image: url("chrome://xtoolbar/skin/img1_pressed.png");
}


As far as I can tell, .less doesn't have any sort of parent selector for mixins.

Solution

I don't see anything wrong with what you are doing but. it can be written shorter just as you asked.

.SBtnM(@selector, @urlprefix, @width, @height)
{
   .@{selector}
   { 
       .toolbarbutton > &
       {
            @url: %("%s_normal.png", @urlprefix);
            width: @width;
            height: @height;
            background-image:url(@url);
       }
       .toolbarbutton:hover > &
       {
            @url:%("%s_rollover.png", @urlprefix);
            background-image:url(@url);
       }
       .toolbarbutton[checked="true"] > &
       {
             @url:%("%s_pressed.png", @urlprefix);
            background-image:url(@url);
       }
   }
}

.SBtnM(btnCSS1, 'chrome://xtoolbar/skin/img1', 42px, 24px);


For me this produces:

.toolbarbutton > .btnCSS1 {
  width: 42px;
  height: 24px;
  background-image: url("chrome://xtoolbar/skin/img1_normal.png");
}
.toolbarbutton > .btnCSS1 {
  background-image: url("chrome://xtoolbar/skin/img1_rollover.png");
}
.toolbarbutton[checked="true"] > .btnCSS1 {
  background-image: url("chrome://xtoolbar/skin/img1_pressed.png");
}


Works for LESS 1.3.1+ ONLY. For previous versions the syntax is slightly different.

Code Snippets

.SBtnM(@selector, @urlprefix, @width, @height)
{
   .@{selector}
   { 
       .toolbarbutton > &
       {
            @url: %("%s_normal.png", @urlprefix);
            width: @width;
            height: @height;
            background-image:url(@url);
       }
       .toolbarbutton:hover > &
       {
            @url:%("%s_rollover.png", @urlprefix);
            background-image:url(@url);
       }
       .toolbarbutton[checked="true"] > &
       {
             @url:%("%s_pressed.png", @urlprefix);
            background-image:url(@url);
       }
   }
}

.SBtnM(btnCSS1, 'chrome://xtoolbar/skin/img1', 42px, 24px);
.toolbarbutton > .btnCSS1 {
  width: 42px;
  height: 24px;
  background-image: url("chrome://xtoolbar/skin/img1_normal.png");
}
.toolbarbutton > .btnCSS1 {
  background-image: url("chrome://xtoolbar/skin/img1_rollover.png");
}
.toolbarbutton[checked="true"] > .btnCSS1 {
  background-image: url("chrome://xtoolbar/skin/img1_pressed.png");
}

Context

StackExchange Code Review Q#24157, answer score: 2

Revisions (0)

No revisions yet.