在 Uniqlo.com 的设计中,较大的促销框使用了在悬停时显示的动画条纹。如果你问我,这效果相当酷。也许是为了尽可能多地与不同的浏览器共享这种酷炫效果,他们使用了 动画GIF 来实现。它的大小只有4K,但正如我们所知,它也是另一个HTTP请求。让我们以渐进增强的方式重现这种效果:减少浏览器兼容性要求,提高效率。

HTML 代码
我们可以只使用父元素来实现这一点,在:hover
状态下将其背景更改为动画条纹。但是,优衣库上的条纹会淡入,而不是直接出现。不幸的是,我们没有可以使用的background-opacity
属性来帮助我们实现过渡效果。
我们可以使用 ::before 伪元素,并使用不透明度来淡入淡出整个元素,但是 对伪元素过渡效果的支持才刚刚开始变得良好。
就这一次,让我们使用一个额外的元素来处理我们的特殊背景
<div class="product">
<div class="product-hover"></div>
<!-- all the product information and stuff -->
</div>
CSS 代码
.product 类将具有一些内边距,这实际上会显示出动画条纹将出现的粗大的白色边框。
.product {
background: white;
padding: 20px;
position: relative;
}
然后,如果我们将.product-hover
绝对定位到每个角,它的背景就会显示在产品周围的 20px padding
中。默认情况下,我们将opacity
设置为 0,使其不可见。
.product-hover {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0;
}
条纹
现在,要创建那个“旋转灯柱”动画条纹,我们需要使用 45 度线性渐变来创建一个可重复的正方形,最终看起来像条纹。以下是相关的代码。
.product-hover {
background-size: 30px 30px;
background-image: linear-gradient(
45deg,
rgba(black, 0.1) 25%,
transparent 25%,
transparent 50%,
rgba(black, 0.1) 50%,
rgba(black, 0.1) 75%,
transparent 75%,
transparent
);
}
在 Lea Verou 的图案库中也有一些 对角线条纹。代码也更简洁一些,但不要允许背景为白色或透明。
以下是渐变的工作原理

