Responsives INLINE-SVG – Inhalt von SVG muss die Breite des übergeordneten Elements ausfüllen

Lesezeit: 6 Minuten

Benutzer-Avatar
Schüchtern

TOR:

Ich versuche eine zu bekommen INLINE SVG -Element, um die volle verfügbare Breite des übergeordneten Elements auszufüllen. Ich kann den gleichen Effekt leicht mit einem erzielen img und object -Tag, um auf die SVG-Datei zu verweisen, aber ich möchte verwenden inline svg weil ich die inneren SVG-Elemente mit Javascript animiere.

PROBLEM:

Ich kann dies in Firefox und mit einigen Optimierungen auch in Chrome erreichen, aber Safari und IE9 & IE10 spielen nicht mit.

  • Der innere Inhalt von svg füllt das svg-Element nicht immer in allen Bildschirmbreiten
  • Webkit fügt eine mysteriöse Auffüllung/Höhe hinzu (in diesem Beispiel befindet sich die Auffüllung innerhalb des SVG-Elements). Die Höhe des SVG-Elements sollte automatisch sein und den inneren SVG-Inhalt umschließen.

Hauptfrage:

Gibt es eine browserübergreifende Lösung für responsives INLINE SVG: Sehen Sie sich das Beispiel in IE9 & 10 und -webkit-Safari an und beachten Sie die nicht erforderliche zusätzliche Höhe innerhalb des SVG-Elements (Cyan-Farbe).

http://jsfiddle.net/David_Knowles/9tUAd/

<div class="block">stuff</div> 
<div class="wrap">
    <svg version="1.1" baseProfile="basic" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 550 350" xml:space="preserve" preserveAspectRatio="xMinYMin meet">

        <rect x="0" y="0" width="550" height="350"/>
        <polyline points="0,0 0,350 550,350"/>
        <text x="0" y="50%" fill="#ffffff" stroke="none" width="100%">The text</text>
    </svg>
</div>
<div class="block">stuff</div> 

  • Versuchen Sie, sogar die Viewbox anzupassen. In einem Projekt von mir hatte ich ein ähnliches Problem und ich löste die Anpassung der Größe des Bildes und seiner Viewbox mit JS

    – Max Markson

    11. Juni 2013 um 14:19 Uhr

Benutzer-Avatar
Ben

Das erste Problem ist, dass Sie Ihre einstellen .svg-wrap div auf 100 % Höhe. 100% von was? In diesem Fall ist das übergeordnete Element dieses div das body-Element. Wenn Sie Inhalte auf Blockebene haben, die 100 % der Körperhöhe ausmachen, und andere In-Flow-Elemente, haben Sie immer eine vertikale Bildlaufleiste. weil Sie immer einen Inhalt von 100% + Ihre haben werden .stuff Elemente. Nur als allgemeiner Tipp, ein konstanter Überlauf wie dieser sollte der Hinweis darauf sein, dass etwas in Ihrem CSS wackelig ist.

Fahren Sie weiter mit dem DOM fort, der 100% Höhenangabe auf Ihrer svg Element zwingt die svg um sich auf die übermäßig hohe Verpackung auszudehnen. Und das ist ein weiterer Teil des Täters.

Die Lösung, die ich verwende, beinhaltet intrinsische Verhältnisse. CSS so:

.svg-wrap {
    background-color:red;
    height:0;
    padding-top:63.63%; /* 350px/550px */
    position: relative;
}

svg {
    background-color: cyan;
    height: 100%;
    display:block;
    width: 100%;
    position: absolute;
    top:0;
    left:0;
}

http://jsfiddle.net/pcEjd/

Getestet in den neuesten Versionen, FF, Chrome, Safari (jedoch nicht IE).

Die Nachteile dieses Ansatzes sind:

a) Sie müssen die Verhältnisse für alle Ihre Boxen vorberechnen oder ein Skript schreiben, das dies tut. Nicht so schlecht.

b) Sie können nicht verwenden border-box global mit der Sternauswahl, oder wenn Sie die Boxgröße wieder überschreiben müssen content-box für Ihre SVG-Container. Machbar.

Als Randnotiz ist dies offensichtlich nicht so, wie die Dinge funktionieren sollen. Browser sollten schlau genug sein, sich das SVG-Attribut viewBox anzusehen, um die Proportionen zu erhalten, die berechnete Breite zu berechnen (nach allen maxWidth-Grenzen) und dann die Höhe zu berechnen.

Aber aktuell funktioniert das nicht so. Es gibt einen weiteren seltsamen Fehler in Chrome, bei dem das Hinzufügen von max-width:100% zum SVG erzeugt eine Situation, in der das SVG immer die kleinste gerenderte Größe hat. Versuchen Sie, diese Geige in Chrome zu laden:

http://jsfiddle.net/ynmey/1/

