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

Css 为什么transform-origin-z在Safari和iOS上会失真?,css,safari,mobile-safari,Css,Safari,Mobile Safari,我一直在使用3D变换构建棱镜旋转效果。transform-origin-z属性似乎最适合变换棱镜的面,但Safari 5和Mobile Safari莫名其妙地拉伸了我的元素,即使没有应用任何变换。Firefox 12和Chrome 18工作正常 我很想了解为什么会发生这种情况。我应该完全避免使用transform-origin-z,还是Safari和Mobile Safari有一些变通方法 <style> /* other browser prefixes omitted f

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

我很想了解为什么会发生这种情况。我应该完全避免使用
transform-origin-z
,还是Safari和Mobile Safari有一些变通方法

<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>​


/*为简洁起见,省略了其他浏览器前缀*/
.集装箱{
利润率:50像素;
边框:2倍实心#00f;
高度:50px;
-webkit透视图:500px;
}
.脸{
高度:50px;
背景色:rgba(255,0,0,0.5);
-webkit转换原点:中心-25px;
-webkit转换:translate3d(0,0,0);
}
​

我相信下面的解释能够回答“为什么”Safari会这样做

我无法访问Safari进行测试,但当我阅读
透视图
属性()的规范时,它指出:

“perspective”属性应用与 perspective()转换函数,但它仅适用于 到元素的已定位或已转换的子元素,而不是到 在元素本身上进行转换


关于我如何阅读上述规范的更新

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

这告诉我,透视变换将被执行,就像在本例中应用了
transform:perspective(500px)
一样

但它仅适用于元素的定位或变换子元素

这告诉我透视变换将应用于子元素,在本例中为
.face
。在这方面,似乎存在一些模糊性。这是否意味着只有在对子元素进行另一次转换时才应应用透视图?而且,
tranform origin
属性是否算作对子级执行的转换(特别是因为该值与
透视图
转换直接相关)?正是在这个模棱两可的时刻,浏览器似乎有所不同。Safari正在进行透视变换,因为子元素将变换原点设置为
-25px
,而其他元素显然没有设置(至少在动画过程中实际的另一个变换对
.face
执行其他操作之前)

而不是元素本身上的转换

这告诉我
.container
z=0
是不相关的,因为此属性的转换不会影响
.container
,而是影响
.container
的子级(即
.face


因此,Safari似乎采取的立场是,您的
.face
始终应用了变换,因为您已将
.container
设置为具有
-webkit透视图:500px
,因此总是有一个
透视图
变换应用于子元素(
.face

请注意,如果拿走动画,并将实际的
变换:透视图(500px)
应用于
,您将使用代码

因此我认为,实际上,Safari可能做得正确,Firefox和Chrome可能不正确。规范有一些模糊性。其他两个浏览器可能仍然应该像Safari那样应用基于
.container
的透视变换,但显然不是这样,而Safari显然是这样

要消除这个问题(不要让它在“静止”时“突出”),您可能需要

  • 在动画开始时设置
    变换原点
    本身的动画(然后重置为
    0
    ),或
  • 当“静止”时,将透视图的
    值本身设置为
    0
    ,当设置动画时,将其设置为
    500px

  • 我的猜测是#1将更容易实现,但我不确定。

    这似乎是Safari中的一个bug。 Chrome将变换中心移动到Z轴上,Safari保留了原来的中心,但将对象本身移动到Z轴上。 因此,该对象在Safari中被放大,看起来更大

    现在我将避免变换原点(在Z轴上),并使用translate-Z来产生相同的效果

    例如:


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

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

    为了确定你的意思:问题是,值中最后一个
    -25px
    实际上是做什么的?不,我理解它是做什么的。我不明白为什么它在Safari中的行为不正确,或者如何修复它<代码>转换原点
    在未应用任何转换时应无效,根据。看到一些css 3d转换存在相同的错误。我以前也遇到过这种情况-我切换到使用translate-z、rotate、translate-z返回序列以确保浏览器之间的一致性,虽然我从来没有得出结论,哪一个浏览器的行为是正确的。我不认为这是正确的。“透视”描述了沿Z轴的平移如何使元素倾斜。如果图元位于
    z=0
    的平面上,则不会产生影响。一个大的“透视图”类似于一个长焦镜头。@Matthew--我想你没有领会我的意思。它不是在
    z=0
    的平面上(我同意你的观点),而是在
    z=-25px
    的平面上,基于
    -webkit transform origin
    上的
    .face
    ,因此父元素的
    透视图
    调用
    500px
    导致
    .face
    基于此进行转换。
    容器
    可能位于
    z=0