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

Safari中SVG标签无法正确识别vh/vw单位问题求助

Safari浏览器不识别SVG中vh/vw单位的解决方案

我正在开发一个网页访客问候用的SVG元素,它在Chrome中渲染正常,但Safari无法正确解析SVG内部属性里的vh/vw单位。以下是原布局代码:

<!DOCTYPE html>
<html>

<body>
    <svg width="100vw" height="88vh" style="position:absolute; z-index:1;">
      <text id="sidename" x="-44vh" y="48" text-anchor="middle" style="color:black; font-family:serif; font-size:44.5;" transform="translate(0,0) rotate(-90)" >TITLE TEXTILE</text>
      <image class="sideicons" width="150" height="150" x="100vw" y="22vh" transform="translate(-180,-75)" href="https://cdn.glitch.global/03f12696-08e6-4dc6-a91d-f09423b082b8/123.svg?v=1664485571668"/>
      <image class="sideicons" width="150" height="150" x="100vw" y="44vh" transform="translate(-180,-75)" href="https://cdn.glitch.global/03f12696-08e6-4dc6-a91d-f09423b082b8/123.svg?v=1664485571668"/>
      <image class="sideicons" width="150" height="150" x="100vw" y="68vh" transform="translate(-180,-75)" href="https://cdn.glitch.global/03f12696-08e6-4dc6-a91d-f09423b082b8/123.svg?v=1664485571668"/>
      <a href="https://www.linkedin.com/"><text x="25vw" y="26" text-anchor="middle" style="color:black; font-family:monospace; font-size:13.31;">LinkedIn</text></a>
      <a href="https://www.instagram.com/"><text x="50vw" y="26" text-anchor="middle" style="color:black; font-family:monospace; font-size:13.31;">Instagram</text></a>
      <a href="https://google.com"><text x="75vw" y="26" text-anchor="middle" style="color:black; font-family:monospace; font-size:13.31;">Google</text></a>
      <text x="50vw" y="48vh" text-anchor="middle" style="color:white; font-family:serif; font-size:60;" transform="translate(103,54)">Title</text>
      <text x="50vw" y="48vh" text-anchor="middle" style="color:black; font-family:serif; font-size:60;" transform="translate(-113,-58)">Title</text>
      <text x="50vw" y="48vh" text-anchor="middle" style="color:black; font-family:serif; font-size:60;" transform="translate(0,0)">Title</text>
    </svg>
    
    <p style="color:grey;">Copyrighted '22</p>
</body>

</html>

问题原因

Safari对SVG内部属性中使用vh/vw这类视窗单位的支持存在兼容性缺陷,Chrome等浏览器已适配此特性,但Safari尚未完全支持SVG属性内的视窗单位解析。

解决方案

方法1:使用viewBox+CSS视窗单位控制(推荐)

通过给SVG添加viewBox属性定义坐标系统,内部元素改用百分比数值定位,再用CSS给SVG设置视窗单位的宽高,让SVG自适应缩放。修改后的代码如下:

<!DOCTYPE html>
<html>

<body>
    <!-- 设置viewBox对应原100vw×88vh的比例,CSS控制实际尺寸 -->
    <svg viewBox="0 0 100 88" style="position:absolute; z-index:1; width:100vw; height:88vh;">
      <!-- 内部数值按viewBox比例转换,比如-44vh转为-44,100vw转为100 -->
      <text id="sidename" x="-44" y="48" text-anchor="middle" style="color:black; font-family:serif; font-size:44.5;" transform="translate(0,0) rotate(-90)" >TITLE TEXTILE</text>
      <!-- 图标宽高和translate按比例缩小(150/100=1.5,180/100=1.8) -->
      <image class="sideicons" width="1.5" height="1.5" x="100" y="22" transform="translate(-1.8,-0.75)" href="https://cdn.glitch.global/03f12696-08e6-4dc6-a91d-f09423b082b8/123.svg?v=1664485571668"/>
      <image class="sideicons" width="1.5" height="1.5" x="100" y="44" transform="translate(-1.8,-0.75)" href="https://cdn.glitch.global/03f12696-08e6-4dc6-a91d-f09423b082b8/123.svg?v=1664485571668"/>
      <image class="sideicons" width="1.5" height="1.5" x="100" y="68" transform="translate(-1.8,-0.75)" href="https://cdn.glitch.global/03f12696-08e6-4dc6-a91d-f09423b082b8/123.svg?v=1664485571668"/>
      <!-- 顶部链接x值转为百分比数值 -->
      <a href="https://www.linkedin.com/"><text x="25" y="26" text-anchor="middle" style="color:black; font-family:monospace; font-size:13.31;">LinkedIn</text></a>
      <a href="https://www.instagram.com/"><text x="50" y="26" text-anchor="middle" style="color:black; font-family:monospace; font-size:13.31;">Instagram</text></a>
      <a href="https://google.com"><text x="75" y="26" text-anchor="middle" style="color:black; font-family:monospace; font-size:13.31;">Google</text></a>
      <!-- 中间标题的translate按比例缩小(103/100=1.03,54/88≈0.61) -->
      <text x="50" y="48" text-anchor="middle" style="color:white; font-family:serif; font-size:60;" transform="translate(1.03,0.61)">Title</text>
      <text x="50" y="48" text-anchor="middle" style="color:black; font-family:serif; font-size:60;" transform="translate(-1.13,-0.66)">Title</text>
      <text x="50" y="48" text-anchor="middle" style="color:black; font-family:serif; font-size:60;" transform="translate(0,0)">Title</text>
    </svg>
    
    <p style="color:grey;">Copyrighted '22</p>
</body>

</html>

说明:viewBox="0 0 100 88"定义了SVG的坐标范围,对应原设计的100vw宽度和88vh高度,内部所有坐标、尺寸按此比例转换为相对数值,再通过CSS给SVG设置width:100vw;height:88vh,让Safari能正确识别CSS层的视窗单位,SVG内部元素随视窗自动缩放。

方法2:JavaScript动态计算定位

通过JS实时计算视窗宽高,将vh/vw转换为实际像素值,再动态设置SVG内部元素的属性:

function updateSVGElements() {
  const vw = window.innerWidth / 100; // 1vw对应的像素值
  const vh = window.innerHeight / 100; // 1vh对应的像素值
  
  // 更新侧边文本位置
  const sidename = document.getElementById('sidename');
  sidename.setAttribute('x', (-44 * vh) + 'px');
  
  // 更新侧边图标位置
  const sideicons = document.querySelectorAll('.sideicons');
  const iconYPositions = [22, 44, 68];
  sideicons.forEach((icon, index) => {
    icon.setAttribute('x', (100 * vw) + 'px');
    icon.setAttribute('y', (iconYPositions[index] * vh) + 'px');
  });
  
  // 更新顶部链接位置
  const linkXPositions = [25, 50, 75];
  const linkTexts = document.querySelectorAll('a text');
  linkTexts.forEach((text, index) => {
    text.setAttribute('x', (linkXPositions[index] * vw) + 'px');
  });
  
  // 更新中间标题位置
  const centerX = 50 * vw;
  const centerY = 48 * vh;
  const centerTexts = document.querySelectorAll('text:not(#sidename):not(a text)');
  centerTexts.forEach(text => {
    text.setAttribute('x', centerX + 'px');
    text.setAttribute('y', centerY + 'px');
  });
}

// 页面加载时初始化
updateSVGElements();
// 窗口大小改变时重新计算
window.addEventListener('resize', updateSVGElements);

说明:该方法通过JS绕过Safari的兼容性问题,直接给元素设置像素值,确保在所有浏览器中定位一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 18:45:42