4
<div style="float: left; padding: 10px; border: 1px solid; 
background: #ccc">random text</div>

Is there a way to achieve something like this in SVG? I mean to have a rectangle and a text and:

a) rectangle's width and height are dynamic, so when I change the text, the rectangle adjust its size
b) when I move the rectangle, the text goes with it

And would it be easier to achieve something like this in <canvas>?

EDIT:

<defs>       
    <text id="text1" x="90" y="100" style="text-anchor:start;font-size:30px;">
    THIS IS MY HEADER</text>
</defs>

<filter x="0" y="0" width="1" height="1" id="background">
    <feFlood flood-color="gray"/>
    <feComposite in="SourceGraphic"/>
</filter>

<use xlink:href="#text1" fill="black" filter="url(#background)"/>

Erik Dahlström proposed something like this. How to put padding to the background, how to add eg. shadow or border to the rectangle? And, this doesn't work in IE9, so I cannot accept it. I could just use <foreignObject> if there was a support for it in IE.

And I just figured out the answer for b) point of my question. You have to put both elements in the group:

<g>
    <rect x="0" y="0" width="100" height="100" fill="red"></rect>
    <text x="50" y="50" font-size="14" fill="blue" text-anchor="middle">Hello</text>
</g>

And then you can move the group using transform param:

<g transform="translate(x, y)">

Seems to work correct in every browser.

geehertush01
  • 511
  • 1
  • 8
  • 15

2 Answers2

13

You can use JavaScript to adjust the box:

<svg xmlns="http:/www.w3.org/2000/svg" onload="init()" height="100" width="200">
      <style type="text/css">
        rect {
          stroke:black;
          stroke-width:1;
          fill:#ccc;
        }
      </style>
      <script type="text/javascript">
        var text, rect
        var padding = 10
        function init() {
          text = document.getElementsByTagName("text")[0]
          rect = document.getElementsByTagName("rect")[0]
          adjustRect()
        }
        
        function adjustRect() {
          var bbox = text.getBBox()
          rect.setAttribute("x",bbox.x - padding)
          rect.setAttribute("y",bbox.y - padding )
          rect.setAttribute("width",bbox.width + 2*padding)
          rect.setAttribute("height",bbox.height + 2*padding)
        }
        
      </script>
      <g>
        <rect x="0" y="0" width="100" height="100" fill="red"></rect>
        <text x="50" y="50" font-size="14" fill="blue" text-anchor="middle">Hello</text>
      </g>
    </svg>
    <div>
      <button onclick="text.textContent='Goodbye';adjustRect()">change text</button>
    </div>
Musakkhir Sayyed
  • 7,012
  • 13
  • 42
  • 65
Thomas W
  • 14,757
  • 6
  • 48
  • 67
2

Use an svg filter to draw the background, that will adapt to the size and position of the text. See this answer for a full example.

Community
  • 1
  • 1
Erik Dahlström
  • 59,452
  • 12
  • 120
  • 139