Search code examples
svgflexboxcss-grid

Responsive SVG that is both vertically and horizontally centered while keeping its aspect ratio / original size


I try to achieve the following things for my SVG:

  1. responsive (I use viewBox and no width/height on the svg element, which works great)
  2. both vertically and horizontally centered (the hard part)
  3. centering the SVG should keep its original aspect size / aspect ratio

I made a jsfiddle demo for illustration (easier to navigate as the built-in SO code snippet): https://jsfiddle.net/McTell/gjx9pcon/3/ (Make sure to set the Editor layout to right results under settings, this makes it easier to change the canvas size by dragging the tile divider line)

As you can see, the canvas sits at the very top and it is horizontally filling the entire width of the viewport, which makes it technically horizontally centered. Moreover, if you click on the button, the black rectangle will move down leaving the canvas halfway, which is the behavior I want.

Now I tried to introduce a centered vertical alignment by adding the following CSS (which is commented-out on jsfiddle):

svg {
  position:fixed;
  height:100%;
  width:100%;
}

This will bring the entire SVG canvas in a vertical and horizontal centered position but it will break the original boundaries of the SVG (as you can see by the background color and the red border). If you click the button now, the black rectangle will also not leave the canvas, as the canvas is now the entire viewport.

My goal is to get horizontal and vertical centered alignment without breaking the SVG. I’m terrible in flexbox and grid, but I guess this may be the right path?

Thank you for any help on this!

EDIT (Add SO Code Snippet)

Open the code snippet "Full Page" and make sure you open your dev tools or rescale your browser. You will see that the SVG is not vertically centered. For playing around, use the jsfiddle version.

svg {
      background-color:teal;
      border: 3px solid red;

      /* This will destroy the SVG canvas, enable to see effect: */
      /* position:fixed;
      height:100%;
      width:100% */
    }
<svg id="my-svg" viewBox="0 0 1920 1080">
</svg>


Solution

  • One way is to use flex-box.

    First you need to make your container element (in this case <body>) the full height of the window. Then use display: flex and align-items: center to center the SVG vertically.

    body {
      height: 100vh;
      display: flex;
      align-items: center;
    }
    

    https://jsfiddle.net/tyLub19n/

    Update

    To make it responsive vertically as well, give the SVG a max-height, and add justify-content: center to the body CSS.

    svg {
      background-color:teal;
      border: 3px solid red;
      max-height: 100vh;
    }
    
    body {
      height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    

    https://jsfiddle.net/3jyzoxb7/