Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Place square svg to the center of the screen, scale it to fit the screen's width and height with some constraints

Tags:

html

css

svg

It seem to be a silly question and possibly a dupe, but I couldn't find a good solution for a while, so finally dare to ask.

I want to place an <svg> element inside an html document and satisfy the following requirements:

  1. Image is placed as an <svg> html5 element, not an external svg-file. (Actually, I want to dynamically generate it with D3.js.)
  2. Image is placed in the center of the screen, both vertically and horizontally.
  3. Actual size of the image should not exceed some predefined value (like 15cm × 15cm).
  4. If either current screen's width or height is less then 15cm, image should be scaled (preserving aspect ratio) in such a way it fit to screen. No parts of the image should be clipped. Image should be placed in the center.

It's basically the same requirements as described in this article. It says that I should use preserveAspectRatio="xMidYMid", but gives no example on how to do it and how does it correspond to other tricks described in the article. This article suggests preserveAspectRatio="xMidYMid meet", but again I wasn't able to reproduce the examples provided there to meet all my requirements.

My current code is like this but it does not fit in height and does not center vertically.

.svg-container {
  height:100%;
  width:100%;
  max-height:15cm;
  max-width:15cm;
  margin: 0 auto;
}
<div class="svg-container">  
<svg id="picture" preserveAspectRatio="xMidYMid meet" viewBox="0 0 100 100">
  <circle cx=50 cy=50 r=50></circle>
</svg>
</div>
like image 786
Ilya V. Schurov Avatar asked Feb 24 '17 20:02

Ilya V. Schurov


2 Answers

The following works if the aspect ratio of the SVG is a given. If the aspect ratio of the SVG is dynamic, you have to use JavaScript, I believe.

This snippet works in modern browsers and takes full advantage of the relatively new vmin viewport-percentage length. Browser support is pretty good. For horizontal and vertical centering, the flexbox layout mode is leveraged. Again, browser support is pretty good.

The trick is that the dimensions of the SVG are set relative to either the width or the height of the screen, whichever is smallest. This means that even when we would set it to be 100vmin, the SVG is guaranteed to fit the screen (but barely). To enforce maximal dimensions, good old max-width and max-height are used, exactly as they are intended to be used.

html, body {
  /* ensure that all of the viewport is used */
  width: 100%;
  height: 100%;
  /* ensure that no scrollbars appear */
  margin: 0;
  padding: 0;
  
  /* center SVG horizontally and vertically */
  display: flex;
  align-items: center;
  justify-content: center;
}

#picture {
  /* ensure 1:1 aspect ratio, tweak 50 to make SVG larger */
  width: 50vmin;
  height: 50vmin;  
  /* set some maximum size (width and height need to match
   * aspect ratio, 1:1 in this case */
  max-width: 200px;
  max-height: 200px;
}
<svg id="picture" viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="50"></circle>
</svg>
like image 189
Just a student Avatar answered Oct 05 '22 20:10

Just a student


Try this css:

#picture {
  transform: translate(-50%, -50%);
  top: 50%;
  left: 50%;
  position: absolute;
  max-height:15cm;
  max-width:15cm;
  width: 80%;
  height: 80%;
}

here is the result: https://jsfiddle.net/twe9jfkf/

is this what you try to achieve?

like image 36
rifa29 Avatar answered Oct 05 '22 19:10

rifa29