Und Sie werden überhaupt kein SVG sehen! Seltsam. Noch seltsamer, schalten Sie das aus max-width -Deklaration in Dev Tools und spielen Sie dann mit der Breite des „Ergebnis“-Ansichtsfensters in jsfiddle. Nehmen Sie es etwas schmaler, dann breiter, dann schmaler, dann breiter. Beachten Sie, dass die SVG-Datei, sobald sie kleiner wird, nicht wieder vergrößert wird, wenn das Ansichtsfenster größer wird!

Dies ist wichtig zu beachten, denn:

 * {max-width:100%}

ist ein gängiger (und völlig legitimer) responsiver Designansatz und richtet derzeit mit SVG in Blink Chaos an. Bleiben Sie also vorerst bei den intrinsischen Verhältnissen.

  • Danke Ben. Ich habe die JS-Lösung verwendet, da ich damit bereits begonnen habe. Ihre Bestätigung der Symptome ist sehr hilfreich und die zusätzliche Recherche sehr wertvoll. Das funktioniert!

    – Schüchtern freundlich

    11. September 2013 um 4:29 Uhr

  • Ich habe Ewigkeiten damit verbracht und das Hinzufügen der CSS- und SVG-Definitionen hat für mich gewirkt!

    – PhoebeB

    11. November 2013 um 12:08 Uhr


Der Standardanzeigetyp für in der Reihe SVG-Elemente ist display: inline;. Das bedeutet, dass das SVG-Element auf der typografischen Grundlinie seines übergeordneten Elements platziert und entsprechend ausgerichtet wird. Unterhalb der Grundlinie ist immer etwas Platz, um die baumelnden Bits von Zeichen wie g und j und dergleichen zu berücksichtigen.

Einfache Lösung: svg { display: block;} oder svg { display: inline-block; vertical-align: top; }.

  • Danke! Toller Tipp. Aber leider löst es das Problem nicht. Ich habe Ihren Vorschlag zur Fiddle-Demo hinzugefügt und wie Sie sehen können, bleibt das Problem in Chrome, Safari und IE bestehen

    – Schüchtern freundlich

    1. Juni 2013 um 10:46 Uhr

  • Gilt das für neue Browserversionen?

    – Stackdave

    30. September 2017 um 15:59 Uhr

  • Soweit ich das beurteilen kann, nein. Ich habe diese Anzeige ausprobiert: block sagte hier und es funktioniert nicht in Chrome Version 101

    – Raúl Luna

    2. Juni um 17:55 Uhr

  • Was für mich funktioniert hat, ist zumindest in Chrom funktioniert es korrekt und füllt den Container. Die Pfadelemente innerhalb der SVG-Datei skalieren jedoch offensichtlich nicht

    – Raúl Luna

    2. Juni um 17:58 Uhr

Ich bin mir nicht ganz sicher, welchen Effekt Sie erzielen möchten, aber ich denke, Sie suchen möglicherweise nachkonservierenAspectRatio =”xMinYMin Slice”

  • Ich entschuldige mich für etwaige Unklarheiten bei der Formulierung der Frage. Ich möchte, dass sich Inline-SVG genau so verhält wie ein Bild in einem responsiven Kontext; dh skalieren Sie die SVG-Breite – und in diesem Fall ihren inneren Inhalt – um die verfügbare Elternbreite proportional auszufüllen. Was passiert ist, dass das äußere SVG-Element skaliert wird, aber die inneren Elemente nicht konsistent über alle Browser hinweg skaliert werden. Das Beispiel verdeutlicht die Unterschiede. Werfen Sie einen Blick in die verschiedenen Browser und Sie werden die Ergebnisse der breiten Palette sehen. Die Verwendung von Slice maskiert nur den SVG-Inhalt ohne proportionale Skalierung.

    – Schüchtern freundlich

    10. Juni 2013 um 7:50 Uhr

Ich habe es geschafft, konsistente Ergebnisse in Webkit/Gecko-Browsern zu erzielen, indem ich a height Wert anders als auto oder 0. In meinem Beispiel verwende ich 1%, aber soweit ich das beurteilen kann, könnte es alles sein. Irgendwie löst dies die falsche Höhe in Webkit (nach meinen Tests, denke ich auto setzt die SVG-Höhe falsch auf 100% Fensterhöhe).

Im IE habe ich das noch nicht getestet. Bitte lassen Sie mich wissen, ob es funktioniert.

http://jsfiddle.net/yXeru/

Nach viel Gefummel ist der moderne Browser und Die von mir verwendete IE11-kompatible Lösung besteht aus zwei Teilen:

  1. Geben Sie beides an viewBox und preserveAspectRatio="xMinYMin meet" im SVG-Root-Tag.
  2. Verwenden Sie CSS-Medienabfragen, um Ihrem SVG-Element eine Höhe zu geben vw Einheiten für jedes Layout.

viel Glück!

1180440cookie-checkResponsives INLINE-SVG – Inhalt von SVG muss die Breite des übergeordneten Elements ausfüllen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy