Come far espandere o contrarre un elemento <svg> nel suo contenitore principale?


112

L'obiettivo è che l' <svg>elemento si espanda alla dimensione del suo contenitore genitore, in questo caso a <div>, non importa quanto grande o piccolo possa essere quel contenitore.

Il codice:

<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>

La soluzione più comune a questo problema sembra essere l'impostazione viewBoxdell'attributo <svg>sull'elemento.

viewBox="0 0 widthOfContainer heightOfContainer"

Tuttavia, questo non sembra funzionare nei casi in cui gli elementi all'interno <svg>dell'elemento hanno larghezze e / o altezze predefinite. Ad esempio, l' <rect>elemento, nel codice precedente, ha la larghezza e l'altezza impostate in modo esplicito.

Quindi la soluzione ovvia è usare% larghezze e% altezze anche su quegli elementi. Ma anche questo deve essere fatto? Soprattutto, poiché <img src=test.svg >funziona bene e si espande / si contrae senza problemi con <rect>altezze e larghezze stabilite esplicitamente .

Se elementi come <rect>, e altri elementi simili, devono avere le loro larghezze e altezze definite in percentuale, c'è un modo in Inkscape per impostarlo in modo che tutti gli elementi con il <svg>documento usino larghezze percentuali, altezze, ecc. Invece di dimensioni fisse ?


1
Salva lo svg come file, quindi fai riferimento ad esso come un'immagine, come <img src = "file.svg" /> e in questo modo puoi usare larghezza: 100% o altezza: 100%
Burimi

Risposte:


56

Non viewBoxè l'altezza del contenitore, è la dimensione del tuo disegno. Definisci viewBoxdi essere 100 unità di larghezza, quindi definisci rectdi essere 10 unità. Dopodiché, per quanto grande sia il ridimensionamento dell'SVG, rectsarà il 10% della larghezza dell'immagine.


33
Ma la domanda è: come ridimensionare SVG?
Adrian Heine

6
@AdrianLang Il ridimensionamento avviene automaticamente quando si imposta una dimensione sull'oggetto SVG, come già fatto nel codice nella domanda. Ecco una versione fissa dell'esempio .
robertc

Hai ragione, fantastico, per me funziona davvero. Immagino che il mio problema fossero le proprietà di altezza e larghezza nel mio elemento radice svg.
Adrian Heine

2
Ho apportato alcune piccole modifiche a quel violino per forzare il ridimensionamento orizzontalmente e verticalmente senza preservare le proporzioni, e l'ho fatto funzionare in IE, mentre il violino @robertc inviato non lo era. Spero che possa aiutare qualcuno lungo la strada!
Mister Crimson

3
Per impostazione predefinita, il tuo svg verrà ridimensionato il più grande possibile in modo che sia completamente visibile ma conservi le sue proporzioni (quindi un viewBox quadrato non riempirà completamente un genitore rettangolare). Se vuoi davvero forzarlo a coprire completamente il contenitore genitore, aggiungi conservaAspectRatio = "none" all'elemento SVG.
patricksurry

24

Supponiamo di avere un SVG simile a questo: pic1

E voglio metterlo in un div e farlo riempire responsabilmente. Il mio modo di farlo è il seguente:

Per prima cosa apro il file SVG in un'applicazione come inkscape. In File-> Proprietà documento ho impostato la larghezza del documento a 800px e l'altezza a 600px (puoi scegliere altre dimensioni). Quindi inserisco l'SVG in questo documento.

pic2

Quindi salvo questo file come nuovo file SVG e ottengo i dati del percorso da questo file. Ora in HTML il codice che fa la magia è il seguente:

<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>

Nota che la larghezza e l'altezza di SVG sono entrambe impostate al 100%, poiché vogliamo che riempia il contenitore verticalmente e orizzontalmente, ma la larghezza e l'altezza del viewBox sono le stesse della larghezza e dell'altezza del documento in inkscape che è 800px X 600px. La prossima cosa che devi fare è impostare preservAspectRatio su "none". Se hai bisogno di maggiori informazioni su questo attributo, ecco un buon link . E questo è tutto quello che c'è da fare.

Un'altra cosa è che questo codice funziona su quasi tutti i principali browser, anche quelli vecchi, ma su alcune versioni di Android e iOS è necessario utilizzare del codice javascrip / jQuery per mantenerlo coerente. Uso quanto segue nel documento pronto e nelle funzioni di ridimensionamento:

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

Spero che sia d'aiuto!


5
+1 per la nota preservAspectRatio. Dopo aver cercato in alto e in basso per ottenere un SVG da allungare effettivamente (non in scala) a un div, questa era la risposta corretta.
adelphus

@ Gazoris, grazie per questa meravigliosa risposta. avere domanda sullo stesso. E se il mio svg fosse annidato. ad esempio, <svg> <svg id = "1"> </svg> <svg id = "2"> </svg> </svg> voglio visualizzare svg 1 e 2 in modo condizionale e dovrebbe prendere larghezza e altezza del contenitore. <div id = "container" style = "width: 200px; height: 200px;"> </div> puoi darmi una mano per questo.
Prasad Parab

@Reza Baradaran: Genius.
DanMad

6

Quello che ha funzionato di recente per me è stato rimuovere tutti gli attributi height=""e width=""dal <svg>tag e tutti i tag secondari. Quindi puoi usare il ridimensionamento usando una percentuale dell'altezza o della larghezza del contenitore principale.


5
Puoi fare un esempio funzionante? Non riesco a far sì che questo faccia nulla.
Michael

2

@robertc ha ragione, ma devi anche notare che svg, #containerfa sì che svg venga ridimensionato in modo esponenziale per qualsiasi cosa tranne il 100% (una #containervolta e una volta per svg).

In altre parole, se ho applicato il 50% h / w a entrambi gli elementi, in realtà è il 50% del 50%, o .5 * .5, che equivale a 0,25 o 25% di scala.

Un selettore funziona bene se usato come suggerisce @robertc.

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

Ecco perché il vostro selettore svg, #containercorrisponde siasvg l'elemento DOM e l' #containerelemento DOM. Credo che invece stavi cercando svg #container, ma la specifica di un genitore non è necessaria se stai comunque utilizzando un ID.
Nit

Non è esattamente quello che ho detto, "una volta per #container e una volta per svg"?
Justin Putney

1
Oh perdono, hai ragione, ma la tua risposta è formulata in modo un po 'strano e porta all'incomprensione. All'inizio sembra che tu stia parlando di un potenziale problema.
Nit

1

Per il tuo iPhone potresti usare nella tua balise in testa:

"width=device-width"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.