How to change background image opacity using CSS

A short CSS trick to change the opacity of background image

Posted on August 21, 2021


When you add a background image to a <div> element, you may want to change the opacity of the image so that the content of the <div> element may stand out and be easier to see.

For example, suppose you have the following HTML body:

<div class="bg-doge">
  <h1 class="color-white">Hello World from the Doge!</h1>
</div>

And then you set the following CSS rule for the bg-doge class (the image used for this example is downloaded from Unsplash):

.bg-doge {
  background-image: url(bg-doge.jpeg);
  background-size: cover;
  height: 600;
  opacity: 0.4;

  /* extra style to center the content */
  /* you can remove them later */
  display: flex;
  align-items: center;
  justify-content: center;
}
.color-white {
  color: #fff;
  background-color: #000;
}

The output of the code above will be as follows:

As you can see, the <h1> element inside the <div> tag gets affected by the opacity property, turning it transparent just like the background image.

This is because the opacity property applies to everything inside the container element. You can’t make the child element less transparent than its parent element.

To solve this issue, you need to place the background image as the child of the <div> tag by using the pseudo-element selector :before.

Take a look at the following CSS syntax:

.bg-doge {
  position: relative;
  height: 600;

  /* extra style to center the content */
  display: flex;
  align-items: center;
  justify-content: center;
}

.bg-doge:before {
  content: "";
  background-image: url(bg-doge.jpeg);
  position: absolute;
  background-size: cover;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  z-index: -1;
  opacity: .6;
}

The pseudo selector :before above is used to create the background image. The absolute position and the top, left, bottom, right values are applied so that the pseudo-element has the same size as its parent.

The z-index of the pseudo-element is set to -1 to position it at the bottom of the order. Without the z-index property, it will be placed on top of other elements, blocking the content from view.

Finally, the .bg-doge position is set to relative so that the pseudo-element is contained inside the <div>.

The output will be as follows:

Now the transparency of the background image won’t be applied to the <div> tag’s content.

Additionally, you can also set the backgroud image to transparent only when the cursor hovers over the element by using the following CSS syntax:

.bg-doge:before {
  content: "";
  background-image: url(bg-doge.jpeg);
  position: absolute;
  background-size: cover;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  z-index: -1;
  opacity: 1;
}

.bg-doge:hover:before {
  opacity: .6;
}

Now the opacity of the background image will be reduced only when the cursor hovers over it:

Feel free to copy the code for your project 😉

See also:

Level up your programming skills

I'm sending out an occasional email with the latest programming tutorials. Drop your email in the box below and I'll send new stuff straight into your inbox!

No spam. Unsubscribe anytime.