2017-09-15 1 views
-1

Ich versuche, eine große Svg in einem Container Div zu zentrieren, während die Größe der Svg und das Seitenverhältnis zu maximieren.Center große Svg in Container

Aus irgendeinem Grund wird die Svg korrekt angezeigt, aber die Breite und Höhe Attribute sind falsch, als ob die Svg in die gesamte Eltern erweitert.

Wie kann ich es so machen, dass die SVG die richtige Größe hat?

Bitte, das sollte nur mit CSS gelöst werden, kein Javascript.

Beachten Sie auch, dass dies funktioniert, wenn ich die SVG durch ein großes Bild ersetzen.

var info = document.getElementById('info'); 
 
var svg = document.getElementById('svg'); 
 
var box = svg.getBoundingClientRect(); 
 

 
info.textContent = 'the ratio is ' + (box.width/box.height) + ' instead of 2.5! The yellow square is not in the viewBox, so why does it show up?';
.container { 
 
    position: absolute; 
 
    top: 40px; 
 
    left: 40px; 
 
    right: 40px; 
 
    bottom: 40px; 
 
} 
 

 
.svg { 
 
    position: absolute; 
 
    max-height: 100%; 
 
    max-width: 100%; 
 
    top: 50%; 
 
    left: 50%; 
 
    transform: translate(-50%, -50%); 
 
    background-color: gray; 
 
}
<div class="container"> 
 
<svg id="svg" class="svg" width="1000px" height="500px" viewBox="0 0 10 5"> 
 
    <rect width="10" height="5" fill="black" /> 
 
    <rect x="-2" y="2" width="1" height="1" fill="yellow" /> 
 
</svg> 
 
</div> 
 
<div id="info"/>

+0

https://css-tricks.com/scale-svg/ – CBroe

+0

Ich glaube, Sie den gleichen Effekt wie 'Hintergrund-Größe erreichen wollen: cover'. Wenn Sie keine älteren Browser und nur die immergrünen Browser unterstützen möchten, können Sie ['object-fit: cover'] (https://developer.mozilla.org/en-US/docs/Web/CSS/Objekt-Fit). – Terry

+0

@Terry: Nein, ich versuche Objekt-Fit zu tun: enthalten. Nicht sicher, wie das Zeug funktionieren soll.Sobald ich Max-Breite oder Max-Höhe entferne, wird die SVG einfach zu groß –

Antwort

1

In gewisser Hinsicht ist Ihr svg bereits in seinem Behälter passend so, wie Sie es wollen. In der Tat können die meisten CSS, die Sie definiert haben, weggelassen werden. Das SVG-Element sollte mit width: 100%, height: 100% definiert werden, so dass das <svg> Element selbst die gleiche Größe wie sein Container hat. Dann wird der durch viewBox definierte Bereich in das Ansichtsfenster gemäß dem Attribut preserveAspectRatio="xMidYMid meet" gerendert. (Implizit verwendet, das ist der Standardwert): Seitenverhältnis beibehalten, maximale Größe, die hineinpasst, in der Mitte positioniert.

Das Problem mit dem gelben rect stellt sich nur, weil der Gehalt an den Rand des Ansichtsfensters , nicht abgeschnitten wird, um die viewBox. Inhalte, die im SVG definiert sind, aber außerhalb der viewBox, sind möglicherweise noch sichtbar.

(Es war zunächst die Idee, ein clip style-Attribut auf das <svg> Element zu unterstützen, aber ihr Konzept war so verworren, dass unbrauchbar war, ist es nun veraltet.)

Die beste Lösung ist es nun, Wickeln Sie das <svg> Element mit einem anderen <svg>. Der innere erhält absolute Werte für Breite und Höhe, der äußere erhält dieselben Werte wie eine viewBox und width: 100%, height: 100%.

Wie Sie sehen können, klammert der innere Svg den Inhalt an den Rändern, und der äußere svg passt den Inhalt in den Container.

Beachten Sie, dass Sie ein CSS background-color auf der inneren Svg nicht definieren können. Dies ist nur für HTML definiert und funktioniert nur auf dem äußeren, da es ein direktes Kind eines HTML-Elements ist. Wenn Sie einen farbigen Hintergrund wünschen, definieren Sie ein Rechteck, das den Bereich der viewBox mit einer entsprechenden fill abdeckt.

.container { 
 
    position: absolute; 
 
    top: 40px; 
 
    left: 40px; 
 
    right: 40px; 
 
    bottom: 40px; 
 
} 
 

 
#svg1 { 
 
    height: 100%; 
 
    width: 100%; 
 
    background-color: gray; /* clipped at the borders of the container! */ 
 
}
<div class="container"> 
 
    <svg id="svg1" class="svg" viewBox="0 0 10 5"> 
 
    <svg id="svg2" width="10" height="5"> 
 
     <rect width="10" height="5" fill="black" /> <!--this is your background--> 
 
     <rect x="-2" y="2" width="1" height="1" fill="yellow" /> 
 
     <ellipse cx="5" cy="2.5" rx="6" ry="3" 
 
       fill="none" stroke="blue" stroke-width="0.2" /> 
 
    </svg> 
 
    </svg> 
 
</div> 
 
<div id="info"/>