固定高度动态宽度的响应式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
相关产品推荐
相关产品推荐

