为什么transform-origin-z会在Safari,iOS上失真?

时间:2012-04-26 18:54:28

标签: css css3 safari mobile-safari

我一直在使用3D变换构建棱镜旋转效果。 transform-origin-z属性似乎最适合转换棱镜的面,但Safari 5和Mobile Safari莫名其妙地拉伸了我的元素,即使没有应用变换。 Firefox 12和Chrome 18正常工作。

Live Demo

Full Prism Demo

我很想知道为什么会这样。我应该完全避免transform-origin-z,还是Safari和Mobile Safari有一些解决方法?

Screen shot

<style>
  /* other browser prefixes omitted for brevity */
  .container {
    margin: 50px;
    border: 2px solid #00f;
    height: 50px;
    -webkit-perspective: 500px;
  }
  .face {
    height: 50px;
    background-color: rgba(255,0,0,0.5);
    -webkit-transform-origin: center center -25px;
    -webkit-transform: translate3d(0,0,0);
  }
</style>

<div class="container">
  <div class="face"></div>
</div>​

3 个答案:

答案 0 :(得分:12)

似乎这是Safari中的一个错误。 Chrome在Z轴上移动变换中心,Safari离开了这个中心,但是将对象本身移动到Z轴上。 因此,对象在Safari中放大,看起来更大。

我现在要避免使用transform-origin(在Z轴上)并使用translate-Z来产生相同的效果。

示例:

http://jsfiddle.net/willemvb/GuhcC/3/

答案 1 :(得分:2)

我相信以下解释回答了“为什么”Safari正在做的事情

我无法访问Safari进行测试,但在阅读perspective属性(the same spec page you point to)的规范时,它指出:

  

'perspective'属性应用与之相同的变换   perspective()转换函数,但它仅适用   对元素的定位或转化的孩子,而不是对   转换元素本身。


更新我如何阅读上述规范

  

'perspective'属性应用与perspective()转换函数相同的转换

这告诉我一个透视转换就像在这种情况下应用transform: perspective(500px)一样。

  

除了它仅适用于元素的定位或转换子元素

这告诉我透视变换将应用于子元素,在本例中为.face。这里似乎有些含糊不清。这是说只有在子元素上进行另一个转换时才应该应用透视吗?并且,tranform-origin属性是否计为对子进行的变换(特别是因为这个值与perspective变换直接相关)? 正是在这一点上,浏览器似乎有所不同。 Safari正在进行perspective转换,因为子元素的tranform-origin设置为-25px,而其他人显然不是(至少,直到实际的其他人transform在动画期间对.face做了其他事情)。

  

不要对元素本身进行转换

这告诉我z=0的{​​{1}}无关紧要,因为此属性的转换不会影响.container,而是影响.container的孩子(即{{} 1}})。


因此,Safari似乎采取了.container 始终应用转换的立场,因为您已将.face设置为.face,因此始终将.container转换应用于子元素(在您的情况下为-webkit-perspective: 500px;)。

请注意,如果您取消动画,并将实际perspective应用于.face,您将see the same result in Firefox or Chrome as what you experience in Safari包含您的代码。

所以我认为实际上, Safari可能正确地执行,而Firefox和Chrome可能不是。规范有些含糊不清。其他两个浏览器可能应该像Safari一样应用基于transform: perspective(500px)的透视变换,但肯定看起来不是,而Safari显然似乎是。

要消除这个问题(在“休息时”没有“坚持”),你可能需要

  1. 动画开头为.face本身设置动画(之后重置为.container), ......
  2. 在“静止”时将transform-origin值本身设为0,在设置动画时为perspective设置动画。
  3. 我的猜测#1会更容易实现,但我不确定。

答案 2 :(得分:0)

我不知道为什么这对我有用。似乎适用于所有浏览器。基本上我认为我取消了css声明效果。

.container {
   perspective: 500px;
   transform-origin: 50% 50% 25px;
}