You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Safari中含transform-style:preserve-3d的div内元素CSS hover样式失效问题

解决Safari中transform-style:preserve-3d容器内hover样式失效问题

问题场景

我实现了一个视差滚动头部组件,其中的Unsplash社交图标配置了hover样式(鼠标悬停时变为橙色、光标变为指针),但该样式在Safari浏览器中完全不生效。移除容器上的transform-style: preserve-3d属性后,hover样式恢复正常,但会直接破坏视差滚动效果,而这个功能在Chrome浏览器中运行完全正常。

代码示例

<!doctype html>
<html class="h-full">
<head>  
  <script src="https://cdn.tailwindcss.com/3.3.1"></script>
</head>
<div class="h-screen">
  <div class="flex h-full flex-col overflow-hidden overflow-y-auto bg-stone-900">
    <div class="scrollbar-thin scrollbar-thumb-orange-400 scrollbar-track-none scrollbar-thumb-rounded-full w-full flex-1 overflow-x-hidden overflow-y-hidden overflow-y-scroll scroll-smooth bg-stone-900" style="perspective: 10px">
      <div class="relative flex h-full items-center justify-center" style="transform-style: preserve-3d">
        <div class="container m-1 lg:w-3/4" style="transform: translateZ(-5px) scale(1.5)">
          <h2 class="font-bungee-hairline inline bg-stone-900 box-decoration-clone p-4 text-3xl font-bold leading-normal text-white hover:bg-red-800 sm:text-4xl md:text-6xl md:leading-tight">Travel &<br />Landscape<br />Photography</h2>
          <div class="mt-4 flex w-min bg-stone-900 px-6 py-4">
            <a :href="links.unsplash" aria-label="Unsplash" target="_blank"
              ><svg class="mr-4 h-6 w-6 fill-white transition hover:cursor-pointer hover:fill-orange-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
                <path d="M448,230.17V480H0V230.17H141.13V355.09H306.87V230.17ZM306.87,32H141.13V156.91H306.87Z" /></svg
            ></a>
          
          </div>
        </div>

        <img class="absolute z-[-1] h-full w-full object-cover" src="https://images.unsplash.com/photo-1661173357770-619fcd1388af?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2340&q=80" alt="A Ginormous salt lake reflecting like a mirror in Turkey at sunset" style="transform: translateZ(-20px) scale(3)" />
      </div>
    </div>
  </div>
</div>

原因分析

这是Safari浏览器的已知渲染bug:当元素处于设置了transform-style: preserve-3d的容器下时,浏览器会将该容器内的元素放入独立的3D渲染层,导致鼠标交互事件(如hover)无法被正确识别和触发。

解决方案

方案1:给hover元素添加transform: translateZ(0)

给需要触发hover效果的元素(这里是<a>标签或<svg>)添加transform: translateZ(0)样式,强制浏览器将元素归入正确的渲染层,既不会破坏原有的视差效果,又能让hover样式正常生效。

修改后的图标代码:

<a :href="links.unsplash" aria-label="Unsplash" target="_blank" style="transform: translateZ(0)">
  <svg class="mr-4 h-6 w-6 fill-white transition hover:cursor-pointer hover:fill-orange-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
    <path d="M448,230.17V480H0V230.17H141.13V355.09H306.87V230.17ZM306.87,32H141.13V156.91H306.87Z" />
  </svg>
</a>

如果用Tailwind CSS,可以直接在class里添加transform translate-z-0。

方案2:替换preserve-3d实现视差

如果方案1无效,可以尝试移除父容器的perspective和transform-style: preserve-3d,直接给需要实现视差的元素设置perspective属性,同样能达到视差效果,同时规避Safari的bug。

修改后的关键代码:

<!-- 移除父容器的perspective和transform-style: preserve-3d -->
<div class="scrollbar-thin scrollbar-thumb-orange-400 scrollbar-track-none scrollbar-thumb-rounded-full w-full flex-1 overflow-x-hidden overflow-y-hidden overflow-y-scroll scroll-smooth bg-stone-900">
  <div class="relative flex h-full items-center justify-center">
    <!-- 给文本容器添加perspective -->
    <div class="container m-1 lg:w-3/4" style="transform: perspective(10px) translateZ(-5px) scale(1.5)">
      <!-- 文本内容不变 -->
    </div>
    <!-- 给图片添加perspective -->
    <img class="absolute z-[-1] h-full w-full object-cover" src="..." alt="..." style="transform: perspective(10px) translateZ(-20px) scale(3)" />
  </div>
</div>

验证效果

修改后在Safari浏览器中测试,hover样式应该能正常触发,同时视差滚动效果保持不变。

内容的提问来源于stack exchange,提问作者Aydin Hassan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 22:25:05