Wie kann ein <svg> -Element in seinem übergeordneten Container erweitert oder verkleinert werden?

112

Ziel ist es, das <svg>Element auf die Größe seines übergeordneten Containers zu erweitern, in diesem Fall a <div>, egal wie groß oder klein dieser Container sein mag.

Der Code:

<style>
    svg, #container{
        height: 100%;
        width: 100%;
    }
</style>

<div id="container">
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" >
         <rect x="0" y="0" width="100" height="100" />
    </svg>
</div>

Die häufigste Lösung für dieses Problem scheint darin zu bestehen, das viewBoxAttribut für das <svg>Element festzulegen.

viewBox="0 0 widthOfContainer heightOfContainer"

Dies scheint jedoch nicht zu funktionieren, wenn Elemente innerhalb des <svg>Elements vordefinierte Breiten und / oder Höhen haben. Beispielsweise werden für das <rect>Element im obigen Code Breite und Höhe explizit festgelegt.

Die naheliegende Lösung besteht also darin, auch für diese Elemente% widths und% height zu verwenden. Aber muss das überhaupt gemacht werden? Zumal es gut <img src=test.svg >funktioniert und sich ohne Probleme mit explizit eingestellten <rect>Höhen und Breiten problemlos ausdehnt / zusammenzieht .

Wenn Elemente wie <rect>und andere Elemente wie diese ihre Breiten und Höhen in Prozent definieren müssen, gibt es in Inkscape eine Möglichkeit, sie so festzulegen, dass alle Elemente mit dem <svg>Dokument prozentuale Breiten, Höhen usw. anstelle fester Abmessungen verwenden ?

user782860
quelle
1
Speichern Sie das SVG als Datei, und verweisen Sie es dann als Bild, wie z. B. <img src = "file.svg" />. Auf diese Weise können Sie Breite: 100% oder Höhe: 100% verwenden
Burimi

Antworten:

56

Das viewBoxist nicht die Höhe des Containers, sondern die Größe Ihrer Zeichnung. Definieren Sie viewBoxeine Breite von 100 Einheiten rectund eine Einheit von 10 Einheiten. Unabhängig davon, wie groß Sie das SVG skalieren, beträgt rectdie Bildbreite 10%.

Robertc
quelle
33
Die Frage ist aber: Wie skaliere ich die SVG?
Adrian Heine
6
@AdrianLang Die Skalierung erfolgt automatisch, wenn Sie eine Größe für das SVG-Objekt festlegen, wie dies bereits im Code in der Frage erfolgt. Hier ist eine feste Version des Beispiels .
Robertc
Du hast recht, großartig, das funktioniert tatsächlich bei mir. Ich denke, mein Problem waren die Eigenschaften für Höhe und Breite in meinem SVG-Stammelement.
Adrian Heine
2
Ich habe einige kleinere Änderungen an dieser Geige vorgenommen, damit die Größenänderung horizontal und vertikal erzwungen wird, ohne das Seitenverhältnis beizubehalten, und sie im IE funktioniert, während die eingereichte Geige @robertc dies nicht tat. Hoffe, es wird jemandem auf der Straße helfen!
Mister Crimson
3
Standardmäßig wird Ihr SVG so groß wie möglich skaliert, sodass es vollständig sichtbar ist, aber das Seitenverhältnis beibehält (sodass eine quadratische Ansichtsbox ein rechteckiges übergeordnetes Element nicht vollständig ausfüllt). Wenn Sie wirklich erzwingen möchten, dass der übergeordnete Container vollständig abgedeckt wird, fügen Sie dem SVG-ElementerveAspectRatio = "none" hinzu .
Patricksurry
24

Angenommen, ich habe eine SVG, die so aussieht: pic1

Und ich möchte es in ein Div einfügen und es das Div als Antwort füllen lassen. Meine Vorgehensweise ist wie folgt:

Zuerst öffne ich die SVG-Datei in einer Anwendung wie inkscape. Unter Datei-> Dokumenteigenschaften stelle ich die Breite des Dokuments auf 800 Pixel und die Höhe auf 600 Pixel ein (Sie können andere Größen auswählen). Dann passe ich die SVG in dieses Dokument ein.

pic2

Dann speichere ich diese Datei als neue SVG-Datei und erhalte die Pfaddaten aus dieser Datei. In HTML lautet der Code, der die Magie ausübt, wie folgt:

