How to mix multiple background with LESS

可紊 提交于 2019-12-07 16:59:17

问题


I have a small question... Is there any option to mix multiple background with LESS?

I have this setup for background in LESS:

.background_centered(
  @url,
  @position_horizontal: center,
  @position_vertical: top,
  @background-repeat: no-repeat,
  @transparency: transparent) {
    background: @arguments;
}

now: i need to write in out put style with multiple background, so i do this:

.class {
   .background_centered(url('../img/war_top_baner_gp.png'),url('../img/war_header_bg.png'));
}

something is not right bc in final output i have this:

background: url('/../img/war_top_baner_gp.png') 
            url('/../img/war_header_bg.png') top no-repeat transparent;

what is wrong? Whether or not it is possible to do so?


回答1:


It is challenging in LESS to pass multiple property values to a single property. YOur current code obviously works well for single backgrounds. To get multiple, you have to usually work with strings.

The following allows multiple urls to be input by passing them as a single string to the first parameter, and then uses inline javascript to do a replacement on the string and concatenate those urls to the other parameters.

LESS

.background_centered(
  @urls,   
  @position_horizontal: center,
  @position_vertical: top,
  @background-repeat: no-repeat,
  @transparency: transparent ) {

  @combinedValues: ~"@{position_horizontal} @{position_vertical} @{background-repeat} @{transparency}";
  @urlsRewrite: ~`@{urls}.replace(/\)/g, ') @{combinedValues}')`;
  background: @urlsRewrite;
}

.class {
   .background_centered("url('../img/war_top_baner_gp.png'), url('../img/war_header_bg.png')");
}

Output

.class {
  background: url('../img/war_top_baner_gp.png') center top no-repeat transparent, url('../img/war_header_bg.png') center top no-repeat transparent;
}



回答2:


I am not aware of less natively having a functionality of applying/looping through all arguments of a mixin, but there is a lot of options how to overcome this.

You can add a custom javascript function to the less block that does what you want. Here is a link to a nice reference for custom functions.

But you can also just build a little loop in less:

    // for loop
    .for(@l,@obg,@i:1) when (@l > @i) {
      @nbg: `@{url}[@{i}]`;
      @bg: ~"@{obg}, @{nbg} @{rest}";
      .for(@l, @bg, @i + 1);
    }

    // multiple background urls + additional bg properties
    .bgmixin(@url, @rest){
      @num: unit(`@{url}.length`);
      @bg: ~`@{url}[0]` @rest;
      .for(@num, @bg);
      background: ~"@{bg}";
    }

    // defining bg urls
    @url: 'url("../img/war_top_baner_gp.png")', 'url("../img/war_header_b‌g.png")';

    // including the bgmixin in .class
    .class{
      .bgmixin(@url, center top no-repeat transparent);
    }

And the output is

    .class {
          background: url("../img/war_top_baner_gp.png") center top no-repeat transparent,
                      url("../img/war_header_b‌g.png") center top no-repeat transparent;
    }

If I understood you right this is what you wanted.


Edit: I just wanted to add here that my idea here was to find a more general solution that is actually looping/recursing through array elements, which makes it easy to use different attributes with their respective images - so you feed the function an array of urls and an array of the other attributes. Here I'll try to illustrate the idea:

    .for(@l,@obg,@i:1) when (@l > @i) {
      @nbg: `@{url}[@{i}]`; @nattr: `@{attr}[@{i}]`;;
      @bg: "@{obg}, @{nbg} @{nattr}";
      .for(@l, @bg, @i + 1);
    }

    .bgmixin(@url, @attr){
      @num: unit(`@{url}.length`);
      @bg: ~`@{url}[0]` ~`@{attr}[0]`;
      .for(@num, @bg);
      background: ~"@{bg}";
    }

    @urls: "url('../img/centered_image_bg.png')", "url('../img/left_image_bg.png')";
    @attr: "center top no-repeat transparent", "left top y-repeat";

    .class{
      .bgmixin(@urls, @attr);
    }

and the output will look like this:

    .class {
        background: url('../img/centered_image_bg.png') center top no-repeat transparent,
                    url('../img/left_image_bg.png') left top y-repeat;
    }



回答3:


To pass a list of comma-separated arguments to a mixin, just use ; instead of comma in mixin call:

 .mixin(@bg, @color) {
   background: @bg;
   color: @color;
 }

 .class {
   .mixin(url('img/bg.png') no-repeat, red; white);
 }

outputs:

.class {
  background: url('img/bg.png') no-repeat, #ff0000;
  color: #ffffff;
}



回答4:


You don't need in mixin to glue several backgrounds. You can use native merge function of LESS language.

The merge feature allows for aggregating values from multiple properties into a comma or space separated list under a single property. merge is useful for properties such as background and transform.

So, your less code may look like:

.element {
  background+: url("../1.png") center top no-repeat transparent;
  background+: url("../2.png") left top repeat;
  background+: url("../3.png") right top repeat;
}

This is much simpler than complex mixins.

Generated css:

.element {
  background: url("../1.png") center top no-repeat transparent,
              url("../2.png") left top repeat, 
              url("../3.png") right top repeat;
}


来源:https://stackoverflow.com/questions/15412940/how-to-mix-multiple-background-with-less

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!