CSS3渐变在悬停时闪烁

4
我正在尝试使用CSS3 Gradient并在鼠标悬停时移动它。从这个jsFiddle可以看出,CSS Gradient出现在:hover上; 但是,它似乎会闪烁几次。
值得一提的是,目前已在Chrome v30/Firefox v24/Safari v5.1上进行了测试。
分开使用它们是有效的解决方案,但是合并使用时会产生闪烁效果。
nav li {
    width: 90px;
    padding-right: 15px;
    padding-left: 15px;
    height: 30px;
    border: 1px solid #000;
    float: left;
    list-style-type: none;

    background-position: -200px -200px;
    -webkit-transition: background 1s ease-out;
    -moz-transition: background 1s ease-out;
    -o-transition: background 1s ease-out;
    transition: background 1s ease-out;
}

nav li:hover {
    background-position: 200px 0;
    background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjIiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzYwNjA2MCIgc3RvcC1vcGFjaXR5PSIwLjIiLz4KICA8L2xpbmVhckdyYWRpZW50PgogIDxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIGZpbGw9InVybCgjZ3JhZC11Y2dnLWdlbmVyYXRlZCkiIC8+Cjwvc3ZnPg==);
    background: -moz-linear-gradient(top,  rgba(255,255,255,0.2) 0%, rgba(96,96,96,0.2) 100%);
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,0.2)), color-stop(100%,rgba(96,96,96,0.2)));
    background: -webkit-linear-gradient(top,  rgba(255,255,255,0.2) 0%,rgba(96,96,96,0.2) 100%);
    background: -o-linear-gradient(top,  rgba(255,255,255,0.2) 0%,rgba(96,96,96,0.2) 100%);
    background: -ms-linear-gradient(top,  rgba(255,255,255,0.2) 0%,rgba(96,96,96,0.2) 100%);
    background: linear-gradient(to bottom,  rgba(255,255,255,0.2) 0%,rgba(96,96,96,0.2) 100%);
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#33ffffff', endColorstr='#33606060',GradientType=0 );
}

我尝试使用animation-iteration-count限制动画,但是我发现这似乎只适用于动画和@keyframes。我还在一些不同的网站上读到了@keyframes还不支持CSS渐变动画。


2
这是一种很酷的效果。如果你想要它,那将会很困难! - Conor Pender
是的,这确实很整洁。但是,这不是我们正在寻找的。我想这是一个愉快的意外。然而,我希望能够在不使用jQuery的情况下使其正常工作。 - davewoodhall
@ConorPender 从Spudley发布的答案中可以看出,这种效果来自于偏移值,它给人一种闪烁的感觉。因此,如果这是一个期望的效果,那么很容易实现。希望这能给你未来的创意带来启发! - davewoodhall
3个回答

5
闪烁的效果是由于元素高度(30px)与您为背景设置的偏移量之间的差异所致(-200px -> 0px)。
基本上,它在一秒的转换中滚动视图六次(因为30可以分成200六次),这就是会出现闪烁效果的原因。如果您将转换时间稍微增加一点,比如设置为5秒,您就可以更容易地看到发生了什么。(当测试完成后,您可以将其设置回来)
如果您将初始的background-position更改为-30px而不是-200px,那么它只会滚动进入视图一次,因此不会有闪烁。
希望能对您有所帮助。

我错过了答案,晚了3分钟 :D - Mr. Alien
看,我想这不是问题,因为我正在使用响应式设计,元素永远不会超过200像素。你的建议完美地解决了问题,但如果我使用百分比(-100%),我的背景会显示出来 - 这正常吗? - davewoodhall
是的 - 背景在某种程度上有些棘手,因为 X% 表示通过图像顶部 X% 的线与元素 X% 通过的线相同。这意味着 0% 对应于“顶部对齐顶部”,50% 表示“中间对齐中间”,100% 表示“底部对齐底部”,其他所有内容都介于两者之间。在这种情况下,由于背景图像与元素大小相同(这就是渐变的工作方式,除非另有明确定义),因此使用什么百分比都无所谓,您将始终获得相同的位置。 - Niet the Dark Absol

4
问题出在background-repeat上。你必须将其设置为no-repeat,这样在悬停之前背景才不会显示。
background-repeat: no-repeat;

JSFiddle


1

如其他答案所述,问题在于background-repeat和您的非常大的背景位置。

这里是一个更新的Fiddle,我相信这就是您想要实现的。

请注意,我已删除了所有冗余的CSS规则 - 所有主要浏览器现在都支持渐变过渡而无需前缀,使得所有这些前缀都没有用(还应该指出的是,-ms-transition-ms-linear-gradient从未存在过,因为IE没有操之过急...你知道在Chrome中至少有三种不同的定义渐变的方法吗?)

除了清理之外,我还将背景定义移到元素的样式中(而不是悬停样式),以确保“向外过渡”,否则它会突然变成空白。我已经应用了background-repeat:repeat-x,只允许水平重复,并调整了background-position,使得在初始状态下,渐变刚好完全超出底部,而悬停状态则处于正确的位置。这产生了一个平滑而精确的过渡。
希望这可以帮助到您!

由于IE11非常新,许多用户尚未升级到此版本。实际上,我的目标受众确实需要旧版本支持(仍有近20%的用户使用IE8或9),因此我仍在使用由Colorzilla(http://www.colorzilla.com/gradient-editor/)生成的脚本。 - davewoodhall
我的Fiddle在IE10中运行良好。使用比IE10更旧版本的人故意忽略Windows更新,所以为什么要浪费时间在他们身上呢?此外,如果他们没有得到漂亮的渐变效果也不是世界末日。 - Niet the Dark Absol
1
只是为了严谨起见,-ms-前缀确实存在,但仅适用于IE10预览版。因此,就所有目的而言,您是正确的,它们并不必要,但说它们从未存在并不完全准确。 - Spudley

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