captainill
captainill

Reputation: 2089

Can I create my own function to assign a variable with LESS?

I am creating 2 variables in my LESS file

@navSpritePath: '/i/data-board/navigation/navigation-sprite.gif';
@navSpritePath2x: ~`@{navSpritePath}.replace(/\.[\w\?=]+$/, function(match) { return "@2x" + match; })`;

Is there a way to abstract the assignment of @navSpritePath2x so that I just pass the path to perform the function on and return the string?

LESS has its own helper functions for math and color. I would like to create my own so it would look like:

@navSpritePath: '/i/data-board/navigation/navigation-sprite.gif';
@navSpritePath2x: createPath2x(@navSpritePath);

///sudo code - does not work
.createPath2x (@path){
    ~`@{path}.replace(/\.[\w\?=]+$/, function(match) { return "@2x" + match; })`;
}

Upvotes: 2

Views: 8478

Answers (2)

ScottS
ScottS

Reputation: 72261

If you want to be able to change the variable name navSpritePath2x that will receive the assignment, then I do not believe that is possible with LESS.

However, if you simply want to abstract that variable name to a mixin, then it is possible. With such, it could be used like so (as an example):

LESS

@navSpritePathOne: '/i/data-board/navigation/navigation-sprite1.gif';
@navSpritePathTwo: '/i/data-board/navigation/navigation-sprite2.gif';

.createPath2x(@path){
  @navSpritePath2x: `@{path}.replace(/\.[\w\?=]+$/, function(match) { return "@2x" + match; })`;
}

.test {
  background-image: url(@navSpritePathOne);
  .high-density & {
      .createPath2x(@navSpritePathOne);
      background-image: url(@navSpritePath2x);
  } 
}

.test2 {
  background-image: url(@navSpritePathTwo);
  .high-density & {
      .createPath2x(@navSpritePathTwo);
      background-image: url(@navSpritePath2x);
  } 
}

CSS Output

.test {
  background-image: url('/i/data-board/navigation/navigation-sprite1.gif');
}
.high-density .test {
  background-image: url("/i/data-board/navigation/[email protected]");
}
.test2 {
  background-image: url('/i/data-board/navigation/navigation-sprite2.gif');
}
.high-density .test2 {
  background-image: url("/i/data-board/navigation/[email protected]");
}

Of course, if you are always going to use it to just set a similar set of properties (say, related to the background-image), then you might as well put it all into the mixin so you don't have to repeat code:

less LESS

@navSpritePathOne: '/i/data-board/navigation/navigation-sprite1.gif';
@navSpritePathTwo: '/i/data-board/navigation/navigation-sprite2.gif';

.createPath2x(@path){
  background-image: url(@path);
  .high-density & {
     background-image:  `@{path}.replace(/\.[\w\?=]+$/, function(match) { return "@2x" + match; })`;
  }
}

.test {
   .createPath2x(@navSpritePathOne);
}

.test2 {
   .createPath2x(@navSpritePathTwo);
}

CSS Output is exactly the same as shown above with the longer LESS code.

Upvotes: 5

Hai Nguyen
Hai Nguyen

Reputation: 4059

I know this doesn't directly answer your question, but I'd like to share how I accomplished what you're trying to do in my own project. I store all high density images in a /2x folder with the same name. Make sure you change the background size dimensions to match your image.

I hope this helps.

//Variables
@highdensity:       ~"only screen and (-webkit-min-device-pixel-ratio: 1.5)",
                    ~"only screen and (min--moz-device-pixel-ratio: 1.5)",
                    ~"only screen and (-o-min-device-pixel-ratio: 3/2)",
                    ~"only screen and (min-device-pixel-ratio: 1.5)";

@CDNURL:                "cdn.mydomain.com/assets/";
@CDNURL-Retina:         "@{CDNURL}2x/";

//Background image URL Function
.BGImage-HD(@image) {
    background-image: url('http://@{CDNURL}@{image}'); 

  @media @highdensity {
        background-image: url('http://@{CDNURL-Retina}@{image}');
    }
}

//Usage
.navSprite {
    .BGImage-HD("navigation-sprite.gif");

    @media @highdensity {
        .background-size(360px, 240px);
    }
}

Upvotes: 1

Related Questions