【问题标题】:Why does transform-origin-z distort on Safari, iOS?为什么 transform-origin-z 在 Safari、iOS 上会变形?
【发布时间】:2016-07-25 18:11:53
【问题描述】:

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

Live Demo

Full Prism Demo

我有兴趣了解为什么会发生这种情况。我应该完全避免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>​

【问题讨论】:

  • 只是为了确定您的意思:问题是,值中的最后一个 -25px 实际作用是什么?
  • 不,我明白它的作用。我不明白为什么它在 Safari 中的行为不正确或如何修复它。根据the spectransform-origin 在未应用任何转换时应该无效。
  • 在一些 css 3d 转换中看到相同的错误。
  • 我之前也遇到过这个问题——我切换到使用 translate-z、rotate、translate-z 后退序列来确保浏览器之间的一致性,尽管我从未得出关于哪个浏览器的行为是正确。

标签: css safari mobile-safari


【解决方案1】:

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

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

例子:

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

【讨论】:

  • 我遇到了同样的问题。你的例子帮助了我很多。谢谢。
【解决方案2】:

我相信以下解释可以回答“为什么”Safari 正在这样做

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

“透视”属性应用与 perspective() 变换函数,除了它只适用 到元素的定位或转换的子元素,而不是 对元素本身进行变换。


更新我如何阅读上述规范

‘perspective’属性应用与perspective()变换函数相同的变换

这告诉我将进行透视变换,就像在这种情况下应用 transform: perspective(500px) 一样。

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

这告诉我透视变换将应用于子元素,在本例中为.face。在这里,似乎有些模棱两可。这是说只有在对子元素进行了另一次变换时才应应用透视图?而且,tranform-origin 属性是否算作对孩子进行的转换(特别是因为该值与perspective 转换直接相关)? 正是在这个模棱两可的地方,浏览器似乎有所不同。 Safari 正在执行perspective 转换,因为子元素将tranform-origin 设置为-25px,而其他元素显然不是(至少,直到实际的其他transform 在动画期间对.face 执行其他操作)。

不要对元素本身进行变换

这告诉我.containerz=0 无关紧要,因为来自此属性的转换不会影响.container,而是影响.container 的孩子(即.face)。


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

请注意,如果您删除动画,并将实际的transform: perspective(500px) 应用于.face,您将使用您的代码see the same result in Firefox or Chrome as what you experience in Safari

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

要消除问题(在“休息”时不会“突出”),您可能需要

  1. 在动画开始时为 transform-origin 本身设置动画(然后重置为 0),...
  2. perspective 值设置为“静止”时的 0 和设置动画时的 500px

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

【讨论】:

  • 我不这么认为。 “透视”描述了沿 Z 轴的平移如何使元素倾斜。如果元素位于z = 0 所在的平面上,它应该没有影响。大的“视角”类似于长焦镜头。
  • @Matthew--我想你没抓住我的意思。它不是位于z=0 的平面上(我同意你的观点),它基于-webkit-transform-origin 上的.face 位于z=-25px 的平面上,所以父元素的perspective 调用@987654357 @ 导致 .face 基于此进行转换。 container 可能位于 z=0perspective 不影响 container 但容器的子项根据规范。并且孩子有一个非零的z 值。
  • @Matthew--关于规范(以及可能是浏览器差异的原因)对我来说有点模棱两可的是 perspective 是否应该仅在存在另一个转换时才适用,或者如果它实际上应该对子元素执行 perspective 变换,如果除了 z 移位之外没有其他变换。
  • @Matthew--另一件事,你有没有看我的第二个小提琴链接,它复制了你在 Firefox 的 Webkit 中看到的相同内容(通过在 .face 上显式设置 perspective 转换) ?
  • @Matthew--我在我的回答中添加了一个更新,基本上总结了我刚刚在上面的 cmets 中写的内容,并且还强调了(粗体)在 Firefox 中重现效果的第二个小提琴链接。
【解决方案3】:

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

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

【讨论】:

  • 这让我摆脱了数小时的沮丧
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-02
  • 2011-03-18
  • 1970-01-01
  • 2020-03-10
  • 2021-07-07
  • 2019-12-30
  • 2015-03-25
相关资源
最近更新 更多