如何解决SVG中fill与stroke重叠导致的颜色及尺寸异常问题
问题根本原因
SVG的stroke默认采用路径居中对齐的绘制规则:描边总宽度的一半会延伸到路径内侧(和fill填充区域重叠),另一半延伸到路径外侧。同时SVG默认先绘制fill再绘制stroke,所以当二者设置半透明同色时,重叠区域会出现alpha混合,颜色比其他区域更深;去掉描边后外侧延伸的部分消失,视觉尺寸就会缩小,和CSS的border-box盒子模型表现不一致。

解决方案
方案1:直接修改描边对齐方式(适合现代浏览器)
SVG 2新增了stroke-alignment属性,直接设置为outer即可让描边完全绘制在路径外侧,和填充区域完全无重叠:
<circle cx="50" cy="50" r="40" fill="rgba(255,0,0,0.5)" stroke="rgba(255,0,0,0.5)" stroke-width="10" stroke-alignment="outer" />
如果你需要描边完全绘制在路径内侧,和CSS的border-box表现一致,设置stroke-alignment="inner"即可。
方案2:调整绘制顺序(兼容全版本浏览器)
如果需要兼容不支持stroke-alignment的旧版浏览器,可以通过paint-order属性修改绘制顺序,先画描边再画填充,让填充完全盖住内侧重叠的描边部分:
- 假设你需要的填充半径为
R,期望外侧描边宽度为W - 将
stroke-width设置为2*W(因为内侧一半会被填充盖住,剩下外侧一半刚好是你需要的宽度) - 保留
r为R不变,添加paint-order="stroke"属性
示例代码:
<circle cx="50" cy="50" r="40" fill="rgba(255,0,0,0.5)" stroke="rgba(255,0,0,0.5)" stroke-width="20" paint-order="stroke" />
以上两种方案都可以完全避免填充和描边的重叠,半透明同色时也不会出现混合痕迹,视觉效果完全均匀。
内容的提问来源于stack exchange,提问作者Alex Ivasyuv
相关产品推荐
相关产品推荐

