0

I am trying to create a svg pattern where size of it is relative to shape to which is applied. Pattern should consist of rect with linearGradient and text elements which repeats in x-axis n-times or every n pixels and is vertically aligned in middle of rect. The results should look like this. Result I want

I have tried following approaches.

<svg width="100%" height="100">
    <defs>
        <linearGradient id="gradient" x1="0%" x2="0%" y1="0%" y2="100%">
            <stop offset="0%" stop-color="#fff" />
            <stop offset="100%" stop-color="#c6c6c6" />
        </linearGradient>
        <pattern id="pattern" width="25%" height="100%">
            <rect width="100%" height="100%" fill="url(#gradient)"></rect>
            <text x="10" y="50%" dx=50 fill="red">test</text>
        </pattern>
    </defs>
    <rect width="1000" height="100" fill="url(#pattern)"></rect>
</svg>

This approach gives the result I want but the size of pattern is not relatve to shape to which is applied and fails when shape is resized, to solve this issue I have tried to create a pattern with patternContentUnits="objectBoundingBox" but then I am having problems positioning the text.

<svg width="100%" height="100%">
    <defs>
        <linearGradient id="gradient" x1="0%" x2="0%" y1="0%" y2="100%">
            <stop offset="0%" stop-color="#fff" />
            <stop offset="100%" stop-color="#c6c6c6" />
        </linearGradient>
        <pattern id="pattern" patternContentUnits="objectBoundingBox" width="25%" height="100%">
            <rect width="1" height="1" fill="url(#gradient)"></rect>
            <text x="0.1" y="0.5">test</text>
        </pattern>
    </defs>
    <rect width="1000" height="100" fill="url(#pattern)"></rect>
</svg>
  • Yes you are right, but no matter what you put it there like 0.2 or something still doesn't show up, I will edit the question so others don't take in consideration this fact. –  Aug 02 '22 at 19:36

1 Answers1

1

objectBoundingBox units are in the range [0, 1] so 10 is too big.

You'll need to use a suitable font-size too.

<svg width="100%" height="100%">
    <defs>
        <linearGradient id="gradient" x1="0%" x2="0%" y1="0%" y2="100%">
            <stop offset="0%" stop-color="#fff" />
            <stop offset="100%" stop-color="#c6c6c6" />
        </linearGradient>
        <pattern id="pattern" patternContentUnits="objectBoundingBox" width="25%" height="100%">
            <rect width="1" height="1" fill="url(#gradient)"></rect>
            <text transform="scale(0.2, 1)" x="0.1" y="0.5" font-size="0.1">test</text>
        </pattern>
    </defs>
    <rect width="1000" height="100" fill="url(#pattern)"></rect>
</svg>
Robert Longson
  • 118,664
  • 26
  • 252
  • 242
  • It is still not showing the text, [0,1] I thought is only for size and positioning didn't know that is for font as well, thanks for that information. –  Aug 02 '22 at 20:05
  • The text shows for me when I run the snippet on Firefox. I see it on Chrome on mobile too. – Robert Longson Aug 02 '22 at 20:15
  • Firefox is showing but Chrome desktop and Edge desktop no! –  Aug 02 '22 at 20:38
  • Just tried Chrome desktop, works fine for me. – Robert Longson Aug 02 '22 at 20:48
  • Chrome has a longstanding bug related to small font sizes. If a `font-size` (in combination with any `transform` attributes on the text element) is lower than 0.5, there is a good chance that it won't be rendered. This makes it very tricky to use `` elements in `objectBoundingBox` situations. Sometimes you can trick it using a `viewBox`, but in this pattern case that workaround isn't suitable. If your text is static, my suggestion is to convert your text to a path. Then the problem will disappear. – Paul LeBeau Aug 03 '22 at 01:18
  • Yep to me in Chrome is not working in Desktop, in mobile it was working though. But however this is not a good solution because I want font-size to be static not relative to the size of the shape, because the shape is resizable and then the font can get a size that I don't want it to have! –  Aug 03 '22 at 08:05
  • Sounds like the text should not be part of the pattern. I guess you can just draw repeated text via javascript and clip it to the shape. – Robert Longson Aug 03 '22 at 08:08
  • I was trying to solve the issue without javascript, but if there is not any other solution then I will go that way, if I go that way I don't need pattern at all, I can just reference gradient directly to the shape. –  Aug 03 '22 at 08:18
  • It is not only Chromium; if you drop the SVG in VSCode it won't show either until you increase the font-size. – Danny '365CSI' Engelman Aug 03 '22 at 08:43
  • 1
    @Danny'365CSI'Engelman [same thing](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/vscode.md) they are both Chromium. – Robert Longson Aug 03 '22 at 08:50