CSS3背景图片过渡效果

150

我正在尝试使用CSS过渡效果制作“淡入淡出”效果。但是我无法在背景图片上实现这个效果...

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;
}​

看一下:http://jsfiddle.net/AK3La/

13个回答

114

你可以切换background-image。在 img 元素上使用以下 CSS:

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

这在 Chrome、Opera 和 Safari 中已经得到本地支持。Firefox 还没有实现它 (bugzil.la)。不确定IE是否支持。


151
background-image 不是可动画化的属性(http://www.w3.org/TR/css3-transitions/#animatable-properties),因此你的解决方案不符合标准。 - TLindig
15
这不是一个解决方案——FF和IE不支持它,正如上面所指出的那样,这也不是规范中应该支持的属性。 - Sentinel
4
应该是一个可动画的属性。 - user669677
6
可动画化的属性是background,应该使用它(在我的Chrome中可以工作)。也许规范(或实现)在问题发布后有所更改。 - fps
2
我正在使用这个,可以确认在Chrome和Safari上“background-image”的过渡效果有效。它增添了一些不错的感觉,我希望FF和IE也能实现它。 - Pedroinpeace
显示剩余6条评论

37

我自己找到的解决方案是一个忍者技巧,我可以提供两种方式:

首先,您需要为<img>创建一个“容器”,它将同时包含正常悬停状态:

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

基本上,您需要隐藏“正常”状态,并在悬停时显示其“悬停”状态。

就是这样,我希望有人会发现它有用。


不错的解决方案。在尝试第一个示例时,我注意到如果将过渡持续时间增加到4秒,当z-index在过渡的中间切换时会出现非常明显的跳跃。至少在Chrome 35上,您可以通过将属性值更改为“all 4s ease,z-index 1ms”(http://jsfiddle.net/eD2zL/330/)来改变z-index切换的时间并清除过渡。 - Neal Stublen
2
@NealS. 你说得对。不过这个答案已经两年了,我会移除 z-index,因为它似乎是不必要的。图片只需要按顺序排列即可。 - Ruffo
非常感谢。您的解决方案对我非常有帮助。 - Volodymyr Chumak
如果我使用这个解决方案,是否可以实现“延迟加载”? - Daniel
1
我使用flex网格和无z-index跳跃更新了这个解决方案:https://jsfiddle.net/khsejL5p/ - Cyrille Pontvieux

21

很遗憾,您无法在background-image上使用过渡效果,请查看W3C可动画属性列表

您可能希望对background-position进行一些技巧处理。


好主意! - undefined

17
我已经找到了一个对我有效的解决方案...
如果您有一个列表项(或div)仅包含链接,假设这是用于页面上的社交链接,如facebook、twitter等,并且您正在使用精灵图像,则可以执行以下操作:
<li id="facebook"><a href="facebook.com"></a></li>

使“li”的背景成为您的按钮图像
#facebook {
   width:30px;
   height:30px;
   background:url(images/social) no-repeat 0px 0px;
}

然后将链接的背景图像设置为按钮的悬停状态。还要添加opacity属性,并将其设置为0。
#facebook a {
   display:inline-block;
   background:url(images/social) no-repeat 0px -30px;
   opacity:0;
}

现在你只需要在"a:hover"下添加"opacity",并将其设置为1即可。
#facebook a:hover {
   opacity:1;
}

将透明度过渡属性添加到每个浏览器的“a”和“a:hover”中,以便最终的CSS看起来像这样:
#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;
}

如果我解释得正确,那么这应该让你拥有一个渐变背景图像按钮,希望至少能帮到你!

4
我也制作了一份视频教程的版本。http://www.youtube.com/watch?v=6ieR5ApVpr0 - Austin Parrish Thomas
据我所知,您不需要在悬停伪类上指定转换;锚点标记类型的转换定义将向前传递到悬停行为,您只需要更改不透明度。请记住,此示例之所以有效,是因为样式直接应用于ID /标记类型;如果您使用类执行此操作,则必须确保您未添加和删除已定义转换的类。 - KeithS

16
你可以使用伪元素来实现你想要的效果,就像我在那个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>

2
这个方法很好,但你可能会遇到两个问题:1)如果你看不到:after元素,请尝试将widthheight设置为100%而不是inherit;2)如果background-image实际上显示在前景中,请为:after元素使用负索引:z-index: -1; - Radek Pech

11

考虑到背景图片无法实现动画效果,我创建了一个小的 SCSS mixin,允许使用伪选择器 :before:after 在不同的 z-index 层之间过渡 2 种不同的背景图片。前面的那个从 opacity 0 开始,并在悬停时变得可见。

您也可以使用相同的方法来创建线性渐变动画。

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; 
     }
  }  
}

现在您可以简单地使用它,只需:

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

您可以在此处查看: https://jsfiddle.net/pablosgpacheco/01rmg0qL/

非常好的解决方案!作为额外的奖励,让我更好地理解如何充分利用元素状态 ':before' 和 ':after'。 - joronimo

10
如果您能使用jQuery,可以尝试使用BgSwitcher插件来切换背景图片并添加特效,非常容易使用。
例如:
$('.bgSwitch').bgswitcher({
        images: ["style/img/bg0.jpg","style/img/bg1.jpg","style/img/bg2.jpg"],
        effect: "fade",
        interval: 10000
});

并添加自己的效果,参见添加效果类型


谢谢,我使用这个插件解决了表格背景变化动画的问题。 - userlond

8
尝试这个,可以使网页中的背景动画正常工作,但在混合移动应用程序中无效。
@-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;
}

3
如果无法使用动画opacity,您也可以使用动画background-size
例如,我使用此CSS设置带有延迟的background-image
.before {
  background-size: 0;
}

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

如果你想要从.after淡出到.before的背景图像具有淡出效果,你必须将背景图像设置到.before中。否则它将没有动画地消失。 - Radek Pech

3
“Salam”,这个答案只适用于Chrome浏览器,因为IE和FF不支持颜色转换。
没有必要将HTML元素设为opacity:0,因为它们有时包含文本,也不需要复制元素!
与jsfiddle中示例的链接相关的问题需要做出小改变,即在.title a中放置一个空图像,如background:url(链接到空图像);,并且与你在.title a:hover中放置的一样,但是让它成为空白图像,那么代码就可以正常工作了。
.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;
}

请查看此链接:https://jsfiddle.net/Tobasi/vv8q9hum/

仍然无法在火狐或IE上工作 :(,但在Chrome中看起来很好。 - mohammed Suleiman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接