<div id="containerId">    
    <svg
    id="svgId" 
    xmlns:svg="http://www.w3.org/2000/svg"
    xmlns="http://www.w3.org/2000/svg"
    version="1.1"
    x="0"
    y="0"
    width="100%"
    height="100%"
    viewBox="0 0 800 600"
    preserveAspectRatio="none">
       <path d="m0 0v600h800v-600h-75.07031l-431 597.9707-292.445315-223.99609 269.548825-373.97461h-271.0332z" fill="#f00"/>
    </svg>
</div>

Beachten Sie, dass Breite und Höhe von SVG beide auf 100% festgelegt sind, da der Container vertikal und horizontal gefüllt werden soll. Breite und Höhe der Ansichtsbox entsprechen jedoch der Breite und Höhe des Dokuments in inkscape (800 x X) 600px. Als nächstes müssen Sie daserveAspectRatio auf "none" setzen. Wenn Sie weitere Informationen zu diesem Attribut benötigen, finden Sie hier einen guten Link . Und das ist alles.

Eine weitere Sache ist, dass dieser Code auf fast allen gängigen Browsern funktioniert, auch auf den alten. Bei einigen Versionen von Android und iOS müssen Sie jedoch Javascrip / jQuery-Code verwenden, um die Konsistenz zu gewährleisten. Ich verwende die folgenden Funktionen für Dokumentbereitschaft und Größenänderung:

$('#svgId').css({
    'width': $('#containerId').width() + 'px',
    'height': $('#containerId').height() + 'px'
});

Ich hoffe es hilft!

Reza Baradaran Gazorisangi
quelle
5
+1 für den ErhaltAspectRatio-Hinweis. Nachdem ich hoch und niedrig gejagt hatte, um eine SVG tatsächlich zu einem Div zu strecken (nicht zu skalieren), war dies die richtige Antwort.
Adelphus
@ Gazoris, Danke für diese wundervolle Antwort. habe frage zum selben. Was ist, wenn mein SVG verschachtelt ist? Zum Beispiel möchte ich <svg> <svg id = "1"> </ svg> <svg id = "2"> </ svg> </ svg> svg 1 und 2 bedingt anzeigen und es sollte Breite und Höhe annehmen des Behälters. <div id = "container" style = "width: 200px; height: 200px;"> </ div> können Sie mir bitte dabei helfen.
Prasad Parab
@ Reza Baradaran: Genie.
DanMad
6

Was in letzter Zeit für mich funktioniert hat, ist, alle height=""und width=""Attribute aus dem <svg>Tag und allen untergeordneten Tags zu entfernen . Anschließend können Sie die Skalierung anhand eines Prozentsatzes der Höhe oder Breite des übergeordneten Containers verwenden.

Geoff Colbath
quelle
5
Können Sie ein funktionierendes Beispiel geben? Ich kann das nicht dazu bringen, irgendetwas zu tun.
Michael
2

@robertc hat es richtig gemacht, aber Sie müssen auch beachten, svg, #containerdass das SVG exponentiell für alles andere als 100% skaliert wird (einmal für #containerund einmal für svg).

Mit anderen Worten, wenn ich 50% h / w auf beide Elemente angewendet habe, sind es tatsächlich 50% von 50% oder 0,5 * 0,5, was einer Skala von 0,25 oder 25% entspricht.

Ein Selektor funktioniert einwandfrei, wenn er wie von @robertc vorgeschlagen verwendet wird.

svg {
  width:50%;
  height:50%;
}
Justin Putney
quelle
Das ist , weil Ihr Selektor svg, #containerpaßt sowohl das svgDOM - Element und das #containerDOM - Element. Ich glaube, Sie haben stattdessen gesucht svg #container, aber die Angabe eines Elternteils ist nicht erforderlich, wenn Sie trotzdem eine ID verwenden.
Nit
Ist das nicht genau das, was ich gesagt habe, "einmal für #container und einmal für svg"?
Justin Putney
1
Oh Verzeihung, Sie haben Recht, aber Ihre Antwort ist etwas seltsam formuliert, was zu Missverständnissen führt. Es hört sich so an, als würden Sie zuerst von einem möglichen Fall sprechen.
Nit
1

Für Ihr iPhone könnten Sie in Ihrem Kopf balise verwenden:

"width=device-width"
Vincent
quelle