当透视应用于父元素时,为啥隐藏的背面可见性在 IE10 中不起作用?

Posted

技术标签:

【中文标题】当透视应用于父元素时,为啥隐藏的背面可见性在 IE10 中不起作用?【英文标题】:Why is backface-visibility hidden not working in IE10 when perspective is applied to parent elements?当透视应用于父元素时,为什么隐藏的背面可见性在 IE10 中不起作用? 【发布时间】:2012-09-19 07:14:17 【问题描述】:

好的,这是另一个 IE10 故障。问题是对父元素应用透视会破坏背面可见性隐藏设置。请看这个小提琴:http://jsfiddle.net/2y4eA

当您将鼠标悬停在红色方块上时,它会在 x 轴上旋转 180°,即使将背面可见性设置为隐藏,也会显示背面,至少在达到 180° 之前,它会消失.去掉perspective 属性,你会看到它按预期工作,背面完全不可见,但当然3d 效果丢失了。

可以通过在 transform 属性中应用透视来解决这个问题:http://jsfiddle.net/M2pyb 但是这会导致与 transform-origin-z 结合使用的问题,当 z 设置为 0 以外的任何值时,整个事情都会“缩放” ": http://jsfiddle.net/s4ndv 所以不幸的是这不是一个解决方案。

背面可见性的东西可能是一个错误?如果是这样,除了我提到的之外,还有其他解决方法吗?

【问题讨论】:

您是否尝试过任何经常修复 Internet Explorer 的老式修复程序?我没有玩过 v10,但通常会更改显示模式,确保它具有布局,使用 overflow:hiddenzoom:1z-index:1,添加子级,-基本上任何你能想到的都可能改变使用的渲染功能。 .. 也将backface-visibility 应用到父母呢?似乎 IE 可能会将其视为一个完全独立的 3D 实体。 我以为最晚IE10没有布局概念了?直到现在我还没有尝试过,不幸的是它没有帮助,行为没有改变。对两个元素应用背面可见性也无济于事。 hmm.. 是的,如果他们摆脱了 Layout,我不会感到惊讶,但正如我所说,这些只是猜测,因为我还没有机会坐下来使用 IE10。这很烦人 :/ 像往常一样的旧 Internet Explorer ......虽然它仍在开发中,所以你可能会发现它得到了修复。 是的,我们会看到...我正在使用 RTM 版本 AFAICT,所以我想如果有什么可以修复,然后更新,但因为 IE 现在似乎有一个单独的更新频道,可能的修复可能会更快一点。 您可以通过将背面可见性应用于子对象而不是父对象(应用变换的相同元素)来使其在 IE10 中工作。看看下面的链接,它包含两个 JSfiddles,一个类似于你描述的和一个修改过的,修复了这个问题:***.com/questions/11400317/… 【参考方案1】:

我也遇到了这个故障,这绝对是一个故障。

解决方法是对子元素应用透视变换。我在这里更新了你的小提琴:http://jsfiddle.net/jMe2c/

.item 
    backface-visibility: hidden;
    transform: perspective(200px) rotateX(0deg);

.container:hover .item 
    transform: perspective(200px) rotateX(180deg);

(另请参阅https://***.com/a/14507332/2105930 的回答)

我认为这是因为在 IE 10 中,父元素 3d-properties 不会传播到子元素。这是一个已知的不受支持的功能。查看http://msdn.microsoft.com/en-us/library/ie/hh673529%28v=vs.85%29.aspx#the_ms_transform_style_property:

目前,Internet Explorer 10 不支持 preserve-3d 关键字。除了子元素的正常变换之外,您可以通过手动将父元素的变换应用于每个子元素来解决此问题。

因此,Microsoft 推荐的解决方案是手动传播您的 3d 属性。

【讨论】:

所以我们又见面了,preserve-3d... 不幸的是,这个“解决方法”是我已经发现并在我的问题中提到的。它的问题是非零 z 变换原点通过在 z 轴上缩放或移动项目来破坏它。这似乎是正确的行为,至少其他浏览器的行为相同,但这是我试图解决的问题:) 对不起,我已经更仔细地阅读了您的问题,您似乎已经得出了这个结论。设置非零 z 变换原点 应该 缩放事物 - 正如您所说,这就是它跨浏览器的工作方式。你想创造什么效果? 请注意,过渡不是故障的根源。只需要.container perspective: 200px.item backface-visibility: hidden; transform: rotateX(179deg);,背面可见性就会被忽略。换句话说,对于父元素中的透视,只有 rotateX(180deg) 会导致背面可见性起作用。 “你想创造什么效果?”其实各种效果。我正在构建一个带有 3d 过渡的幻灯片,我一次又一次地偶然发现了这个问题。我已经使用了诸如旋转+翻译之类的解决方法,而不仅仅是旋转+变换-原点,但是这使得动画看起来不同,所以我仍在寻找一种方法来解决/解决这个问题的根源。 所以过了一段时间我又看了一遍,我真的很想知道为什么我花了这么长时间才得到它,应用透视引起的移位可以很容易地通过移动元素来补偿在z轴上-depth/2像素。所以我猜透视函数是一个“解决方法”(即使很难它是problematic in some situations),因此我会将此标记为正确答案,稍后我还将添加我的工作长方体的示例。 【参考方案2】:

