How to Change a CSS Background Image’s Opacity

With CSS and CSS3 you can do a lot of things, but setting an opacity on a CSS background is not one of them. However, if you get creative, there are a ton of creative work-arounds you to make it seem like you’re changing the CSS background image’s opacity. Both of the following methods have excellent browser support down to Internet Explorer 8.

Method 1: Use absolute positioning and an image

This method is exactly like it sounds. You simply use absolute positioning on an a normal img tag and make it seem like you used the CSS background-image property. All you have to do is put the image inside of a position: relative; container. Here’s what the HTML markup generally looks like:

<div class="demo_wrap">   <h1>Hello World!</h1>   <img src=""> </div> 

And here’s what your CSS will look like:

.demo_wrap {     position: relative;     overflow: hidden;     padding: 16px;     border: 1px dashed green; } .demo_wrap h1 {     padding: 100px;     position: relative;     z-index: 2; } .demo_wrap img {     position: absolute;     left: 0;     top: 0;     width: 100%;     height: auto;     opacity: 0.6; } 

The trick here is to absolutely position the img and stretch it so it fills the entire parent container. And to relatively position everything else so that you can set a z-index that pulls it above the img.

Here’s a live demo:

Hello World!

Method 2: Using CSS Pseudo-Elements

This method is seems simple once you see it, and is definitely my preferred method of doing this. Using CSS pseudo-elements of either :before or :after, you a div with a background image and set an opacity on it. Here’s what your HTML markup would roughly look like:

<div class="demo_wrap">   <h1>Hello World!</h1> </div> 

And here’s what the CSS looks like:

   .demo_wrap {     position: relative;     background: #5C97FF;     overflow: hidden; } .demo_wrap h1 {     padding: 50px;     position: relative;     z-index: 2; } /* You could use :after - it doesn't really matter */ .demo_wrap:before {     content: ' ';     display: block;     position: absolute;     left: 0;     top: 0;     width: 100%;     height: 100%;     z-index: 1;     opacity: 0.6;     background-image: url('');     background-repeat: no-repeat;     background-position: 50% 0;     background-size: cover; } 

Here again we must move the z-index of content (in this cas the <h1>) above the background pseudoelement, and we must explicitly define the position: absolute; and z-index: 1 on the :before pseudoelement.

The rest of the attributes on the pseudoelement exist to position it to overlap 100% of the parent, and also make use of a clever new CSS property: background-size: cover which sizes the background to cover the element without changing proportions.
Here’s a nice little demo of this method:

Hello World!