Search code examples
svgtransformcenter

SVG - how to center a rectangle?


I have a simple SVG with two rectangles. I want the "inner" rectangle to be exactly in the middle of the SVG. By setting x and y attributes to 50% the upper left corner is centred. Instead, I want to center the middle of the rectangle. I've tried setting transform-origin to center but it doesn't work.

<svg width="100" height="100">
   <rect width="100%" height="100%" fill="gold" />
  
  
   <rect width="30" height="30" x="50%" y="50%" fill="green" />
</svg> 

How to achieve such functionality without manually specifying x and y attributes?


Solution

  • The explanation of the code: The x and y coordinates of a rectangle represent the position of the upper left corner. So if you give your rectangle x="50" y="50" this will put the upper left corner of the rectangle in the middle of the SVG canvas. To center the rectangle you need to offset it with half width or height: 50 - (30/2) = 35. The solution is <rect width="30" height="30" x="35" y="35" fill="green" />

    <svg width="100" height="100" viewBox="0 0 100 100">
       <rect width="100%" height="100%" fill="gold" />
       <rect width="30" height="30" x="35" y="35" fill="green" />
    </svg>

    update:

    The op is commenting:

    I would actually prefer to set 50% for x and y instead of doing some math

    In this case you may need to translate your rect, but you still need some math in order to know how much to translate:

    <svg width="100" height="100" viewBox="0 0 100 100">
       <rect width="100%" height="100%" fill="gold" />
       <rect width="30" height="30" x="50%" y="50%" transform="translate(-15,-15)" fill="green" />
    </svg>

    <svg width="100" height="100" viewBox="0 0 100 100">
       <rect width="100%" height="100%" fill="gold" />
       <rect width="30" height="30" x="-15" y="-15" transform="translate(50,50)" fill="green" />
    </svg>

    Yet an other solution would be using a polygon or a path with the center in the origin:

     <svg width="100" height="100" viewBox="0 0 100 100">
           <rect width="100%" height="100%" fill="gold" />
           <polygon points="-15,-15 15,-15 15,15 -15,15" transform="translate(50,50)" fill="green" />
      </svg>