我挣扎了好几个小时。这是唯一对我有用的跨浏览器解决方案:http://www.cssplay.co.uk/menu/css3-3d-card.html

【讨论】:

如果您能在此处描述解决方案,而不是仅仅链接到另一个站点,那就太好了。 经过数小时的挫折,我发现这是唯一(真正跨浏览器)的工作方法。 最后,这也确实适用于 IE 10!我也一直在寻找解决方案几个小时。 好东西。有用!为了呼应 Marius,这是我发现的唯一一种在所有浏览器中都能正常工作的方法。旁注:在这里显示答案中的方法会更有帮助,但不要认为我忘恩负义;) 请注意(尤其是@ASGM),此链接唯一解决方案受版权保护,作者有超出***要求的条件才能使用(显示在页面底部)。【参考方案3】:

我想的一种解决方法是为不透明度添加一个时间为 0 且延迟为透视转换一半的转换。

.container, .item 
    width: 200px;
    height: 200px;
    opacity:1;

.container 
    perspective: 200px;

.container:hover .item 
    transform: rotateX(180deg);
    opacity:0;

.item 
    background-color: #ff0000;
    backface-visibility: hidden;
    transition: transform 3000ms, opacity 0ms 1500ms;

【讨论】:

好主意,但不幸的是不是很可靠。当设置为一半的时间时,该项目隐藏得太晚了,并且当使用在正确的时刻隐藏它的值(在这种情况下大约 760 毫秒)时,当项目旋转回来时它会在错误的时刻显示恢复到原来的状态:/ 但您可以更改悬停时的延迟。对于正常状态,它是转换:transform 3000ms,opacity 0ms 760ms 和 .container:hover .item 使其转换:transform 3000ms,opacity 0ms 2200m 或尽可能多的让它看起来不错。 那行不通,必要的延迟取决于转换中的当前位置,即取决于您何时准确翻转/退出延迟需要相应调整(这既不可能也不如果它在哪里可行),因为过渡总是重新开始。【参考方案4】:

我建议停止在所有转换元素上设置透视属性的 IE 并开始测试对 preserve-3d 的支持。我跟着这个人通过属性测试扩展了 Modernizr:https://coderwall.com/p/qctclg?comment=This+was+awesome%21+And+exactly+what+i+needed.+Thanks%21+

这样,它可以为 IE 缺乏 3d 转换的实现做一个后备,并开始在其他浏览器中使用更前沿的可能性。

否则 IE 将使您的代码过于混乱,并且仍然无法为您提供相同的可能性 - 例如旋转多面 3d 对象。

..只是我的 2 美分。

【讨论】:

【参考方案5】:

我有一个很好的不合逻辑的解决方案,我尝试了上述所有解决方案,但都没有奏效。但是,发生了错误。我将卡片翻转时的背面可见性设置为可见。适用于 IE 和 Chrome。

在 Chrome 中效果更好,IE 还可以。

var flipcard = document.getElementsByClassName("flipcard");
var i;

for (i = 0; i < flipcard.length; i++) 
    flipcard[i].addEventListener("click", function() 
        this.classList.toggle("is-flipped");
    );
.card_scene 
    width: 180px;
    height: 234px;
    margin: 10px 5px;
    perspective: 600px;
    float:left;
  

  .flipcard 
    height: 100%;
    transition: transform 1s;
    transform-style: preserve-3d;
    cursor: pointer;
    position: relative; 
  

  .flipcard.is-flipped 
    transform: rotateY(180deg);
  

  .flipcard.is-flipped .card__face 
    backface-visibility: visible;                        


 .card__face 
    position: absolute;
    max-width: 100%;
    max-height: 100%;
    line-height: 234px;
    backface-visibility: hidden;
  
  
 

.card__face--front 
	transform: rotateY(0deg);


.card__face--back 
	background: white;
	transform: rotateY(-180deg);
	border: 1px solid #CCC; 
	width: 100%;


