【问题标题】:Positioning/Rendering issues in Safari (OSX and iPad) when adding CSS pulse animation添加 CSS 脉冲动画时,Safari(OSX 和 iPad)中的定位/渲染问题
【发布时间】:2016-02-20 04:20:45
【问题描述】:

我想使用 CSS 动画在垂直和水平居中的图像上创建一个脉冲动画。这在 Firefox 和 Chrome(移动和 OSX 版本)中运行良好。但是在Safari中搞砸了,图片的定位不正确。

奇怪的是,在切换桌面(三指向左或向右滑动)并返回 safari 后,图像的位置正确。

我创建了一个 jsfiddle 来显示问题,我省略了除 -webkit 之外的所有前缀。

这里是 JSfiddle:https://jsfiddle.net/stxnt1sb/9/

HTML

<article>
  <img src="http://lorempixel.com/600/400/sports/">
</article>

CSS

article{
  position:relative;
  width:600px;
  height:400px;
  overflow:hidden;
}
img{
  position:absolute;
  top:50%;
  left:50%;
  width:100%;
  -webkit-transform:translate(-50%,-50%);
  -webkit-animation-name: pulse;
  -webkit-animation-duration: 10s;
  -webkit-animation-timing-function: ease-in-out;
  -webkit-animation-iteration-count: infinite;
  -webkit-animation-direction: normal;
}
@-webkit-keyframes pulse {
  0% {
    -webkit-transform: translate(-50%, -50%) scale(1) ;
  }
  33% {
    -webkit-transform:  translate(-50%, -50%) scale(1.05);
  }
  100% {
    -webkit-transform: translate(-50%, -50%) scale(1) ;
  }
}

图像在相对容器中绝对定位,以平移(-50%,-50%) 为中心。脉冲是通过 css 动画完成的,为图像的比例设置动画。

【问题讨论】:

    标签: css safari position css-animations pulse


    【解决方案1】:

    正如 Ricardo 所说,Safari 的渲染引擎可能存在疑问。 Safari 确定转换后的元素需要一个复合层。这些图层是单独渲染的特殊图层。我的猜测是 Safari 不会更新复合层然后加载图像。

    这留下了一些选择。

    1:设置高宽属性

    我很确定这会解决它。在图像上设置宽度和高度允许 Safari 在加载之前预测大小。不幸的是,它确实需要硬编码值或额外的 I/O 读取来确定图像的大小。

    2:强制更新

    Paul Lewis,又名 Aerotwist,创建了 CSS Triggers,一个 CSS 属性列表以及它们触发的内容。您可以设置一个属性并触发重绘。在这种特殊情况下,我不确定您是否需要布局,因此复合层确定其内容的大小并相应地调整大小,或者复合层只是改变位置。

    有不同的方法可以做到这一点。你可以设置一个 CSS 属性,你可以通过这样做来获取信息并触发刷新(例如el.getComputedStyle()el.offsetTop),或者你可以简单地做一个window.dispatchEvent(new Event('resize'))。将此作为最后的手段,因为它们可能会对渲染性能产生影响。

    3:避免复合层

    您正在使用变换来居中对齐图像,并且您必须在动画中设置变换,这意味着您不能将它重用于没有相同变换的元素。尽管动画可能仅适用于该特定元素,但隔离职责是一种很好的做法。动画应该可以工作,无论您将其应用于什么元素。

    无论如何,还有其他方法可以使元素居中对齐。

    display: table method 很旧,但很可靠。如果您使用的是现代浏览器,centering using Flexbox 可能是最简单的方法。

    【讨论】:

      【解决方案2】:

      我认为您可能想尝试一种与使用真正的&lt;img /&gt; 元素不同的方法。正如您的代码所建议的那样,您希望根据图像的纵横比来缩放图像。但是,您只能将宽度或高度设置为 100%,否则会超出比例地拉伸图像。

      遗憾的是,就 Safari 而言,我认为图像是在呈现样式表之后加载的。这让 Safari 的渲染引擎对如何处理垂直定位产生疑问(因为此时尚未设置高度)。

      因此我建议将传统的&lt;img /&gt; 换成这样的:

      article{
        position:relative;
        width:600px;
        height:400px;
        overflow:hidden;
      }
      .pulsing-background{
        background-position: center center;
        background-size: cover;
        height: 100%;
        width: 100%;
        position:absolute;
        margin: 0;
        padding: 0;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        -webkit-animation-name: pulse;
        -webkit-animation-duration: 10s;
        -webkit-animation-timing-function: ease-in-out;
        -webkit-animation-iteration-count: infinite;
        -webkit-animation-direction: normal;
      }
      @-webkit-keyframes pulse {
        0% {
          
          -webkit-transform: scale(1) ;
         
        }
        33% {
          
          -webkit-transform: scale(1.05);
        
        }
        100% {
         
          -webkit-transform: scale(1) ;
         
        }
      }
      <article>
        <figure style="background-image: url(http://lorempixel.com/600/400/sports/)" class="pulsing-background"></figure>
      </article>

      这确保了子元素(图形)始终是其父元素的大小。它在语义上并不完美,您可能还会找到切换到 Flex-Box 实现的解决方案。至少你现在知道去哪里找了。

      编辑:忘记添加边距:0;在 sn-p 中重置 Safari 中的默认 &lt;figure /&gt; 样式。

      【讨论】:

      • 您仍然可以定位元素,同时保持它们的纵横比 (fiddle)
      • @tim-s 绝对!但是,这需要您事先知道图像的尺寸。我不确定 OP 所考虑的实际用例。使用“背景尺寸:封面;”适用于任何纵横比,并且是在具有特定格式的容器内实现不同纵横比图像的一种万无一失的方法。虽然我不喜欢为此使用 'style' 属性。
      猜你喜欢
      • 2011-07-30
      • 2021-06-24
      • 1970-01-01
      • 1970-01-01
      • 2011-05-19
      • 2012-04-07
      • 1970-01-01
      • 2011-06-09
      • 1970-01-01
      相关资源
      最近更新 更多