Safari动画(关键帧和变换)设置错误位置。

6
我在Safari上遇到了一个奇怪的问题(很奇怪吗?哈哈)。无论您使用iPhone、iPad还是桌面Mac,Safari都会在使用动画关键帧和变换时进行错误的计算来定位一个标志。
问题是标志需要移动到它的位置,但在Safari上,标志向左移动过多,当关键帧达到100%时,标志恰好适合它的位置。
您可以在以下网址上看到这个奇怪的效果:https://amonarraiz.com(在Safari上的访问与在其他浏览器上的访问不同,但代码相同)。
以下是我的代码:

.intro-wrapper {
  position: fixed;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
}
.intro-logo {
  background: url(https://amonarraiz.com/css/img/slider/2.png) center center no-repeat;
  background-size: cover;
  width: 50rem;
  height: 41rem;
  position: absolute;
  left: 50%;
  top: 50%;
  -ms-transform: translate(-86%, -52%);
  -webkit-transform: translate(-86%, -52%);
  transform: translate(-86%, -52%);
  opacity: 0;
  cursor: pointer;
}

.intro-in {
  -moz-animation-duration: 3.75s;
  -webkit-animation-duration: 3.75s;
  animation-duration: 3.75s;
  -moz-animation-name: intro-in;
  -webkit-animation-name: intro-in;
  animation-name: intro-in;
  -moz-animation-iteration-count: 1;
  -webkit-animation-iteration-count: 1;
  animation-iteration-count: 1;
  -moz-animation-fill-mode: forwards;
  -webkit-animation-fill-mode: forwards;
  animation-fill-mode: forwards;
  -webkit-animation-timing-function: ease-in-out;
  -moz-animation-timing-function: ease-in-out;
  animation-timing-function: ease-in-out;
}
@-moz-keyframes intro-in {
  0% {
    opacity: 0.6;
    width: 50rem;
    height: 41rem;
    -ms-transform: translate(-50%, -50%);
    -webkit-transform: translate(-50%, -50%);
    transform: translate(-50%, -50%);
  }
  30% {
    opacity: 1;
    width: 50rem;
    height: 41rem;
    -ms-transform: translate(-50%, -50%);
    -webkit-transform: translate(-50%, -50%);
    transform: translate(-50%, -50%);
  }

  100% {
    opacity: 1;
    width: 25.6rem;
    height: 19.5rem;
    -ms-transform: translate(-106%, -46%);
    -webkit-transform: translate(-106%, -46%);
    transform: translate(-106%, -46%);
  }
}

@-webkit-keyframes intro-in {
  0% {
    opacity: 0.6;
    width: 50rem;
    height: 41rem;
    -ms-transform: translate(-50%, -50%);
    -webkit-transform: translate(-50%, -50%);
    transform: translate(-50%, -50%);
  }
  30% {
    opacity: 1;
    width: 50rem;
    height: 41rem;
    -ms-transform: translate(-50%, -50%);
    -webkit-transform: translate(-50%, -50%);
    transform: translate(-50%, -50%);
  }

  100% {
    opacity: 1;
    width: 25.6rem;
    height: 19.5rem;
    -ms-transform: translate(-106%, -46%);
    -webkit-transform: translate(-106%, -46%);
    transform: translate(-106%, -46%);
  }
}

@keyframes intro-in {
  0% {
    opacity: 0.6;
    width: 50rem;
    height: 41rem;
    -ms-transform: translate(-50%, -50%);
    -webkit-transform: translate(-50%, -50%);
    transform: translate(-50%, -50%);
  }
  30% {
    opacity: 1;
    width: 50rem;
    height: 41rem;
    -ms-transform: translate(-50%, -50%);
    -webkit-transform: translate(-50%, -50%);
    transform: translate(-50%, -50%);
  }

  100% {
    opacity: 1;
    width: 25.6rem;
    height: 19.5rem;
    -ms-transform: translate(-106%, -46%);
    -webkit-transform: translate(-106%, -46%);
    transform: translate(-106%, -46%);
  }
}
<div class="intro-wrapper">
  <div class="intro-logo intro-in"></div>
</div>

我不知道问题出在哪里。所有浏览器都能完美地呈现它(包括Google Chrome的模拟器),但是Safari(iOS / Mac)在动画运行时无法正确呈现它(当动画结束时,标志会停留在它的位置)。
如果您需要更多详细信息,请告诉我,我将尽快添加它们。
谢谢。
编辑
我将添加一个赏金,因为这没有得到足够的关注。

我曾经以为自己要疯了,试图理解这个 bug 是从哪里来的——动画和变换似乎是问题所在。感谢您发布这个问题。 - Larry
不客气,那是一个奇怪的问题。 - Marcos Pérez Gude
1个回答

4
您可以使用 translate 和百分比值,根据元素的宽度和高度计算其位置。但是,宽度和高度也会随着动画而更改。在我看来,这可能是Safari的一个错误,它根据初始宽度和高度计算翻译。
您有两个解决方法可选。在变换时使用 scale 或使用具体单位进行距离计算。如果您想使用 scale,需要更改一些数字,但我不确定它的确切工作方式。
如果您在动画中使用 rem 而不是百分比,则它将正常工作:

.intro-wrapper {
  position: fixed;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
}
.intro-logo {
  background: url(https://amonarraiz.com/css/img/slider/2.png) center center no-repeat;
  background-size: cover;
  width: 50rem;
  height: 41rem;
  position: absolute;
  left: 50%;
  top: 50%;
  opacity: 0;
  cursor: pointer;
}
.intro-in {
  -moz-animation-duration: 3.75s;
  -webkit-animation-duration: 3.75s;
  animation-duration: 3.75s;
  -moz-animation-name: intro-in;
  -webkit-animation-name: intro-in;
  animation-name: intro-in;
  -moz-animation-iteration-count: 1;
  -webkit-animation-iteration-count: 1;
  animation-iteration-count: 1;
  -moz-animation-fill-mode: forwards;
  -webkit-animation-fill-mode: forwards;
  animation-fill-mode: forwards;
  -webkit-animation-timing-function: ease-in-out;
  -moz-animation-timing-function: ease-in-out;
  animation-timing-function: ease-in-out;
}
@-moz-keyframes intro-in {
  0% {
    opacity: 0.6;
    width: 50rem;
    height: 41rem;
    -ms-transform: translate(-25rem, -21.5rem);
    -webkit-transform: translate(-25rem, -21.5rem);
    transform: translate(-25rem, -21.5rem);
  }
  30% {
    opacity: 1;
    width: 50rem;
    height: 41rem;
    -ms-transform: translate(-25rem, -21.5rem);
    -webkit-transform: translate(-25rem, -21.5rem);
    transform: translate(-25rem, -21.5rem);
  }
  100% {
    opacity: 1;
    width: 25.6rem;
    height: 19.5rem;
    -ms-transform: translate(-27.136rem, -8.97rem);
    -webkit-transform: translate(-27.136rem, -8.97rem);
    transform: translate(-27.136rem, -8.97rem);
  }
}
@-webkit-keyframes intro-in {
  0% {
    opacity: 0.6;
    width: 50rem;
    height: 41rem;
    -ms-transform: translate(-25rem, -21.5rem);
    -webkit-transform: translate(-25rem, -21.5rem);
    transform: translate(-25rem, -21.5rem);
  }
  30% {
    opacity: 1;
    width: 50rem;
    height: 41rem;
    -ms-transform: translate(-25rem, -21.5rem);
    -webkit-transform: translate(-25rem, -21.5rem);
    transform: translate(-25rem, -21.5rem);
  }
  100% {
    opacity: 1;
    width: 25.6rem;
    height: 19.5rem;
    -ms-transform: translate(-27.136rem, -8.97rem);
    -webkit-transform: translate(-27.136rem, -8.97rem);
    transform: translate(-27.136rem, -8.97rem);
  }
}
@keyframes intro-in {
  0% {
    opacity: 0.6;
    width: 50rem;
    height: 41rem;
    -ms-transform: translate(-25rem, -21.5rem);
    -webkit-transform: translate(-25rem, -21.5rem);
    transform: translate(-25rem, -21.5rem);
  }
  30% {
    opacity: 1;
    width: 50rem;
    height: 41rem;
    -ms-transform: translate(-25rem, -21.5rem);
    -webkit-transform: translate(-25rem, -21.5rem);
    transform: translate(-25rem, -21.5rem);
  }
  100% {
    opacity: 1;
    width: 25.6rem;
    height: 19.5rem;
    -ms-transform: translate(-27.136rem, -8.97rem);
    -webkit-transform: translate(-27.136rem, -8.97rem);
    transform: translate(-27.136rem, -8.97rem);
  }
}
<div class="intro-wrapper">
  <div class="intro-logo intro-in"></div>
</div>


天呐,使用固定单位一切运作正常。Safari的故障很让人烦恼。这是获得赏金的好机会。但是,请问这是否会因屏幕分辨率而引起问题?我使用百分比编写代码,以避免在所有屏幕分辨率上出现问题。如果你能确认这一点,你将获得150个声望点的赏金。你可以在https://amonarraiz.com上使用你的代码测试最终结果。 - Marcos Pérez Gude
一个问题:你能给我的帖子点个赞吗?这是为了补偿花费的声望 :) 谢谢!! - Marcos Pérez Gude
@MarcosPérezGude 百分比不是必需的。您可以使用相对于其父元素字体大小的 rem(相对 em)单位。在其他分辨率或字体大小上,您应该没有问题。关于 Safari 中的此错误,我会报告它,但我没有苹果设备来验证它在 Safari 的最新版本中是否存在。 - Gokhan Kurt
我确认这个完美地运作。我知道这可能会在其他浏览器中引起问题,但在我的第一次测试中一切都很好。我了解rem的工作原理,但我没有想到这可以解决问题。我使用百分比是因为尺寸可能会根据屏幕分辨率变大或变小。非常感谢您提供的好解决方案。赏金归您 :) - Marcos Pérez Gude

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接