Background Image Opacity in CSS

The other day I was working on something where I needed to use CSS to apply multiple background images to an element, e.g.

<div>
  My content with background images.
</div>
<style>
  div {
    background-image: 
      url(image-one.jpg),
      url(image-two.jpg);
    background-position:
      top right,
      bottom left;
      /* etc. */
  }
</style>

As I was tweaking the appearance of these images, I found myself wanting to control the opacity of each one.

A voice in my head from circa 2012 chimed in, “Um, remember Jim, there is no background-opacity rule. Can’t be done.” Then that voice started rattling off the alternatives:

Then modern me interrupted this old guy. “I haven’t reached for background-opacity in a long time. Surely there’s a way to do this with more modern CSS?”

So I started searching and found this StackOverflow answer which says you can use background-color in combination with background-blend-mode to achieve a similar effect, e.g.

div {
  /* Use some images */
  background-image: 
      url(image-one.jpg),
      url(image-two.jpg);

  /* Turn down their 'opacity' by blending them into
     the background color */
  background-color: rgba(255,255,255,0.6);
  background-blend-mode: lighten;
}

Worked like a charm! It probably won’t work in every scenario like a dedicated background-image-opacity might, but for my particular use case at that moment in time it was perfect!

I love little moments like this where I reach to do something in CSS that was impossible back when I really cut my teeth on the language, and now there’s a one- or two-line modern solution!

[Sits back and gets existential for a moment.]

We all face moments like this where we have to balance leveraging hard-won expertise with seeking new knowledge and greater understanding, which requires giving up the lessons of previous experience in order to make room for incorporating new lessons of experiences.

It’s hard to give up the old, but it’s the only way to make room for the new — death of the old is birth of the new.

Update 2025-04-08

ShopTalk Show kindly pointed me at “Maybe there kinda is background-opacity?”. Looks like there’s a spec for a cross-fade() function in CSS, though it’s only been implemented by Safari and the time of this writing.

Building off Chris’ CSS-Tricks article linked above, you could do something like this (I put the gif as a custom property, for readability’s sake, not sure you could actually do this):


div {
  /* 1px transparent gif, base64 encoded */
  --transparentImg: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7;
  
  /* 1px transparent gif, base64 encoded */
  background-image:
    /* 1st image */ 
    cross-fade(
      /* my image */
      url(image.jpg),
      /* transparent image */
      url(var(--transparentImg)),
      /* desired 'background opacity' */
      50%
    ),
    
    /* 2nd image */ 
    cross-fade(
      url(image.jpg),
      url(var(--transparentImg)),
      20%
    ),
    
    /* 3rd image, etc. */
   ;
}

Maybe once that ships 4real, we really will have a proxy for background-opacity!