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

srcSet属性在Safari浏览器中无法正常工作的问题求助

Safari中srcset图标不生效的解决建议

你当前的导航栏图标通过srcset实现多分辨率适配,在Chrome、Firefox等浏览器正常,但Safari无法加载对应分辨率的图片,以下是针对Safari兼容性的修复方案:

问题代码回顾

icons.ts

import dashboardIcon from 'assets/icons/dashboard_icon.png'
import dashboardIcon2x from 'assets/icons/dashboard_icon@2x.png'
import dashboardIcon3x from 'assets/icons/dashboard_icon@3x.png'
import dashboardIcon4x from 'assets/icons/dashboard_icon@4x.png'

dashboardIcon: {
    src: dashboardIcon,
    srcset: `${dashboardIcon4x} 4x,${dashboardIcon3x} 3x,${dashboardIcon2x} 2x, ${dashboardIcon} 1x`,
  },

CustomIcon.tsx

import React from 'react'
import styled from 'styled-components'

import { FixMeLater } from 'types'
import FilePicker from 'components/button/FilePicker'

export interface IconSourceType {
  src: string
  srcset: string
}
interface IIconProps {
  id?: string
  source: IconSourceType
  className?: string
  isFilePicker?: boolean
  getInputProps?: FixMeLater
  onClick?: (e: React.MouseEvent<HTMLElement>) => void
  onMouseDown?: (e: React.MouseEvent<HTMLElement>) => void
  onMouseUp?: (e: React.MouseEvent<HTMLElement>) => void
}

const CustomIcon = ({
  id = '',
  source,
  className,
  isFilePicker,
  getInputProps,
  onClick,
  onMouseDown,
  onMouseUp,
}: IIconProps) => {
  return (
    <>
      <IconWrapper
        id={id}
        onClick={onClick}
        onMouseDown={onMouseDown}
        onMouseUp={onMouseUp}
        className={className}
        src={source.src}
        srcSet={source.srcset}
        clickable={!!onClick || !!onMouseUp}
      />
      {isFilePicker && <FilePicker getInputProps={getInputProps} icon />}
    </>
  )
}

export default CustomIcon

const IconWrapper = styled.img`
  cursor: ${({ clickable }: { clickable: boolean }) => (clickable ? 'pointer' : 'unset')};
`

使用方式(NavigationBar.tsx)

...
<CustomIcon source={icons.dashboardIcon} />
...

修复方案

1. 确保图片实际分辨率与x描述符严格匹配

Safari对srcset的x描述符校验非常严格,要求@nx图片的实际像素尺寸必须是基础图的n倍。例如:

  • 基础图dashboard_icon.png如果是48×48像素,那么@2x必须是96×96,@3x是144×144,@4x是192×192。
  • 若图片尺寸不匹配,Safari会忽略对应分辨率的图片,直接加载基础src。

2. 修正srcset的格式空格

你的srcset中部分条目缺少逗号后的空格(如4x,${dashboardIcon3x}),虽然其他浏览器容错,但Safari可能解析失败。统一格式为逗号+空格分隔:

dashboardIcon: {
    src: dashboardIcon,
    srcset: `${dashboardIcon4x} 4x, ${dashboardIcon3x} 3x, ${dashboardIcon2x} 2x, ${dashboardIcon} 1x`,
  },

3. 强制添加sizes属性(关键修复)

Safari在没有sizes属性时,无法准确判断图片的布局尺寸,进而无法正确选择srcset中的图片。根据你的图标实际布局尺寸添加sizes:

  • 若图标固定显示为24px宽:
    修改IconWrapper的props,添加sizes="24px":
    <IconWrapper
      id={id}
      onClick={onClick}
      onMouseDown={onMouseDown}
      onMouseUp={onMouseUp}
      className={className}
      src={source.src}
      srcSet={source.srcset}
      sizes="24px" // 新增
      clickable={!!onClick || !!onMouseUp}
    />
    
  • 若图标使用相对单位(如1em),则设置sizes="1em",确保值与CSS中图标宽度一致。

4. 检查图片加载状态

打开Safari开发者工具的网络面板,筛选图片请求,确认各个分辨率的图片是否能正常加载:

  • 若出现404,检查图片路径是否正确(注意webpack等打包工具的路径处理)。
  • 若出现跨域错误,确认服务器配置了正确的CORS头。

5. 备选方案:改用<picture>元素

如果以上方案仍无效,可替换为<picture>元素实现多分辨率适配,Safari对其支持更稳定:
修改CustomIcon.tsx的返回部分:

const CustomIcon = ({
  id = '',
  source,
  className,
  isFilePicker,
  getInputProps,
  onClick,
  onMouseDown,
  onMouseUp,
}: IIconProps) => {
  // 拆分srcset为各个分辨率条目
  const srcItems = source.srcset.split(',').map(item => item.trim().split(' '))
  
  return (
    <>
      <picture>
        {/* 为每个分辨率添加source */}
        {srcItems.map(([url, ratio]) => (
          <source 
            key={ratio} 
            srcSet={url} 
            media={`(-webkit-min-device-pixel-ratio: ${ratio.replace('x', '')})`} 
          />
        ))}
        {/* 基础图片作为 fallback */}
        <IconWrapper
          id={id}
          onClick={onClick}
          onMouseDown={onMouseDown}
          onMouseUp={onMouseUp}
          className={className}
          src={source.src}
          clickable={!!onClick || !!onMouseUp}
        />
      </picture>
      {isFilePicker && <FilePicker getInputProps={getInputProps} icon />}
    </>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 05:35:15