user1739757
user1739757

Reputation:

Responsively center SVG element inside another SVG element?

I'm trying to do something very simple in SVG:

  1. Divide the entire viewport into two rectangles
  2. Each rectangle should have a width 50% of the viewport's width
  3. Each rectangle should have a height 100% of the viewport's height
  4. In the center of each rectangle, draw another rectangle 100px wide and 40px high
  5. The center of each of these "child" rectangles, for lack of a better term, should be aligned with the center of their respective "parent" rectangles--at any viewport size.

Here's an example of what I'd like to achieve, but using <text> elements instead of <rect> elements:

<svg version="1.1" width="100%" height="100%">

  <svg x="0" y="0" width="50%" height="100%" overflow="visible">
    <rect x="0" y="0" width="100%" height="100%" fill="#363636"></rect>
    <text x="50%" y="50%" text-anchor="middle" text-color="#393939">Sign In</text>
  </svg>

  <svg x="50%" y="0" width="50%" height="100%" overflow="visible">
    <rect x="0" y="0" width="100%" height="100%" fill="#999999"></rect>
    <text x="50%" y="50%" text-anchor="middle">Sign Up</text>
  </svg>

</svg>

How can I do this with rectangles--or any SVG shape, for that matter?

Upvotes: 4

Views: 8033

Answers (1)

user1739757
user1739757

Reputation:

It turns out the secret to responsive SVG design is to have each object on the screen be its own <svg> element. In other words, use <svg> as a group tag.

Why? Because <svg> elements can be positioned using percentages.

To position the <svg> by its center rather than its upper, left-hand corner, use its transform="translate(dx,dy)" property.

In the case of our example, putting the text and "child" rectangles inside their own <svg> parent, and then transforming that, pulls off the desired effect:

<svg version="1.1" width="100%" height="100%">

  <!-- Left Column -->
  <svg x="0" y="0" width="50%" height="100%" overflow="visible">

    <!-- "Parent" Rectangle -->
    <rect x="0" y="0" width="100%" height="100%" fill="#363636"></rect>

    <!-- "Child" Rectangle with Text -->
    <svg x="50%" y="50%" width="116" height="40" overflow="visible">
      <rect x="0" y="0" width="100%" height="100%" rx="20" ry="20" fill="#FFFFFF" transform="translate(-58, -25)"></rect>
      <text x="0" y="0" text-color="#393939" transform="translate(-29, 0)">Sign Up</text>
    </svg>

  </svg>

  <!-- Right Column -->
  <svg x="50%" y="0" width="50%" height="100%" overflow="visible">

    <!-- "Parent" Rectangle -->
    <rect x="0" y="0" width="100%" height="100%" fill="#999999"></rect>

    <!-- "Child" Rectangle with Text -->
    <svg x="50%" y="50%" width="100" height="40" overflow="visible">
      <rect x="0" y="0" width="100%" height="100%" rx="20" ry="20" fill="#FFFFFF" transform="translate(-50, -25)"></rect>
      <text x="0" y="0" text-color="#393939" transform="translate(-25, 0)">Sign In</text>
    </svg>

  </svg>

</svg>

( Tested in Mac OS X Chrome 39.0 and iOS 8.1.2 Safari )

Upvotes: 1

Related Questions