← 🔷 SVG × CSS:一块能被 CSS 管的画布 / 嵌入矩阵:谁能被 CSS 管到 待审核 1 / 9
embed · 嵌入矩阵

嵌入矩阵:谁能被 CSS 管到

同一颗心,用五种方式放进页面。然后按下面两个开关:一个让外部 CSSfill 改为绿色,一个改宿主文字色currentColor 的来源)。观察哪些跟随变化、哪些不受影响——这就是「图标系统为什么偏爱 inline / <use>」的根本原因。

把同一段 SVG 这样放进页面 外部 CSS 能改它内部? JS / :hover? currentColor 继承宿主?
inline <svg> ✅ 完全
<use href="#id"> (同文档) ✅ 可穿透
<img src=".svg"> ❌ 隔离
background-image: url()
<object> / <iframe> ❌ 跨文档 ⚠️ 独立文档

图标系统为什么偏爱 inline / <use> 而非 <img>,根源就在这张表——本页逐格实测每一项;那几个 ❌ 隔离格,param() 提案想给它们开一扇传参口。

1 · 五种写法

只有 inline同文档 <use> 把图形真正接入了当前文档的 DOM 树,所以外部 CSS 选择器能选中、currentColor 能继承宿主的 color:hover 也能命中。<img>background-image 把 SVG 当作一张沙箱位图——内部 DOM 对外不可见;<object> / <iframe>另一个独立文档,外部 CSS 同样无法进入(但它内部的 <style> 有效)。

2 · 复用三件套:<defs> / <use> / <symbol>

上面那个能被 CSS 改色的 <use>,正是图标 sprite 系统的地基:把图形定义一次放进 <defs><symbol>(不渲染、待引用),页面各处用 <use href="#id"> 克隆。<symbol><g> 多一个自带 viewBox,所以每次 <use> 都能缩放贴合。

<use> 克隆出的内容在一棵 shadow tree 里,外部 CSS 选不中它的内部元素(写 use circle {…} 没用)。但继承类属性 (fill / color / --var) 能从 <use> 元素本身穿透下去——所以改色靠的是「在 use 上设 fill,让内部继承」,而不是直接选中内部。主题化图标的细节见 presentation attribute 一页。

3 · 两个 SVG 的反直觉特性

其一:SVG 没有 z-index 元素的层叠顺序完全等于文档顺序——写在后面的覆盖前面的,要调整层级只能改变 DOM 位置(或用 <use> 重新引用)。给 SVG 子元素写 z-index 无效。

其二:pointer-events 在 SVG 里取值更多。 除了 auto/none,还有 visiblePainted(默认:只有被填充 / 描边的可见部分响应点击)、fill(透明填充区也响应)、strokeall。因此一个只描边的圆环,默认点击中间空心处不会触发——除非设 pointer-events: fill