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

如何解决SVG径向进度条resize后内容截断,实现随父容器自适应?

径向进度条SVG自适应缩放、避免内容截断的可落地方案

问题根因拆解

当前代码出现截断效果,核心来自四个叠加的配置问题:

  • 未给SVG设置和实际绘制范围匹配的viewBox,固定像素的圆形半径、文字大小没有和SVG显示尺寸建立映射关系,缩小父容器时内部坐标系和显示区域无法对应缩放
  • 没有覆盖SVG浏览器默认的overflow: hidden规则,filter生成的投影、粗stroke的边缘超出元素本身边界时,会被SVG容器自动裁切
  • 自定义filter没有配置自身的绘制范围,大模糊值的阴影效果容易超出filter默认的计算区域,被提前截断
  • 部分元素属性无效:给<path>标签设置x/y属性对路径绘制没有任何作用,不会触发坐标修正,反而可能引发渲染偏差

具体修改方案

1. 配置匹配实际边界的viewBox

先计算所有绘制元素的最大外接范围:当前代码中最大圆形半径为138px,叠加27px的最粗stroke宽度、投影偏移和模糊半径(约16px),整个内容的最大直径约为296px,对应设置viewBox为0 0 296 296,把所有绘制内容完整纳入SVG的独立坐标系中。

注意:viewBox的范围必须覆盖所有元素(包括stroke、阴影效果的延伸范围),之前单独使用viewBox效果不佳,大多是因为范围没有把这些延伸效果包含进去,导致内容依然被裁切。

2. 配置缩放对齐与溢出规则

给SVG元素增加两个核心属性,保证缩放逻辑符合预期:

  • preserveAspectRatio="xMidYMid meet":控制内容等比缩放,居中对齐,完整显示所有内容,不会出现拉伸变形、边缘裁切的问题
  • 显式设置overflow: visible:覆盖浏览器默认的SVG溢出隐藏规则,让阴影、粗stroke的边缘可以正常显示,不会被SVG自身边界切掉

3. 扩大filter的计算范围

浏览器默认的filter计算区域仅为元素边界的-10%到+120%范围,对于模糊值较大的阴影效果,很容易超出计算边界被裁切,需要给自定义filter扩大计算范围:

<filter id="inset-drop-shadow" x="-20%" y="-20%" width="140%" height="140%">

4. 修正元素坐标逻辑

配合viewBox的坐标系,把原来写死的百分比中心坐标替换为坐标系内的固定中心值(即viewBox范围的中心:148,148),删除<path>标签上无效的x/y属性,避免渲染异常。

修正后的完整示例代码

<style>
text {
    text-anchor: middle;
    font-weight: bolder;
    font-family: 'Nunito', sans-serif;
}
.shadow {
    -webkit-filter: drop-shadow(6px 6px 10px #000000cc);
    filter: drop-shadow(6px 6px 10px #000000cc);
}
</style>

<div id="svg-container" class="containter" style="width: 180px;height:280px">
    <svg id="svg" 
         width="100%" 
         height="100%" 
         viewBox="0 0 296 296" 
         preserveAspectRatio="xMidYMid meet"
         style="overflow: visible;">
        <defs>
            <filter id="inset-drop-shadow" x="-20%" y="-20%" width="140%" height="140%">
                <feFlood flood-color="#000000" />
                <feComposite in2="SourceAlpha" operator="out" />
                <feGaussianBlur stdDeviation="6" result="blur" />
                <feComposite operator="atop" in2="SourceGraphic" />
            </filter>
        </defs>
        <circle cx="148" cy="148"  r="138" stroke="#ccc" stroke-width="1" fill="#999" />
        <circle cx="148" cy="148" r="135" stroke="#ccc" stroke-width="1" fill="#efefef" filter="url(#inset-drop-shadow)" />
        <circle cx="148" cy="148" r="105" stroke="#ccc" stroke-width="1" fill="#fff" class="shadow" />
    
        <text x="148" y="118" font-size="35" fill="#555">Value</text>
        <text x="148" y="178" font-size="45" fill="#555">100.0<tspan>%</tspan></text>
    
        <path id="arc1" fill="none" stroke="#0f0" stroke-width="27" filter="url(#inset-drop-shadow)" />
        <path id="arc2" fill="none" stroke="#999" stroke-width="10">
            <title>Target 80%</title>
        </path> 
    </svg>
</div>

适配效果说明

  • 当父容器宽度缩小时,SVG内部的所有圆形、文字、阴影效果会等比缩小,不会出现边缘截断的问题
  • 如果父容器不是正方形,SVG内容会自动等比适配到容器内的最大可用尺寸,居中显示,不会把圆形拉成椭圆
  • 如果需要让SVG完全填满非正方形的父容器,可以把preserveAspectRatio改为none,但这种模式下对称图形会被拉伸,不适合进度条类的组件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 22:54:02