Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Responsive fit to box SVG using VH expressed height

I would like to be able to fit my SVG graph to my div in the way aspectratio is ignored (fit to screen). However, when I change the window width, my chart goes out of my yellow box. How can I correct this keeping using a vh-expressed div height ?

not fitted graph to the yellow box

.svg-container {
  display: inline-block;
  position: relative;
  width: 100%;
  height: 60vh;
  /* aspect ratio */
  vertical-align: top;
  overflow: hidden;
  background-color: yellow;
}
.svg-content-responsive {
  display: inline-block;
  position: absolute;
  top: 10px;
  left: 0;
}
.line {
  fill: none;
  stroke: steelblue;
  stroke-width: 1.5px;
}
<div class="container-fluid" data-ng-swipe-left="showMenu.value = true" data-ng-swipe-disable-mouse="">
  <div aw-resolve-loader="" ui-view="main" class="view reveal-animation ng-scope">
    <div style="float: left" class="ng-scope"></div>
    <div class="ng-scope ng-isolate-scope">
      <div class="svg-container">
        <svg viewBox="0 0 800 600" preserveAspectRatio="none">
          <path class="line" d="M0,600L114.28571428571428,300L228.57142857142856,562.5L457.1428571428571,225L571.4285714285714,375L800,0"></path>
        </svg>
      </div>
    </div>
  </div>
</div>

Here is my plunker: http://plnkr.co/edit/Ea7AK6kkvAVf8KIsnZwQ

like image 402
Ranumao Avatar asked Jul 31 '15 10:07

Ranumao


People also ask

How do I scale SVG viewBox?

Just set the viewBox on your <svg> , and set one of height or width to auto . The browser will adjust it so that the overall aspect ratio matches the viewBox . Beautiful.

How do I make SVG fit to the parent container 100?

Using both max-width: 100% and max-height: 100% will make the svg always scale to the container without ever overflowing or losing its aspect ratio.

How do I scale SVG size?

We use viewBox to make the SVG image scalable. viewBox = “0 0 100 100”: defines a coordinate system having x=0, y=0, width=100 units and height=100 units. Thus, the SVG containing a rectangle having width=50px and height=50px will fill up the height and width of the SVG image, and all the dimensions get scaled equally.

What is a viewBox SVG?

The viewBox is an attribute of the SVG element in HTML. It is used to scale the SVG element that means we can set the coordinates as well as width and height. Syntax: viewBox = "min-x min-y width height" Attribute Values: min-x: It is used to set the horizontal axis.


1 Answers

The problem is because you are assigning a height in viewport units only to the container but not the actual SVG element. Because of this, the height of your container always remains responsive (as 60vh) but height of the svg element changes depending on the width and the viewBox settings. This makes part of your SVG get clipped due to overflow: hidden on the container element.

You can verify the above by removing overflow: hidden from the container and adding a border to the SVG element.

To fix this issue, just add the below CSS properties to your svg element. This would make sure that the SVG is always only as big as the container.

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

.svg-container {
  display: inline-block;
  position: relative;
  width: 100%;
  height: 60vh;  /* aspect ratio */
  vertical-align: top;
  overflow: hidden;
  background-color: yellow;
}
svg {
  width: 100%;
  height: 100%;
}
.svg-content-responsive {
  display: inline-block;
  position: absolute;
  top: 10px;
  left: 0;
  border: 1px solid;
}
.line {
  fill: none;
  stroke: steelblue;
  stroke-width: 1.5px;
}
<div class="container-fluid" data-ng-swipe-left="showMenu.value = true" data-ng-swipe-disable-mouse="">
  <!-- uiView: main -->
  <div aw-resolve-loader="" ui-view="main" class="view reveal-animation ng-scope">
    <div style="float: left" class="ng-scope"></div>
    <div class="ng-scope ng-isolate-scope">
      <div class="svg-container">
        <svg viewBox="0 0 800 600" preserveAspectRatio="none">
          <path class="line" d="M0,600L114.28571428571428,300L228.57142857142856,562.5L457.1428571428571,225L571.4285714285714,375L800,0"></path>
          <!--rect x="50" y="200" width="250" height="40" /-->
        </svg>
      </div>
    </div>
  </div>
</div>

Another possible option would be to set the parent container to display: block and then set the required dimensions directly to the svg element.

.svg-container {
  display: block;
  position: relative;
  vertical-align: top;
  overflow: hidden;
  background-color: yellow;
}
svg{
  width: 100%;
  height: 60vh; /* aspect ratio */  
}

.svg-container {
  display: block;
  position: relative;
  vertical-align: top;
  overflow: hidden;
  background-color: yellow;
}
.svg-content-responsive {
  display: inline-block;
  position: absolute;
  top: 10px;
  left: 0;
}
svg {
  width: 100%;
  height: 60vh;  /* aspect ratio */
}
.line {
  fill: none;
  stroke: steelblue;
  stroke-width: 1.5px;
}
<div class="container-fluid" data-ng-swipe-left="showMenu.value = true" data-ng-swipe-disable-mouse="">
  <!-- uiView: main -->
  <div aw-resolve-loader="" ui-view="main" class="view reveal-animation ng-scope">
    <div style="float: left" class="ng-scope"></div>
    <div class="ng-scope ng-isolate-scope">
      <div class="svg-container">
        <svg viewBox="0 0 800 600" preserveAspectRatio="none">
          <path class="line" d="M0,600L114.28571428571428,300L228.57142857142856,562.5L457.1428571428571,225L571.4285714285714,375L800,0"></path>
          <!--rect x="50" y="200" width="250" height="40" /-->
        </svg>
      </div>
    </div>
  </div>
</div>
like image 131
Harry Avatar answered Sep 25 '22 01:09

Harry