CSS 变换旋转不在 Webkit 上呈现/iPhone(但在 Chrome Devtools 设备工具栏中有效)

CSS transform rotate not rendering on Webkit / iPhone (but works in Chrome Devtools device toolbar)

tl;dr:如我的标题所述:CSS 变换旋转不在 Webkit 上呈现/iPhone(但在 Chrome Devtools 设备工具栏中有效)。

更新:我还为此创建了一个单独的 GitHub 问题,它更简洁(可以说更容易阅读)并且没有代码摘录,here.


只是为了某些上下文(以防万一):我正在从 React 调用我的 Express API,获取图像及其关联的方向,我将它们映射到顺时针方向的值 0、180 和 270 度垂直方向(来自 EXIF 数据),然后在我完成初始渲染后使用 CSS 旋转它们。当我向下滚动页面时,我也是 lazy-loading 图片,所以我使用新的 IntersectionObserver API 它需要 WebKit / Safari 的 polyfill(所以我已经将该 polyfill 包含在root index.html 在我的 public 目录中)。在没有 polyfill 的 Google Chrome 中,以及在有 polyfill 的 Safari 中,这一切都工作正常,但是在 iPhone 上的 /Safari 中,它没有'旋转图像.

下面是一些相关代码:

// LazyImage.js
render() {
    const { className } = this.props;
    const transformRotationValue = `rotate(${360 - this.state.orientation}deg)`;
    const styles = {
      '-webkit-transform':  transformRotationValue,
      '-moz-transform':     transformRotationValue,
      '-ms-transform':      transformRotationValue,
      '-o-transform':       transformRotationValue,
      transform:            transformRotationValue,
      height:               '500px',
    }
    return (
      <Fragment>
        <p>
          Date: {this.state.date}
        </p>
        <img alt={this.state.date} className={className} style={styles} ref={el => this.element = el} />
      </Fragment>
    );
  }

此外,我对 CSS 不是很好,但这是我的 CSS 代码:

/* PhotoFeed.css */
/*  */
:local(.photos) {
  width: inherit;
  flex-shrink: 0;
  min-height: 100%
}
:local(.photoContainer) {
  height: 500px;
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
  margin-top: 2px;
}

对应React组件中的这段代码:

// PhotoFeed.js
return (
              <div className={styles.photoContainer} key={idx}>
                <LazyImage className={styles.photos} src={`${apiRootURL}/photos/demo/${fileName}?token=${Authentication.getToken()}`}/>
              </div>
            );

完整代码也可用于 server-side and the client-side code (in case anybody wants to actually run the entire program, though the client code is the main code in question here). The demo code is also live at this website and can be accessed like so,以防有人想通过某种浏览器工具测试网站的 front-end。

我也研究了一些建议 here,但我只是不明白为什么 CSS 在 iPhone 上不起作用,但它在Chrome 和我的 macOS 上的 Safari。


一些更新

更新 1:

我试过this,正如@MohammadRF 在评论中建议的那样,但它仍然不起作用。更详细地说,我将那些相同的 classes 添加到我的 CSS,并按如下方式更新我的反应代码:

const styles = {
      // '-webkit-transform':  transformRotationValue,
      // '-moz-transform':     transformRotationValue,
      // '-ms-transform':      transformRotationValue,
      // '-o-transform':       transformRotationValue,
      // transform:            transformRotationValue,
      height:               '500px',
    }
    return (
      <Fragment>
        <p>
          Date: {this.state.date}
        </p>
        <img alt={this.state.date} className={className + ` rotate${360 - this.state.orientation}`} style={styles} ref={el => this.element = el} />
      </Fragment>
    );

这不起作用,因为 CSS 甚至没有从 class 名称中应用,即使在没有 webkit 的浏览器上也是如此(尽管 class 列表确实得到在呈现的 HTML 代码中更新)。所以到目前为止,我的原始(和当前)解决方案效果更好。


更新 2:

我刚刚意识到我的 Chrome DevTools 给我以下警告 {face-palm}:

index.js:1446 Warning: Unsupported style property -webkit-transform. Did you mean WebkitTransform?

index.js:1446 Warning: Unsupported style property -moz-transform. Did you mean MozTransform?

index.js:1446 Warning: Unsupported style property -ms-transform. Did you mean msTransform?

index.js:1446 Warning: Unsupported style property -o-transform. Did you mean OTransform?

所以现在我已经修复它,所以警告不会出现:

    const rotationValue = 360 - this.state.orientation;
    const transformRotationValue = `rotate(${rotationValue}deg)`;
    const styles = {
      WebkitTransform:  transformRotationValue,
      MozTransform:     transformRotationValue,
      msTransform:      transformRotationValue,
      OTransform:       transformRotationValue,
      transform:        transformRotationValue,
      height:           '500px',
    }

...但它在我的 macOS Chrome/Safari 上仍然可以正常旋转,但 在 iPhone 浏览器上仍然无法旋转

主要问题是确定问题。这是令人震惊的时刻:事实证明 iPhone 上的浏览​​器(Chrome 和 Safari)会自动将 jpeg 图像定向到所需的方向,但桌面浏览器不会这样做。一旦我意识到这一点,这是一个 5 分钟的修复。我通过 this MDN page and this tutorial 查看了 Safari 开发工具中 iPhone 上的用户代理字符串,然后为我的渲染方法提出了这个简单的解决方案:

render() {
    let { className } = this.props;
    const styles = {
      transform:  'rotate(0deg)',
      height:     '500px',
    }
    if (navigator.userAgent.indexOf('iPhone') === -1) {
      styles.transform = `rotate(${360 - this.state.orientation}deg)`;
    }
    return (
      <Fragment>
        <p>
          Date: {this.state.date}
        </p>
        <img alt={this.state.date} className={className} style={styles} ref={el => this.element = el} />
      </Fragment>
    );
  }

答案基本上是这样的:

确保您还设置了默认值 属性:旋转(0 度)

不设置它适用于 Chrome,但不适用于 iOS 和 Edge