0

I’m still new to SVG, so I’m unclear on the terminology.

Is there an SVG only way of passing on a parameter value to used element? For example I have hard-coded the text Name in the g element, but would like to pass it a value from the use element.

Currently I create the g element without the text and place some text after I use it, but there should be a better way.

I have searched widely on the Internet, but I can’t find anything that’s current or relevant to this application.

Some have suggested using JavaScript, but that’s not a general solution, since I won’t be necessarily plugging in to a browser.

<svg width="160" viewBox="0 0 160 120">
    <defs>
        <g id="test">
            <rect width="60" height="40"/>
            <text x="8" y="24" stroke="none" fill="black">Name</text>
        </g>
    </defs>
    <use href="#test" x="00" y="20" fill="aqua" stroke="blue"/>
    <use href="#test" x="80" y="20" fill="orange" stroke="red"/>
    <text y="100">This space for rent</text>
</svg>
Manngo
  • 14,066
  • 10
  • 88
  • 110
  • Some ideas here: https://stackoverflow.com/questions/1422238/svg-about-using-defs-and-use-with-variable-text-values – ksav Aug 23 '21 at 08:04

4 Answers4

1

The short answer is no.

You can't pass parameters via a <use> element. The nearest you can get to customising a used reference is by inheriting certain style properties from the <use>, such as colour. You certainly can't customise the actual content of elements, without using Javascript.

Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181
0

I understand your problem.

In my experience, you need to pass some parameter and use it like below

function generateSVG(width, hight){
    return `<svg viewBox='0 0 160 120'>` + 
           `<defs>`+
           ...
           `<rect width='${width}' height='${height}'` +
           ...
           `</svg>`;
}

Now you generate svg using this function.

generateSVG(60,40);
0

Using JavaScript is a general solution if you create your own Web Component, supported in all modern Browsers.

<svg-label fill=aqua stroke=blue>Hello Web</svg-label>
<svg-label fill=orange stroke=red>Components!</svg-label>

<script>
  customElements.define("svg-label", class extends HTMLElement {
    connectedCallback() {
      setTimeout(() => { // make sure inner DOM is parsed
        this.innerHTML = `<svg width="160" viewBox="0 0 160 120">
 <rect width="100%" height="40" x="0" y="0" 
       fill="${this.attributes.fill.value}" stroke="${this.attributes.stroke.value}"/>
 <text y="25%" x="8" stroke="none" fill="black">${this.innerHTML}</text>
</svg>`;
      });
    }
  })
</script>
Danny '365CSI' Engelman
  • 16,526
  • 2
  • 32
  • 49
  • I don’t think you can rely on JavaScript if you’re not using a browser. – Manngo Aug 23 '21 at 07:45
  • That requirement is nowhere mentioned in OPs question. I do wonder why he wants SVGs then? A new toy that can print them on paper without a computer? – Danny '365CSI' Engelman Aug 23 '21 at 07:49
  • I _am_ the OP, and I’m not sure that comment about the new toy is entirely helpful. The requirement for a browser wasn’t mentioned either. I wanted an SVG only solution, since I plan to embed the SVG in another technology, but not a web browser. And, yes, it might even be printed on paper. – Manngo Aug 23 '21 at 07:53
0

Not quite what you're after, but you could make some changes to what is a used element, place it inside a group and then just place text on top of it.

<svg width="160" viewBox="0 0 160 120">
    <defs>
        <g id="test">
            <rect width="60" height="40"/>
        </g>
    </defs>
    
    <g transform="translate(0,20)">
        <use href="#test" fill="aqua" stroke="blue" />
        <text x="10" y="25">Name</text>
    </g>
    <g transform="translate(80,20)">
        <use href="#test" fill="orange" stroke="red" />
        <text x="10" y="25">Other</text>
    </g>
    
    <text y="100">This space for rent</text>
</svg>
ksav
  • 20,015
  • 6
  • 46
  • 66