CSS3 background image transition

CssBackgroundBackground ImageCss Transitions

Css Problem Overview


I'm trying to make a "fade-in fade-out" effect using the CSS transition. But I can't get this to work with the background image...

The CSS:

.title a {
    display: block;
    width: 340px;
    height: 338px;
    color: black;
    background: transparent;
    /* TRANSITION */
    -webkit-transition: background 1s;
    -moz-transition: background 1s;
    -o-transition: background 1s;
    transition: background 1s;
}

.title a:hover {
    background: transparent;
    background: url(https://lh3.googleusercontent.com/-p1nr1fkWKUo/T0zUp5CLO3I/AAAAAAAAAWg/jDiQ0cUBuKA/s800/red-pattern.png) repeat;
    /* TRANSITION */
    -webkit-transition: background 1s;
    -moz-transition: background 1s;
    -o-transition: background 1s;
    transition: background 1s;
}​

Take a look: http://jsfiddle.net/AK3La/

Css Solutions


Solution 1 - Css

You can transition background-image. Use the CSS below on the img element:

-webkit-transition: background-image 0.2s ease-in-out;
transition: background-image 0.2s ease-in-out;

This is supported natively by Chrome, Opera and Safari. Firefox hasn't implemented it yet (bugzil.la). Not sure about IE.

Solution 2 - Css

The solution (that I found by myself) is a ninja trick, I can offer you two ways:

first you need to make a "container" for the <img>, it will contain normal and hover states at the same time:

<div class="images-container">
    <img src="http://lorempixel.com/400/200/animals/9/">
    <img src="http://lorempixel.com/400/200/animals/10/">
</div>

Basically, you need to hide "normal" state and show their "hover" when you hover it

and that's it, I hope somebody find it useful.

Solution 3 - Css

Unfortunately you can't use transition on background-image, see the w3c list of animatable properties.

You may want to do some tricks with background-position.

Solution 4 - Css

I've figured out a solution that worked for me...

If you have a list item (or div) containing only the link, and let's say this is for social links on your page to facebook, twitter, ect. and you're using a sprite image you can do this:

<li id="facebook"><a href="facebook.com"></a></li>

Make the "li"s background your button image

#facebook {
   width:30px;
   height:30px;
   background:url(images/social) no-repeat 0px 0px;
}

Then make the link's background image the hover state of the button. Also add the opacity attribute to this and set it to 0.

#facebook a {
   display:inline-block;
   background:url(images/social) no-repeat 0px -30px;
   opacity:0;
}

Now all you need is "opacity" under "a:hover" and set this to 1.

#facebook a:hover {
   opacity:1;
}

Add the opacity transition attributes for each browser to "a" and "a:hover" so the the final css will look something like this:

#facebook {
   width:30px;
   height:30px;
   background:url(images/social) no-repeat 0px 0px;
}
#facebook a {
   display:inline-block;
   background:url(images/social) no-repeat 0px -30px;
   opacity:0;
   -webkit-transition: opacity 200ms linear;
   -moz-transition: opacity 200ms linear;
   -o-transition: opacity 200ms linear;
   -ms-transition: opacity 200ms linear;
   transition: opacity 200ms linear;
}
#facebook a:hover {
   opacity:1;
   -webkit-transition: opacity 200ms linear;
   -moz-transition: opacity 200ms linear;
   -o-transition: opacity 200ms linear;
   -ms-transition: opacity 200ms linear;
   transition: opacity 200ms linear;
}

If I explained it correctly that should let you have a fading background image button, hope it helps at least!

Solution 5 - Css

You can use pseudo element to get the effect you want like I did in that Fiddle.

CSS:

