Leon
Leon

Reputation: 1881

Change background on element with multiple background images

I have used CSS background on multiple divs to create a number of large format buttons. It looks beautiful, but the buttons are created dynamically, and there could be thousands of them. This means a HUGE dynamic CSS script... it there a better way of giving each element a different CSS background with the same properties?

here is the example code - HTML:

<div id="ab_a" class="banner_button">           
     <h2>Title A</h2>`
</div>

<div id="ab_b" class="banner_button">       
     <h2>Title B</h2>`
</div>

<div id="ab_c" class="banner_button">           
     <h2>Title C</h2>`
</div> 

etc.... (there could be several thousand of these)

The CSS:

#ab_a {
      background: 
    linear-gradient(
      rgba(0, 0, 0, 0.0),
      rgba(0, 0, 0, 0.6)
    ),
    url(../images/bgimageA.jpg);
    background-size: cover;
    width: 100%;
    padding-bottom:37.01%;
    position: relative;
    float: left;
}
#ab_b {
      background: 
    linear-gradient(
      rgba(0, 0, 0, 0.0),
      rgba(0, 0, 0, 0.6)
    ),
    url(../images/bgimageB.jpg);
    background-size: cover;
    width: 100%;
    padding-bottom:37.01%;
    position: relative;
    float: left;
}
#ab_c {
      background: 
    linear-gradient(
      rgba(0, 0, 0, 0.0),
      rgba(0, 0, 0, 0.6)
    ),
    url(../images/bgimageC.jpg);
    background-size: cover;
    width: 100%;
    padding-bottom:37.01%;
    position: relative;
    float: left;
}

...I don't want to have to repeat this block of code 1000's of times in a dynamic CSS file.

How can I separate the background url (the only bit which changes) from the rest of the code?

BTW - Putting just the background url inline within the script will not work, it will ignore all the CSS properties in the stylesheet.

Thanks in advance.

Upvotes: 3

Views: 1627

Answers (1)

Roko C. Buljan
Roko C. Buljan

Reputation: 206593

Using multiple background images on a single element, unfortunately, there's no way using pure CSS to set the second background image in a separate rule without repeating all the previous background layers.

jQuery to the rescue.
jsFiddle demo in action

Inside your CSS set the second background to none:

.banner_button{

    background: linear-gradient(
      rgba(0, 0, 0, 0.0),
      rgba(0, 0, 0, 0.6)
    ), none  50% / cover;  /* notice the `none` for the second layer */

    width: 100%;
    padding-bottom: 37.01%;
    position: relative;
    float: left;
}

while creating your elements, make sure to generate them passing the desired image URL from whatever data you use, >> inside a data-* attribute of your generated element:

<div class="banner_button" data-bg="../images/whatever.jpg"></div>

Than using jQuery, replace that none value with the value holded by the data-bg attribute:

$(".banner_button").css("backgroundImage", function(i, v){
  return v.replace("none", "url("+ $(this).data("bg") +")" );
});

That's it.
jQuery will rebuild the whole background layers for you!

Upvotes: 2

Related Questions