Dynamic multiple CSS backgrounds via JS

Hello there,

I have a twig file that generates on a page basis this kind of html:

<div class="slide">
  <img class="lazy-slide" data-original="my-image.jpg" src="placeholder.gif" alt="copyright & blabla">
</div>

I have a javascript file that checks any .slide img, gets the data-original from the img, hides the img then applies the data-original image to .slide as an inline background-image css property:

// this = the image element
var background = $(this).attr("data-original");

$(this).css({'display':'none'});
$(this).parent().css({'background-image':'url('+ background +')'});

or in plain JS (preferred):

// this = the image element
var background = this.getAttribute('data-original');

this.style.display = 'none';
this.parentElement.style.backgroundImage = 'url("' + background + '")';

which gives:

<div class="slide" style="background-image: url('my-image.jpg')">
  <img style="display:none" class="lazy-slide" data-original="my-image.jpg" src="placeholder.gif" alt="copyright & blabla">
</div>

Now, some of these images are in low resolution and show up as pixelated. Fiddling with the DevTools, I find that combining multiple backgrounds is what I need, in case of having such images (I can check via Twig the image’s sizes):

background: 
    url("my-image") no-repeat 50% 50% / contain, 
    linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.5)),
    url("my-image") no-repeat 50% 50% / cover;

Problems:

  • Those images are dynamic, I can’t create default CSS styles with hardcoded backgrounds, so it needs to be inline
  • Setting this background the CSS way in Javascript outputs this:
<div class="slide" style="background: url('img.jpg') 50% 50% / contain no-repeat, 50% 50% / cover no-repeat">
	<img src="img.jpg" class="" data-original="img.jpg" alt=" " title=" " style="display: none;">
</div>

And the JS code (original code is one-lined in case those \ might annoy the whole thing:

this.parentElement.style.background = url("' + background + '") no-repeat 50% 50% / contain, \ 
linear-gradient(...), \
url("' + background + '") no-repeat 50% 50% / cover';

I don’t know why the second URL doesn’t show up,

I tried setting things up like this:

this....backgroundImage = 'url(' + background + '), url(' + background + ')';
this....backgroundPosition = '50% 50%';
this....backgroundSize = 'contain, cover';
this....backgroundRepeat = 'no-repeat';

But to no avail :frowning:

The result:

<div class="slide" style="background-image: url('img.jpg'); background-position: 50% 50%; background-size: contain, cover; background-repeat: no-repeat;">
	<img src="img.jpg" class="" data-original="img.jpg" alt=" " title=" " style="display: none;">
</div>

What am I missing here? I tried with just setting up a linear-gradient with another background, but that didn’t work neither…

Thank you for your help :slight_smile:

I’m not sure, it works for me…
fiddle

I know it should too, I’ve tested it out directly in the Devtools’ console. Unexplainable thing is why it removes the second url… :frowning:

Here’s the function body as I found it in the theme’s files, in case it may help:

$('.slide img').each({
  if (!$(this).hasClass('lazy') || !$(this).hasClass('lazy') {
    background = $(this).attr("src"); 
    $(this).css({'display':'none'});
    $(this).parent().css({'background-image':'url('+ background +')'});
  }
});

This function is strange too… will have to investigate further

Cheers :slight_smile:

Well, I checked the whole code, and found the culprit function.

It all works by using normal CSS backgrounds declaration

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.