跳到主要内容

嵌入方式与CSS尺寸

同一份 SVG 字节,嵌进页面的方式决定它是 文档 还是 图片。交互、无障碍、脚本、能否吃页面 CSS,都在这一层分叉,不在 viewBox 四个数上。

1. 适用 / 不适用

适用: 产品 UI、可点热区、可编辑图形 → inline;图标/插画装饰、用户上传预览 → <img> 或 background;需要 fallback HTML → &lt;object>;要强隔离文档 → &lt;iframe>

不适用: 不可信内容 inline;需要读屏角色却用 background;需要内部命中却用 <img>。安全边界见 08

2. 五种嵌入

方式脚本指针命中内部节点无障碍继承页面 CSS文件内 SMIL
inline &lt;svg>进当前 DOM 树
<img src>否(整张图一块)alt,无内部树
&lt;object>视同源文档视该文档独立文档 + fallback
&lt;iframe>隔离文档隔离隔离
CSS background-image无(纯装饰)

「SMIL 会」指 文件自己带的 animate*,不依赖页面样式表。这也是 SMIL 仍有岗位的原因:<img> 里 WAAPI 进不去。

object / iframe 对同源 SVG 几乎是「又开了一份文档」。跨源则按普通嵌入处理,页面 JS 摸不到内部节点。不要靠 contentDocument 当公共 API。

3. CSS 尺寸:盒子不是用户单位

inline 时 &lt;svg> 是普通 CSS 盒。属性 width/height 会变成 intrinsic size,和样式表里的宽高一起打架。响应式优先 只留 viewBox,用 CSS 控盒

export function fitInlineSvg(
svg: SVGSVGElement,
viewBox: string,
cssWidth: string,
): void {
svg.setAttribute("viewBox", viewBox);
svg.removeAttribute("width");
svg.removeAttribute("height");
svg.style.width = cssWidth;
svg.style.height = "auto";
svg.setAttribute("preserveAspectRatio", "xMidYMid meet");
}

height: auto 能工作,前提是有 viewBox(或显式宽高比)。没有 viewBox 时,引擎把 SVG 当 replaced 元素的默认 300×150 一类盒子,再被 CSS 拉扯——看起来像位图。

<img> / background 的尺寸完全是 图片盒子。内部用户单位只通过 viewBox 映射到这张位图的绘制过程;你无法从页面 CSS 改到某个 circlefill。要主题化图标,inline 或 CSS mask / currentColor 方案,不要指望 img { fill: ... }

4. 交互与无障碍怎么选

export type EmbedKind = "inline" | "img" | "object" | "iframe" | "background";

export function pickEmbed(input: {
interactive: boolean;
untrusted: boolean;
decorative: boolean;
}): EmbedKind {
if (input.untrusted) return "img";
if (input.decorative && !input.interactive) return "background";
if (input.interactive) return "inline";
return "img";
}

inline 才能在节点上挂 title / role / tabindex,见 03 交互与命中

可点击热区:命中必须落在内部图形上 → inline。用透明 <img> 叠 DOM 热区是另一条产品线,和 SVG 命中无关。

object 的 fallback 子节点在 SVG 加载失败时出现,适合「矢量优先、位图垫底」。不要把 fallback 当成第二套交互。同源 object 里的脚本会跑;不可信文件不要用 object 冒充「比 inline 安全」——要沙箱用 <img> 或跨源 iframe

&lt;iframe> 有独立浏览上下文,CSP / 尺寸隔离更完整,代价是通信和焦点。装饰插画不要上 iframe。

5. 失败形态

症状原因
querySelector("path") 为 null嵌在 img / background 里,没有内部 DOM
读屏只听到「图像」可交互图用了 img / background
页面改 fill 不起作用非 inline,样式进不去 shadow/独立文档
用户 SVG 弹脚本不可信内容 inline 或同源 object
盒子 300×150 或被拉扁无 viewBox,又靠属性宽高和 CSS 双通道

权威资料

核对日期:2026-08-26