使用背面可见性“翻转”框时闪烁的背面可见性

Posted

技术标签:

【中文标题】使用背面可见性“翻转”框时闪烁的背面可见性【英文标题】:Flickering back-face visibility when 'flipping' a box using back-face visibility 【发布时间】:2013-12-21 18:38:48 【问题描述】:

我正在使用一个相当简单的 CSS 过渡来创建一个通过同时将两个 div 过渡 180 度来“翻转”的框。当您在盒子的“背面”时,它应该略微透明,以便您可以看到底面。

除了最新的 Safari 7 和 ios 7 之外,我在所有浏览器中都可以轻松完成这项工作。在 Safari 7 上,动画会闪烁,并且背面卡片会在动画结束时“弹出”到前面。

这似乎是在较新的 Safari 上呈现动画的错误。有没有办法让它表现得更好?

查看Chrome和Safari上的动画GIF

在此处查看演示 http://cssdeck.com/labs/flippable-card

【问题讨论】:

到现在我只能想出一个hack involving 2 'back' cards for Safari 7。希望我可以在不引入额外元素的情况下做到这一点。不过,您的演示在我运行 iOS 7 的 iPhone 上运行良好。 无法在 safari 上进行测试,但不久前在 Chrome 中发生了类似的错误。这种情况下的解决方案是在 z .card__back transform: rotateY(180deg) translateZ(1px); 中向后移动 1px背面可见性:隐藏; .card--翻转 .card__back 变换:rotateY(0deg) translateZ(1px); @vals,你想把它作为答案发布吗? 【参考方案1】:

您需要添加两个转换时间,一个用于-webkit-backface-visibility,另一个用于-webkit-transform

如果您尝试将过渡延迟设置为 0 秒,您将立即看到颜色变化,如您所愿。

尝试修改您的转换规则,例如

transition: -webkit-transform 1s ease-in-out, -webkit-backface-visibility 0s ease-in-out;

或仅针对背面可见性覆盖 1 秒过渡。

编辑

不使用看起来有问题的-webkit-backface-visibility,我想我可以使用背卡的display

参见 Demo(在 Safari 7 iOs 7.0.2 和 Mavericks 上测试)

【讨论】:

你能用这个工作发布一个演示吗?我不确定我是否理解你的答案,因为我无法让它工作(让 Safari 7 动画看起来像 Chrome) 抱歉,我确信可以使用这种语法来分隔转换计时器,但我只是发现了 browserstack,但似乎没有。编辑了我的答案 假设他不关心其他属性的动画,只需使用transition: all 1s ease-in-out【参考方案2】:

所以我设法在我当前的 Safari 中复制了这种行为,并认为这很有趣。 这是我想出的: http://codepen.io/anon/pen/usGCL

基本上,从一开始,背面就已经通过-webkit-transform: scaleX(-1); 转过来了。

这样您就不必将其旋转回 0 度。 现在不是前后翻转,您只需将整个容器翻转 180 度,让背面再次出现“正常”。此外,z-index 必须在此过程中更改,这使得 backface-visibility: hidden; 变得多余。我想如果稍微修改一下,你当然可以使用更少的 jQuery。

编辑

Guess Aperçu 的答案也正是您想要的。 不过只是为了好玩:http://codepen.io/BenMann/pen/DmjHv

我同意背面可见性肯定会导致问题。

【讨论】:

+1 用于通过旋转容器来解决此问题。不过我建议稍作改动:将.show-back 类应用于#wrap 并仅使用jQuery 切换它。然后可以使用子/后代选择器将其余样式移动到样式表中,例如.show-back>.back z-index: 2 啊,老回忆,就在 5 年前,这需要 Flash 和几十行 ActionScript! :) 分享爱:] 只有真正有帮助的(2020 年)! transform: scaleX(-1) translateZ(-1px); 并删除 .back 面的 backface-visibility: hidden;。甚至 Chrome 也存在延迟面部翻转后实际渲染的问题。现在可以在 Chrome 和 Safari 中使用。【参考方案3】:

正如问题中提到的,发生了两件事:

1.动画闪烁:这是由于移动浏览器中的点击延迟。基本上,单击事件会在物理地对元素进行标记后 300 毫秒触发。你会想收听touchstart,它会在标签页上立即触发,但在非触摸界面上根本不会触发(Fastclick 是一个很好的 polyfill,它可以消除移动浏览器中的这种点击延迟,但不会影响非触摸式 UI。)

为了这个答案,我只是将我的听众绑定到touchstart而不是click(因此,演示将在触摸设备上查看):

$('.card').on("touchstart", function() 
  $(this).toggleClass('card--flipped');
);

2。后卡在动画结束时“弹出”到前面:经过一些实验,似乎当transformbackface-visibility 都定义在同一个元素上时会发生这种情况。为了解决这个问题,我将backface-visibily 保留在.card__back 上,但将transform: rotateY(180deg) 放在.card__front 上。

因此,.card__front 最初将被翻转,这意味着 .card 也必须最初翻转以弥补这一点。

我们还必须在.card 上定义transform-style: preserve-3d,以便transform 在3D 空间中渲染.card__front.card__back(而不是被展平)。

/* Relevant CSS */

.card 
  transition: all 1s ease-in-out;
  transform-style: preserve-3d;
  transform: rotateY(-180deg);


.card__front 
  transform: scaleX(-1);


.card__back 
  backface-visibility: hidden;


.card--flipped 
  transform: rotateY(0);

移动端演示(在移动端 Safari 或 Chrome 中查看): http://jsbin.com/aMAwezA/15/

DEMO(适用于非触控设备): http://jsbin.com/aMAwezA/16/

编辑: 经过进一步测试,我发现.card__front 上的transform: rotateY(180deg) 导致Chrome 出现一些闪烁。用transform: scaleX(-1) 替换它解决了这个问题。更新了上面的 CSS 和演示链接,它应该可以在移动 Safari 和 Chrome 上运行。

【讨论】:

感谢您的详细回答。这看起来很有趣。我会看看这在我的项目中是如何工作的【参考方案4】:

无法在 safari 上进行测试,但不久前 Chrome 中也发生过类似的错误。

这种情况下的解决方案是在 z 中向后移动 1px

.card__back  
    transform: rotateY(180deg) translateZ(1px); 
    backface-visibility: hidden; 
 

.card--flipped .card__back 
    transform: rotateY(0deg) translateZ(1px); 

这发生在 Chrome 中,因为在制作动画时,会计算空间顺序(我的意思是,元素在 3d 空间中的位置),并且它会覆盖其他因素。

动画结束后,不再使用该计算系统。

正如我之前所说的;无法在 Safari 中测试,所以我可以确定这是一个解决方案。

【讨论】:

您好,这在 Safari 中运行良好,我已经遇到过几次该错误,并且只能将事情稍微远离以避免它,其中 translate() 只是使事情正常工作的方法适当地。 +1 当然 thks 很高兴它有帮助! 还有一点可能会有所帮助,如果您的卡片已放置好(您可能会这样做),请将“正面”卡片上的 z-index 设置为高于“背面”

以上是关于使用背面可见性“翻转”框时闪烁的背面可见性的主要内容,如果未能解决你的问题,请参考以下文章

统一背面剔除使用搅拌机对象移除我的墙外

FliCard 和 ListView Android 中一个奇怪的可见性错误

使用PyQt中的QCheckBox或QComboBox更改小部件可见性

Flutter 中的不可见性、消失、可见性 ROW 和列

可见性原子性有序性

内存可见性问题分析