尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

前端里 SVG 三种用法:img、内联、组件

前端里 SVG 三种用法:img、内联、组件 SVGScalable Vector Graphics可缩放矢量图形是用 XML 描述的矢量图放大仍保持清晰适合图标与简单插画。前端项目里同一份 SVG 常有三种用法当图片用、写进 HTML/JSX、包成组件。选错时会出现颜色改不动、包体积变大、或每个页面复制一大段 path。下面把三种用法拆开并给出怎么选。一、先说一个具体麻烦设计给了一个logo.svg。你随手写成imgsrc/logo.svgaltlogowidth120height40/上面代码中SVG 被当成普通图片引用。多数情况下这没问题缓存友好写法简单。接着产品说「暗色模式下 logo 要改成浅色。」你写了img { fill: #fff }发现没用。因为以img引入时外部 CSS 通常改不了 SVG 内部的fill。于是有人改成整段内联 SVG颜色能改了但每个页面粘贴上百行 path维护又变痛。第三种做法是做成组件把color当 prop 传进去。三种方式都对只是解决问题不同。二、用法一当作图片img 或 CSS background把 SVG 当静态资源和 PNG 类似。适合1颜色固定、不需要运行时改 fill / stroke2只要清晰缩放与小体积3希望浏览器按普通图片缓存不太适合1要随主题切换颜色2要精细控制内部某个 path 的动画或交互3需要从外层 CSS 穿透修改图形属性补充background-image: url(...svg)与img类似外部 CSS 同样难改内部 fill。可用 CSS mask 做单色图标技巧但那是另一条路本文先按三种主用法讲。三、用法二内联 SVG把svg.../svg直接写进 HTML 或 JSX。适合1要用 CSS 改fill/stroke/currentColor2要对内部节点做动画或悬停态3图标少、改动频繁的关键视觉元素不太适合1大量重复内联导致 JSX 嘈杂2同一图标在几十处复制粘贴3设计师频繁换稿你却在改多份拷贝下面是一个最小内联示例。svgwidth24height24viewBox0 0 24 24aria-hiddentruepathfillcurrentColordM12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20z//svg上面代码中fillcurrentColor让图标颜色跟随文字颜色。父级改color图标跟着变这是内联相对img的关键优势。无障碍上装饰性图标可aria-hiddentrue有意义的图形要有可访问名称例如roleimgtitle或由旁白文字说明。四、用法三做成组件在 React / Vue 等框架里把 SVG 封装成组件通过 props 控制尺寸、颜色、标题。适合1设计系统里的图标集2多处复用且要统一 APIsize/color/className3既要可改样式又不想到处粘贴 path不太适合1只用一次的大插画可能直接内联或当图更简单2完全不需要样式控制的静态资源img更轻下面是一个最小 React 示意。type IconProps { size?: number; className?: string; title?: string; }; export function CircleIcon({ size 24, className, title }: IconProps) { return ( svg width{size} height{size} viewBox0 0 24 24 className{className} role{title ? img : undefined} aria-hidden{title ? undefined : true} {title ? title{title}/title : null} path fillcurrentColor dM12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20z / /svg ); }上面代码中尺寸与无障碍属性变成稳定 API颜色继续走currentColor或外部 class。路径只维护一份。工程上还可以用 SVGR 等工具把.svg文件编译成组件避免手贴 path。那是工具链细节心智模型仍是「第三种用法」。五、怎么选可以按决策树走1颜色与内部样式都不用改 → 优先img或背景图2要改颜色 / 做简单交互且出现次数少 → 内联3多处复用、要统一 props → 组件补充两条经验1logo 常两套默认用img保证缓存与简单若强依赖主题色再提供组件版或内联版2图标集走组件设计系统里不要一半 img 一半内联API 不统一会拖慢所有人六、性能与包体注意点1内联与组件会把路径打进 JS/HTML图标极多时注意打包体积与缓存粒度2img可独立缓存、可懒加载适合大装饰图3无论哪种方式导出前用 SVGO 一类工具清理无用元数据能明显缩小 path4不要为了「全矢量」把照片级复杂度的图硬转 SVG七、常见误区1以为所有 SVG 都能用 CSS 改 fill只有进入 DOM 的内联/组件版通常可以img不行常规情况。2把几十份内联复制粘贴当组件改一处漏十九处是维护事故。3忽略 viewBox只有宽高、没有正确viewBox缩放与裁剪会怪。4装饰图标不处理无障碍要么隐藏要么给名称避免读屏读出一堆 path 噪音。5用 SVG 替换本该用字体或系统控件的地方按钮、焦点态、语义仍要落在 HTML 控件上SVG 负责图形不负责整套交互语义。八、小结前端用 SVG常见三条路1img当图片简单可缓存难改内部样式2内联进 DOM好调色与动画怕复制粘贴3组件可复用、可传参适合图标系统先问「要不要改样式、要不要复用」再选用法。选对了暗色模式改个颜色不会变成半天排障。完
返回列表