除了 RGBa 值中的“黑色”之外,所有这些都是标准的 CSS,这可以通过 Sass 实现。
那个 30px ✕ 30px 的块是完全可重复的,并将用条纹填充.product-hover
。
显示条纹
它本身就是一个元素,所以非常容易
.product:hover .product-hover {
opacity: 1;
}
但这是一种瞬间显示的效果。为了实现淡入淡出的效果,我们设置了一个 CSS3 过渡。
.product-hover {
transition: opacity 0.3s ease;
}
动画条纹
这里我们需要使用 动画(而不是过渡),因为我们希望条纹无限循环动画。
在.product-hover
上移动背景位置将改变我们的小 30px ✕ 30px 方块的起始位置,从而使其看起来像旋转灯柱一样移动。
@keyframes barberpole {
from { background-position: 0 0; }
to { background-position: 60px 30px; }
}
然后,我们为元素设置该动画,使其以线性方式(无缓动)无限循环。
.product-hover {
animation: barberpole 0.5s linear infinite;
}
演示
搞定!演示 在 CodePen 上查看
Check out this Pen!
使用这种方法模拟 Adobe Photoshop 中的“蚂蚁线”选择效果也很酷!
你不能直接使用
rgba()
值代替background-opacity
吗?对于纯色填充,是的。但我们这里使用的是渐变,渐变内部的各个值无法进行过渡(我认为)。
我一直在渐变中使用 rgba!对我来说效果很好。唯一的缺点是语法突然变得长多了。
对我来说,背景渐变的语法实际上是一行代码
@include background(linear-gradient(black, gray));
Sass 会处理剩下的部分。
——
顺便说一句,上面的声明块来自 Compass 的 Background Image 混合宏。
不需要额外的元素。你只需要做的就是为白色条纹设置动画,并在悬停时将背景从白色过渡到灰色。
看起来你确实丢失了淡入淡出的效果,是吗?
我的过渡效果太突兀了。现在在 Chrome 中,我将过渡时间增加到 1 秒后,它可以很好地淡入了,当然,这可以根据需要进行调整。
令人印象深刻的解决方案,但在现实世界中,我认为我会选择 4K 请求以获得更广泛的支持。
我也很可能这样做,但“现实世界”并不自动意味着“始终追求最广泛的浏览器支持”。我认为声明官方的浏览器目标并基于此做出决策更为合理。即使如此,这仍然取决于你认为这些不同部分的重要性。条纹是最重要的部分吗?还是动画?或者某种纯色回退是否可以接受?也许需要一个基于 Modernizr 的回退?也许 4K 和请求并不重要,或者它可能会超出你的 性能预算,而这种方法很合适。对于前端开发人员来说,这是一个复杂的世界!
干得好,Chris!看到我们无需图像的帮助就能用 CSS 做到什么,总是令人兴奋。
我第一次在你的教程中看到这种效果……它真的很酷,伙计……感谢你为我们付出的辛勤劳动
关于将
.product-hover
定位到所有四个边(left
、top
、right
、bottom
)有一些问题A. 这样做有什么作用?
B. 还有哪些其他示例可以使用这种“四边定位”技术?
谢谢。
它使它与父元素完全相同的大小,假设父元素不是
position: static;
。这通常用于全屏覆盖等内容。我发现
top: 0; left: 0; width: 100%; height: 100%;
稍微“更安全”一点——例如,iframe 只有这样才能正常工作,不会占用右侧/底部。但是,如果你没有使用box-sizing: border-box;
,那么你就有可能遇到 100% 变成 100% + 内边距的情况,这也是一个安全风险(触发滚动条)。嗯,很有意思,Chris。
几年前,我为我的网站创建了一个非常相似的动画 GIF,所以
我继续使用这个案例/问题创建了一个笔,请查看:使position:absolute; top:0; left:0; right:0; bottom:0; 工作。
笔记
• 我使用了
rem
单位而不是px
• 我使用了 Sass + Compass,所以你会看到一些混合宏(没什么特别的)
• “动画”帧始终可见
请告诉我你的想法。
谢谢。
我和Ricardo有同样的问题。所以你的意思是,如果你将所有边距设置为0px(使用position和top/left/right/bottom,而不是margin属性),元素将被“拉伸”并变得与父元素一样宽和高?我的意思是,它甚至没有宽度或高度来显示。这种技术是如何工作的?
@Andrew,查看我上面的帖子。
谢谢Chris!我喜欢这个效果:) 现在在我的网站上使用它(仍在开发中)
你好,为什么不使用
rgba(0,0,0,0.1)
来创建渐变?因为Chris正在使用Sass来创建他的CSS文件,所以像
#000
、#000000
或rgb(0,0,0)
这样的值可以通过声明black
来实现,例如rgba(0,0,0,.5)
=rgba(black,.5)
文章引用:“除了RGBa值中的“black”之外,所有这些都是标准的CSS,这是通过Sass实现的。”
很棒的技巧,Chris!我爱死它了=)
我曾经尝试解决一个更难的问题,想看看你是否可以尝试一下 :)
https://droplr.com/hello + 将文件拖放到放置区域
问题是他们使用了一种我不希望使用的hack…应该有一种更好的方法来做到这一点!
对于那些想知道的人,这仅在IE10中有效。Chris还写了另一篇关于RGBa支持的文章:RGBa支持。很棒的文章,但不能跨浏览器工作,并且需要为IE提供回退方案。话虽如此,学习新东西总是很棒的!干杯&感谢分享。
很棒的作品!
GIF实际上只有1.7k :) — 但在这一点上,HTTP请求更成问题(对于重复访问者来说,可以通过长时间的过期头来缓解)。IE9的支持可能是一个障碍,但假设该页面的性能相同或更好(已经有很多内容了),可以为特定浏览器的实现提出论点。
确实如此!
4KB 可能是 OS X 或其他系统上的“最小文件大小”。
Windows 上也显示 4 KB,如果我错了请纠正我,但 4 KB 是磁盘上的“分配”空间,而不是实际的文件大小。
文件大小确实是 1.697 字节/1.65 KB
:)
你好,Chris,作为在uniqlo.com上实施原始版本开发人员,我必须说做得非常好!不幸的是,优衣库要求它不仅要在Webkit/FF上工作。
我相信这是一个明智的决定!电子商务是一个经典的例子,它表明广泛的浏览器支持是明智且易于证明的。
嗨,Chris。不错的教程!我实际上从未想过这样的事情。它看起来不错,并吸引人们对特定帖子/产品的关注。
感谢你的教程!
Uniqlo.com 是一个有害网站。
F-Secure 的安全报告
http://browsingprotection.f-secure.com/swp/result?url=http%3A%2F%2Fwww.uniqlo.com%2Fus%2F&lang=en
不错的技巧,但我实际上有一种技术,它不使用除图像之外的任何其他元素。
它使用一个内嵌白色阴影,在悬停时从白色过渡到透明。
这是一个 jsFiddle
http://jsfiddle.net/alicelieutier/RDq3a/
非常棒的效果!有没有办法你可以发布纯CSS而不是仅仅是SASS代码?不是每个人,尤其是像我这样的新手都还在使用CSS预处理器…这将不胜感激。
Eric,如果你访问Codepen中的示例,在中间部分的CSS部分,点击顶部标题,标题上写着“CSS (SCSS)”,然后你就会看到“已编译CSS”。
哦,抱歉,忘了说它在剪切粘贴到HTML文件或分成两个文件时不起作用。抱歉,上面的错别字也请见谅…
很棒的教程,Chris,我很想在我的产品网站上应用它。但我有一个问题,这个动画会影响浏览器速度吗?
这看起来像是垃圾邮件,但无论如何,这是我的答案。
任何东西都会影响浏览器速度,从CSS、HTML、JavaScript、图像文件的大小,到标记的数量、被请求的文件(HTTP请求),到CSS文件和图像中的动画/过渡及其速度。
为了保持答案简短,我省略了许多其他内容。
但一个好的经验法则是:谨慎使用所有这些效果,记住“始终关注用户体验”。
@Ricardo Zea:仅仅发布你的网站和一个问题,并不能使其成为垃圾邮件:) 作为一名网页开发人员,我每天都会访问顶级设计网站来学习新知识和技巧。
感谢你的回答。我同意你的观点。用户体验永远是首要的。
不错的教程!有一点:在我的模式库中,repeating-linear-gradient() 版本是如何“不允许背景为白色或透明的”?显然你需要调整颜色,但除此之外,我没有看到任何问题。
你说得对,没问题。我第一次看的时候很困惑,因为它的设置依赖于纯色背景,然后条纹是透明的白色覆盖在上面。
如果将背景设置为白色,则不会显示任何内容。但正如你所说,你可以调整颜色使其成为纯色而不是透明色。也许一个更简单的例子是
http://dabblet.com/gist/5073506
重复渐变的浏览器支持也略微少一些,但不足以构成问题(https://caniuse.cn/#search=gradient)
非常酷的效果!
真的很棒,我想把它作为市场单一的循环
非常棒!
哇,很棒的作品,喜欢这个代码!
非常好,希望CodePen是用纯CSS编写的,这样我们这些还没有决定转向SASS/LESS/SCSS的人就可以使用了。开始感觉我们这些纯CSS开发者被冷落了。:-)
@Chris C,正如我上面对Eric提到的,如果你访问Codepen中的示例,在中间部分的CSS部分,点击顶部标题,标题上写着“CSS (SCSS)”,然后你就会看到已编译CSS。
跑题了——
我不久前还是一个“纯CSSer”,不想被落下,所以我不得不跳上CSS预处理器的列车,今天我无法想象自己不用Sass(以及Compass和Bourbon)编写CSS,并且创建自己的mixin,并且对所有这些东西感到不知所措,哦,天哪)。
这是给Ricardo的,
感谢你的信息。我仍然是一个普通的CSSer,现在才开始学习预处理器。
是的,谢谢Ricardo…我没有意识到我可以这样查看!
如果主要关注的是多一个HTTP请求,可以使用data URI技术。
它会稍微增加大小(而不是1.7kb,而是2.3kb),但它与更多浏览器兼容。
这并不是主要问题,它只是比文件大小更成为一个问题。数据 URI 在理论上是一个很有趣的想法(尤其是在字体方面),但在大型生产站点上,考虑到浏览器支持、维护等因素,我还没有发现它很实用。最终,我认为在这种情况下,最佳方案是 Chris 为支持它的浏览器提供的解决方案,以及其他浏览器使用的现有代码。我们看看它是否会出现在网站上 :)
当你拥有简单的语法时,维护和支持所有浏览器并不难。
这是一个使用图像作为 IE6 和 IE7 备选方案的示例。
将它与 SASS 或 LESS 的 inline-image() 函数一起使用,你就可以获得完整的解决方案。
太棒了。加入潮流!
使用动画 GIF 看起来要明智得多。
我实际上会使用 Flash,这似乎是最明智的。
下载更有效率,渲染不一定更有效率。渐变需要浏览器生成渐变。动画渐变需要浏览器在每一帧都生成渐变。另一方面,图像只解码一次。
参见 Google I/O 演讲“Jank Busters”,https://www.youtube.com/watch?v=x0VR3lUOpdc