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

固定高度动态宽度的响应式SVG如何让填充图案保持宽高比?

问题描述

我希望在HTML文档中定义一个内联<svg>,它具有固定高度(如50px)和动态宽度(如100%),内部包含一个填充了图案(如棋盘格图案)的polyline。我希望polyline能缩放至填满<svg>区域(即不保留自身宽高比),但希望图案保持宽高比(使棋盘格中的方块保持方形)。我注意到<pattern>有preserveAspectRatio属性,但直接将其设置为xMinYMin meet似乎没有效果,如下代码片段所示:

svg {
  height: 50px;
  width: 100%;
}
<svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="none">
    <defs>
        <pattern id="pattern-checked" x="0" y="0" width="40" height="40" patternUnits="userSpaceOnUse" preserveAspectRatio="xMinYMin meet">
            <rect x="0" y="0" width="20" height="20" fill="black" />
            <rect x="20" y="20" width="20" height="20" fill="black" />
        </pattern>
    </defs>
    <polyline fill="url(#pattern-checked)" points="0,100 20,50 50,0 70,30, 100,100" />
</svg>

请问有没有办法实现这一需求(理想情况下不依赖获取元素实际宽度的JS)?

解决方案

核心问题在于patternUnits="userSpaceOnUse"会让图案基于SVG的用户坐标系定位,而SVG的preserveAspectRatio="none"会拉伸整个坐标系,导致图案也被拉伸。要让图案保持方形,需要改用patternContentUnits="objectBoundingBox",并结合viewBox和preserveAspectRatio控制图案缩放行为,同时保留patternUnits="userSpaceOnUse"确保图案在拉伸的polyline上重复时比例正确。

修改后的代码如下:

svg {
  height: 50px;
  width: 100%;
}
<svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="none">
    <defs>
        <pattern id="pattern-checked" x="0" y="0" width="20" height="20" 
                 patternUnits="userSpaceOnUse"
                 patternContentUnits="objectBoundingBox"
                 viewBox="0 0 1 1" preserveAspectRatio="xMinYMin meet">
            <rect x="0" y="0" width="0.5" height="0.5" fill="black" />
            <rect x="0.5" y="0.5" width="0.5" height="0.5" fill="black" />
        </pattern>
    </defs>
    <polyline fill="url(#pattern-checked)" points="0,100 20,50 50,0 70,30, 100,100" />
</svg>

关键修改说明:

  • patternContentUnits="objectBoundingBox":让图案内部元素使用相对图案自身边界的比例坐标(0到1范围),而非绝对用户空间坐标。
  • 给<pattern>添加viewBox="0 0 1 1"和preserveAspectRatio="xMinYMin meet":强制图案内容保持1:1宽高比,即便SVG拉伸导致图案的width/height变化,棋盘格方块仍能保持方形。
  • 调整图案内<rect>尺寸为0.5(即图案大小的一半),确保棋盘格比例正确。

若需要调整图案大小,直接修改<pattern>的width和height值即可,比如设为10,棋盘格方块会变小但依然保持方形。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 14:12:46