.title a {
    display: block;
    width: 340px;
    height: 338px;
    color: black;
    position: relative;
}
.title a:after {
    background: url(https://lh3.googleusercontent.com/-p1nr1fkWKUo/T0zUp5CLO3I/AAAAAAAAAWg/jDiQ0cUBuKA/s800/red-pattern.png) repeat;
    content: "";
    opacity: 0;
    width: inherit;
    height: inherit;
    position: absolute;
    top: 0;
    left: 0;
    /* TRANSISITION */
    transition: opacity 1s ease-in-out;
    -webkit-transition: opacity 1s ease-in-out;
    -moz-transition: opacity 1s ease-in-out;
    -o-transition: opacity 1s ease-in-out;
}
.title a:hover:after{   
    opacity: 1;
}

HTML:

<div class="title">
    <a href="#">HYPERLINK</a>
</div>

Solution 6 - Css

If you can use jQuery, you can try BgSwitcher plugin to switch the background-image with effects, it's very easy to use.

For example :

$('.bgSwitch').bgswitcher({
        images: ["style/img/bg0.jpg","style/img/bg1.jpg","style/img/bg2.jpg"],
        effect: "fade",
        interval: 10000
});

And add your own effect, see adding an effect types

Solution 7 - Css

Try this, will make the background animated worked on web but hybrid mobile app not working

@-webkit-keyframes breath {
 0%   {  background-size: 110% auto; }
 50%  {  background-size: 140% auto; }
 100% {  background-size: 110% auto; }      
}
body {
   -webkit-animation: breath 15s linear infinite;
   background-image: url(images/login.png);
    background-size: cover;
}

Solution 8 - Css

Considering background-images can't be animated, I created a little SCSS mixin allowing to transition between 2 different background-images using pseudo selectors before and after. They are at different z-index layers. The one that is ahead starts with opacity 0 and becomes visible with hover.

You can use it the same approach for creating animations with linear-gradients too.

scss

@mixin bkg-img-transition( $bkg1, $bkg2, $transTime:0.5s ){  
  position: relative;  
  z-index: 100; 
  &:before, &:after {
    background-size: cover;  
    content: '';    
    display: block;
    height: 100%;
    position: absolute;
    top: 0; left: 0;    
    width: 100%;    
    transition: opacity $transTime;
  }
  &:before {    
    z-index: -101;
    background-image: url("#{$bkg1}");    
  }
  &:after {    
    z-index: -100;
    opacity: 0;
    background-image: url("#{$bkg2}");    
  }
  &:hover {
     &:after{
       opacity: 1; 
     }
  }  
}

Now you can simply use it with

@include bkg-img-transition("https://picsum.photos/300/300/?random","https://picsum.photos/g/300/300");

You can check it out here: https://jsfiddle.net/pablosgpacheco/01rmg0qL/

Solution 9 - Css

If animating opacity is not an option, you can also animate background-size.

For example, I used this CSS to set a backgound-image with a delay.

.before {
  background-size: 0;
}

.after {
  transition: background 0.1s step-end;
  background-image: $path-to-image;
  background-size: 20px 20px;
}

Solution 10 - Css

Salam, this answer works only in Chrome, cause IE and FF support color transition.

There is no need to make your HTML elements opacity:0, cause some times they contain text, and no need to double your elements!.

The question with link to an example in jsfiddle needed a small change, that is to put an empty image in .title a like background:url(link to an empty image); same as you put it in .title a:hover but make it empty image, and the code will work.

.title a {
display: block;
width: 340px;
height: 338px;
color: black;
background: url(https://upload.wikimedia.org/wikipedia/commons/5/59/Empty.png) repeat;
/* TRANSISITION */
transition: background 1s;
-webkit-transition: background 1s;
-moz-transition: background 1s;
-o-transition: background 1s;
  }
  .title a:hover{   background: transparent;
   background: url(https://lh3.googleusercontent.com/-p1nr1fkWKUo/T0zUp5CLO3I/AAAAAAAAAWg/jDiQ0cUBuKA/s800/red-pattern.png) repeat;
/* TRANSISITION */
transition: background 1s;
-webkit-transition: background 1s;
-moz-transition: background 1s;
-o-transition: background 1s;
}

Check this out https://jsfiddle.net/Tobasi/vv8q9hum/

Solution 11 - Css

With Chris's inspiring post here:

https://css-tricks.com/different-transitions-for-hover-on-hover-off/

I managed to come up with this:

#banner
{
	display:block;
	width:100%;
	background-repeat:no-repeat;
	background-position:center bottom;
	background-image:url(../images/image1.jpg);
    /* HOVER OFF */
	@include transition(background-image 0.5s ease-in-out);	
	
	&:hover
	{
		background-image:url(../images/image2.jpg);
        /* HOVER ON */
		@include transition(background-image 0.5s ease-in-out); 
	}
}

Solution 12 - Css

This can be achieved with greater cross-browser support than the accepted answer by using pseudo-elements as exemplified by this answer: https://stackoverflow.com/a/19818268/2602816

Solution 13 - Css

I was struggling with this for a bit, I first used a stack of images on top of each other and every three seconds, I was trying to animate to the next image in the stack and throwing the current image to the bottom of the stack. At the same time I was using animations as shown above. I couldn't get it to work for the life of me.

You can use this library which allows for **dynamically-resized, slideshow-capable background image ** using jquery-backstretch.

https://github.com/jquery-backstretch/jquery-backstretch

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNick ZaniView Question on Stackoverflow
Solution 1 - CssHengjieView Answer on Stackoverflow
Solution 2 - CssRuffoView Answer on Stackoverflow
Solution 3 - CssOlwaroView Answer on Stackoverflow
Solution 4 - CssAustin Parrish ThomasView Answer on Stackoverflow
Solution 5 - CssMaxCloutierView Answer on Stackoverflow
Solution 6 - CssMaxDhnView Answer on Stackoverflow
Solution 7 - CssHesham NasserView Answer on Stackoverflow
Solution 8 - CssPablo S G PachecoView Answer on Stackoverflow
Solution 9 - Cssshock_oneView Answer on Stackoverflow
Solution 10 - Cssmohammed SuleimanView Answer on Stackoverflow
Solution 11 - CssCarol McKayView Answer on Stackoverflow
Solution 12 - Cssvaer-kView Answer on Stackoverflow
Solution 13 - CssAkhil KhannaView Answer on Stackoverflow