.cardtext 
	margin: 6px;
    font-size:14px;
    line-height: 1.2em;
    display: inline-block;
    width: 100%;
    white-space: pre;


.flipcard-breakfloat 
 clear: left;   
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- start of flipcard tempalte -->
<div class="build-only">
<h2>question text here</h2>
<p>Flip the pictures to...</p>
<div>
<div class="card_scene">
<div class="flipcard">
<div class="card__face card__face--front"><picture class="card__image"><img   id="yui_3_17_2_1_1534724749880_198" src="https://media.gettyimages.com/photos/world-heritage-listed-rainforest-in-dorrigo-national-park-new-south-picture-id936315116" /> </picture></div>
<div class="card__face card__face--back">
<p class="cardtext">** max width of feedback **<br />Add feedback text here use <br />shift+enter for line breaks. <br />don't use just use enter or <br />break will appear below  <br />iamge, and overlay the text. <br />note the class <br />".nsw-td-flipcard-breakfloat" <br />this breaks the float: left so <br /> following text appears <br />as normal <br />Image size is width: <br />"180" height: "234"</p>
</div>
</div>
</div>
<div class="card_scene">
<div class="flipcard">
<div class="card__face card__face--front"><picture class="card__image"> <img    src="https://media.gettyimages.com/photos/lonely-single-tree-in-the-field-picture-id680917092" /> </picture></div>
<div class="card__face card__face--back">
<p class="cardtext">** max width of feedback ** <br />Add feedback text here use <br />shift+enter for line breaks. <br />don't use just use enter or <br />break will appear below  <br />iamge, and overlay the text. <br />note the class <br />".nsw-td-flipcard-breakfloat" <br />this breaks the float: left so <br /> following text appears <br />as normal <br />Image size is width: <br />"180" height: "234"</p>
</div>
</div>
</div>
<div class="card_scene">
<div class="flipcard">
<div class="card__face card__face--front"><picture class="card__image"> <img    src="https://media.gettyimages.com/photos/old-tree-picture-id173501312" /> </picture></div>
<div class="card__face card__face--back">
<p class="cardtext">** max width of feedback ** <br />Add feedback text here use <br />shift+enter for line breaks. <br />don't use just use enter or <br />break will appear below  <br />iamge, and overlay the text. <br />note the class <br />".nsw-td-flipcard-breakfloat" <br />this breaks the float: left so <br /> following text appears <br />as normal <br />Image size is width: <br />"180" height: "234"</p>
</div>
</div>
</div>
</div>
<div class="flipcard-breakfloat"></div>
</div>
<!-- end of flipcard tempalte -->
<p></p>
<p></p>

【讨论】:

【参考方案6】:

我在这个jsfiddle中实现了@torbonaut 和@chowey 提出的解决方案

html

<div id='container'>
<div class='backhide bottom'>bottom</div>
<div class='backhide top'>top</div>
</div>

css

  #container, .bottom, .top 
    width: 200px;
    height: 300px;
    position: absolute;
    -webkit-transition: 1.5s ease-in-out;
    -moz-transition: 1.5s ease-in-out;
    -ms-transition: 1.5s ease-in-out;
    -o-transition: 1.5s ease-in-out;
    transition: 1.5s ease-in-out;
  

  .backhide

    -moz-backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
  

  #container:hover .bottom 
    -moz-transform: perspective(800px) rotateY(0);
    -webkit-transform: perspective(800px) rotateY(0);
    transform: perspective(800px) rotateY(0);
  
  #container:hover .top 
    -webkit-transform: perspective(800px) rotateY(-180deg);
    -moz-transform: perspective(800px) rotateY(-180deg);
    transform: perspective(800px) rotateY(-180deg);
  

  .bottom 
    background-color: #ff0000;
    -moz-transform: perspective(800px) rotateY(180deg);
    -webkit-transform: perspective(800px) rotateY(180deg);
    transform: perspective(800px) rotateY(180deg);
  

  .top 
    background-color: #e0e0e0;


    -moz-transform: perspective(800px) rotateY(0deg);
    -webkit-transform: perspective(800px) rotateY(0deg);
    transform: perspective(800px) rotateY(0deg);

  

【讨论】:

以上是关于当透视应用于父元素时,为啥隐藏的背面可见性在 IE10 中不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

元素背面没有鼠标事件

IE10:“可见性:可见”在“可见性:隐藏”元素的伪元素之前

进度可见性在列表视图页脚中不起作用

C# WPF TextBlock 可见性在 StoryBoard 之后没有改变

怎样在js中控制一个HTML元素的可见与不可见

基于控件可见性在运行时自定义动态布局