SVG: text inside rect
Asked Answered
E

5

235

I want to display some text inside SVG rect. Is it possible?

I tried

<svg xmlns="http://www.w3.org/2000/svg">
  <g>
    <rect x="0" y="0" width="100" height="100" fill="red">
      <text x="0" y="10" font-family="Verdana" font-size="55" fill="blue"> Hello </text>
    </rect>
  </g>
</svg>

But it does not work.

Evulsion answered 17/7, 2011 at 16:43 Comment(2)
possible duplicate of insert text between a rectangle drawn in svg.Schelling
Does this answer your question? Insert text between a rectangle drawn in SVGOptimistic
S
331

This is not possible. If you want to display text inside a rect element you should put them both in a group with the text element coming after the rect element ( so it appears on top ).

<svg xmlns="http://www.w3.org/2000/svg">
  <g>
    <rect x="0" y="0" width="100" height="100" fill="red"></rect>
    <text x="0" y="50" font-family="Verdana" font-size="35" fill="blue">Hello</text>
  </g>
</svg>
Sikang answered 18/7, 2011 at 11:59 Comment(9)
Is there a way to not have to manually set height and width on the rect?Edwardedwardian
Depends on the situation and what you mean by 'manually'. You can script in in JavaScript if you like (see narendra's answer below)Sikang
Using my html knowledge - which might well not apply here - it seems like the g element has an implicit size here and I'd like the rectangle to expand to it's size.Edwardedwardian
The group fits to its content not the other way. I think the elements are still relative to the parent svg.Blondellblondelle
is the group element important here?Heliostat
@dmo, No at all. However, it may be useful when we want to do styling or transformation that affects for both rect and text elements as a group.Acronym
@GeorgeMauer Width and Height can be set to 100% instead of 100, which is much better.Tuberculosis
Great answer, this solution worked in my case as well. Thank you! Also, I did specify a group as the answer mentions.Sunless
I think this is a better case for me - codepen.io/techhysahil/pen/POJWpWTenantry
W
75

Programmatically using D3:

body = d3.select('body')
svg = body.append('svg').attr('height', 600).attr('width', 200)
rect = svg.append('rect').transition().duration(500).attr('width', 150)
                .attr('height', 100)
                .attr('x', 40)
                .attr('y', 100)
                .style('fill', 'white')
                .attr('stroke', 'black')
text = svg.append('text').text('This is some information about whatever')
                .attr('x', 50)
                .attr('y', 150)
                .attr('fill', 'black')
Wiggins answered 13/8, 2012 at 13:17 Comment(5)
This produces markup that displays like OP wants, but it doesn't do what OP is trying to do (which isn't legal). This still produces <svg><rect/><text/></svg>.Collectivize
Javascript != SVG. The question is tagged with svg, text and rect. Nothing indicates that the user has access to a programming language. (Making this remark since I came here looking for a static solution.)Gymnosophist
While its true this doesn't pertain to the question me and apparently many other people came here for D3Grape
Is it possible to autofit the rect to the width of the textEnrika
@Colin D That's what I am looking for too. But It looks impossible to expect it done automatically. Instead, we have to do so manually by ourselves to achieve that. It will need some measurements of dimension (width and/or height) of both elements (rect and text).Acronym
B
35

You can use foreignobject for more control and placing rich HTML content over rect or circle

    <svg width="250" height="250" xmlns="http://www.w3.org/2000/svg">
        <rect x="0" y="0" width="250" height="250" fill="aquamarine" />
        <foreignobject x="0" y="0" width="250" height="250">
            <body xmlns="http://www.w3.org/1999/xhtml">
                <div>Here is a long text that runs more than one line and works as a paragraph</div>
                <br />
                <div>This is <u>UNDER LINE</u> one</div>
                <br />
                <div>This is <b>BOLD</b> one</div>
                <br />
                <div>This is <i>Italic</i> one</div>
            </body>
        </foreignobject>
    </svg>

enter image description here

Binal answered 20/8, 2019 at 6:18 Comment(3)
Unlike the text-tags-only option, this one actually placed the text inside the path instead of hiding it in some invisible space above it! The x and y attributes weren't necessary for me but the width and height were or it also was nowhere to be seen!Korte
This is a fantastic answer. Only drawback is that IE11 doesn't support foreignObject; but support for this browser is going away, so this might not be an issue. It is way simpler than using a bunch of tspan.Clermontferrand
Dont use foreignObject, its not supported properly, and likely never will be with browsers like Safari. It has bugs since a decade back bugs.webkit.org/show_bug.cgi?id=23113Metalline
W
6
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
    <g>
  <defs>
    <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" style="stop-color:rgb(145,200,103);stop-opacity:1" />
      <stop offset="100%" style="stop-color:rgb(132,168,86);stop-opacity:1" />
    </linearGradient>
  </defs>
  <rect width="220" height="30" class="GradientBorder" fill="url(#grad1)" />
  <text x="60" y="20" font-family="Calibri" font-size="20" fill="white" >My Code , Your Achivement....... </text>
  </g>
</svg> 
Wiggins answered 13/8, 2012 at 13:21 Comment(0)
B
3

Programmatically display text over rect using basic Javascript

 var svg = document.getElementsByTagNameNS('http://www.w3.org/2000/svg', 'svg')[0];

        var text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
        text.setAttribute('x', 20);
        text.setAttribute('y', 50);
        text.setAttribute('width', 500);
        text.style.fill = 'red';
        text.style.fontFamily = 'Verdana';
        text.style.fontSize = '35';
        text.innerHTML = "Some text line";

        svg.appendChild(text);

        var text2 = document.createElementNS('http://www.w3.org/2000/svg', 'text');
        text2.setAttribute('x', 20);
        text2.setAttribute('y', 100);
        text2.setAttribute('width', 500);
        text2.style.fill = 'green';
        text2.style.fontFamily = 'Calibri';
        text2.style.fontSize = '35';
        text2.style.fontStyle = 'italic';
        text2.innerHTML = "Some italic line";

       
        svg.appendChild(text2);

        var text3 = document.createElementNS('http://www.w3.org/2000/svg', 'text');
        text3.setAttribute('x', 20);
        text3.setAttribute('y', 150);
        text3.setAttribute('width', 500);
        text3.style.fill = 'green';
        text3.style.fontFamily = 'Calibri';
        text3.style.fontSize = '35';
        text3.style.fontWeight = 700;
        text3.innerHTML = "Some bold line";

       
        svg.appendChild(text3);
    <svg width="510" height="250" xmlns="http://www.w3.org/2000/svg">
        <rect x="0" y="0" width="510" height="250" fill="aquamarine" />
    </svg>

enter image description here

Binal answered 20/8, 2019 at 7:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.