Come posso creare una scala svg con il suo contenitore principale?


236

Voglio avere una scala dei contenuti dell'elemento svg inline quando la dimensione non è nativa. Naturalmente potrei averlo come file separato e ridimensionarlo in quel modo.

index.html: <img src="foo.svg" style="width: 100%;" />

foo.svg: <svg width="123" height="456"></svg>

Tuttavia, voglio aggiungere altri stili al file SVG tramite CSS, quindi il collegamento di uno esterno non è un'opzione. Come faccio a creare una scala SVG in linea?


2
prova i precents nelle larghezze e altezze svg.
ncm,

@ncm Come sarebbe fatto con JS?
Mawg dice di ripristinare Monica il

Risposte:


458

Per specificare le coordinate all'interno dell'immagine SVG indipendentemente dalle dimensioni ridimensionate dell'immagine, utilizzare l' viewBoxattributo sull'elemento SVG per definire quale sia il riquadro di delimitazione dell'immagine nel sistema di coordinate dell'immagine e usare ilwidthheight attributi e per definire quali la larghezza o l'altezza sono rispetto alla pagina contenente.

Ad esempio, se si dispone di quanto segue:

<svg>
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

Verrà visualizzato come un triangolo di 10 x 20 pixel:

Triangolo 10x20

Ora, se imposti solo la larghezza e l'altezza, ciò cambierà la dimensione dell'elemento SVG, ma non ridimensionerà il triangolo:

<svg width=100 height=50>
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

Triangolo 10x20

Se si imposta la casella di visualizzazione, ciò provoca la trasformazione dell'immagine in modo tale che la casella specificata (nel sistema di coordinate dell'immagine) venga ridimensionata per adattarsi alla larghezza e all'altezza indicate (nel sistema di coordinate della pagina). Ad esempio, per ingrandire il triangolo in modo che sia 100px di 50px:

<svg width=100 height=50 viewBox="0 0 20 10">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

Triangolo 100x50

Se vuoi ridimensionarlo fino alla larghezza del viewport HTML:

<svg width="100%" viewBox="0 0 20 10">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

Triangolo 300x150

Si noti che per impostazione predefinita, le proporzioni vengono mantenute. Quindi, se specifichi che l'elemento dovrebbe avere una larghezza del 100%, ma un'altezza di 50 px, in realtà verrà ridimensionato solo fino all'altezza di 50 px (a meno che tu non abbia una finestra molto stretta):

<svg width="100%" height="50px" viewBox="0 0 20 10">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

Triangolo 100x50

Se si desidera che si estenda orizzontalmente, disabilitare la conservazione delle proporzioni con preserveAspectRatio=none:

<svg width="100%" height="50px" viewBox="0 0 20 10" preserveAspectRatio="none">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

Triangolo 300x50

(nota che mentre nei miei esempi uso la sintassi che funziona per l'incorporamento HTML, per includere gli esempi come immagine in StackOverflow invece sto incorporando in un altro SVG, quindi ho bisogno di usare una sintassi XML valida)


1
Come si crea non solo viewBox preservAspectRatio, ma anche la casella principale? Voglio larghezza: 100%; altezza: auto per esso.
bjb568,

1
@ Amico: penso che l'esempio con width="100%"e senza altezza specificata faccia quello che vuoi. Ho aggiunto immagini per dimostrare. Ha una larghezza del 100% e aumenta proporzionalmente l'altezza. Se non è quello che stai cercando, puoi provare a chiarire cosa intendevi?
Brian Campbell,

1
Oh. Nessun problema in realtà. È solo un bug di webkit. In Safari e Chrome l'altezza "reale" è predefinita al 100%, non automatica. Come potrei aggirare questo allora?
bjb568,

4
@ Amico Ah, sì, capisco. Funziona bene su Firefox, ma non Chrome o Safari. Secondo le specifiche SVG , Firefox sembra essere corretto; mentre il valore predefinito di widthe heightper un elemento SVG è 100%, questa non è la definizione CSS del 100% (100% del blocco contenitore), ma invece il 100% del viewport che è stato specificato in base alle proporzioni intrinseche ( che viene calcolato dal viewBoxmomento in cui viene dato). Non ho ancora trovato una soluzione per quel problema che funziona in Chrome / Safari.
Brian Campbell,

1
Questo funziona per me. Per prima cosa creo un attributo viewBox sull'elemento SVG e imposto il valore su "0 0 [larghezza svg originale] [altezza svg originale]". Quindi cambio l'attributo width dell'elemento SVG su "auto" e l'attributo height su "100%". Il contenitore deve inoltre avere un'altezza definita. In questo modo il vettore viene ridimensionato al 100% dell'altezza del contenitore, consentendo alla larghezza di fluttuare. Infine, imposta la larghezza massima CSS di SVG al 100% per evitare il superamento del contenitore.
Ryan Griggs,

28

Dopo circa 48 ore di ricerca, ho finito per farlo per ottenere un ridimensionamento proporzionale:

NOTA: questo esempio è scritto con React. Se non lo stai usando, cambia la roba della custodia del cammello in trattini (cioè: cambia backgroundColorin background-colore cambia lo stile Objectin a String).

<div
  style={{
    backgroundColor: 'lightpink',
    resize: 'horizontal',
    overflow: 'hidden',
    width: '1000px',
    height: 'auto',
  }}
>
  <svg
    width="100%"
    viewBox="113 128 972 600"
    preserveAspectRatio="xMidYMid meet"
  >
    <g> ... </g>
  </svg>
</div>

Ecco cosa sta succedendo nel codice di esempio sopra:

viewbox

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox

min-x, min-y, larghezza e altezza

ovvero: viewbox = "0 0 1000 1000"

Viewbox è un attributo importante perché sostanzialmente dice all'SVG quale dimensione disegnare e dove. Se avessi usato CSS per creare SVG 1000x1000 px ma il tuo riquadro di visualizzazione fosse 2000x2000, vedresti il quarto in alto a sinistra del tuo SVG.

I primi due numeri, min-x e min-y, determinano se l'SVG deve essere sfalsato all'interno del riquadro di visualizzazione.

Il mio SVG deve spostarsi su / giù o a sinistra / a destra

Esaminare questo: viewbox = "50 50 450 450"

I primi due numeri sposteranno il tuo SVG a sinistra di 50 px e su di 50 px, e i secondi due numeri hanno la dimensione del riquadro di visualizzazione: 450x450 px. Se il tuo SVG è 500x500 ma ha qualche imbottitura extra, puoi manipolare quei numeri per spostarlo all'interno della "viewbox".

Il tuo obiettivo a questo punto è cambiare uno di quei numeri e vedere cosa succede.

Puoi anche omettere completamente la viewbox, ma la tua distanza varierà in base a tutte le altre impostazioni che hai in quel momento. Nella mia esperienza, incontrerai problemi con la conservazione delle proporzioni perché la viewbox aiuta a definire le proporzioni.

CONSERVARE IL RAPPORTO ASPETTO

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio

Sulla base della mia ricerca, ci sono molte impostazioni di proporzioni diverse, ma viene chiamata quella predefinita xMidYMid meet. L'ho messo sul mio per ricordare esplicitamente a me stesso. xMidYMid meetlo fa ridimensionare proporzionalmente in base al punto medio X e Y. Ciò significa che rimane centrato nel riquadro di visualizzazione.

LARGHEZZA

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/width

Guarda il mio codice di esempio sopra. Nota come imposto solo la larghezza, non l'altezza. L'ho impostato al 100% in modo da riempire il contenitore in cui si trova. Questo è ciò che probabilmente contribuisce maggiormente a rispondere a questa domanda StackTranslate.it.

Puoi cambiarlo in qualsiasi valore di pixel tu voglia, ma ti consiglio di usare il 100% come ho fatto per farlo esplodere fino alla dimensione massima e quindi controllarlo con CSS tramite il contenitore padre. Lo consiglio perché otterrai un controllo "adeguato". Puoi utilizzare le query multimediali e puoi controllare le dimensioni senza JavaScript pazzo.

SCALING CON CSS

Guarda di nuovo il mio codice di esempio sopra. Nota come ho queste proprietà:

resize: 'horizontal', // you can safely omit this
overflow: 'hidden',   // if you use resize, use this to fix weird scrollbar appearance
width: '1000px',
height: 'auto',

Questo è aggiuntivo, ma mostra come consentire all'utente di ridimensionare l'SVG mantenendo le proporzioni corrette. Poiché SVG mantiene le proprie proporzioni, è necessario solo ridimensionare la larghezza sul contenitore padre e ridimensionerà come desiderato.

Lasciamo l'altezza da sola e / o la impostiamo su auto e controlliamo il ridimensionamento con larghezza. Ho scelto larghezza perché spesso è più significativo a causa di progetti reattivi.

Ecco un'immagine di queste impostazioni utilizzate:

inserisci qui la descrizione dell'immagine

Se leggi tutte le soluzioni in questa domanda e sei ancora confuso o non vedi esattamente ciò di cui hai bisogno, dai un'occhiata a questo link qui. L'ho trovato molto utile:

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

È un articolo enorme, ma analizza praticamente ogni modo possibile per manipolare un SVG, con o senza CSS. Vi consiglio di leggerlo mentre bevete casualmente un caffè o la vostra scelta di liquidi selezionati.


Questo non sembra funzionare per nessun SVG - Se non si ha il controllo della sorgente SVG, questo metodo fallisce quando l'SVG ha una larghezza fissa.
user48956

@ user48956 Puoi sempre manipolarlo dopo il fatto con JavaScript.
Andrew,

Sì, con una programmazione è sempre possibile colpire le viscere di vari formati di file, ma si spera che ci sia un metodo che funzioni per tutti i tipi di risorse (ad esempio PNG) e non richiede la programmazione JavaScript.
user48956

21

Ti consigliamo di fare una trasformazione in quanto tale:

con JavaScript:

document.getElementById(yourtarget).setAttribute("transform", "scale(2.0)");

Con CSS:

#yourtarget {
  transform:scale(2.0);
  -webkit-transform:scale(2.0);
}

Avvolgi la tua Pagina SVG in un tag Group come tale e scegli come target per manipolare l'intera pagina:

<svg>
  <g id="yourtarget">
    your svg page
  </g>
</svg>

Nota : la scala 1.0 è del 100%


7
Ok. Non voglio JS in questo. C'è un modo per trasformarlo per adattarlo ai genitori?
bjb568,

@bj setAttribute è la stessa cosa di <tag attributo = "valore">
john ktejik l'

17

In giro e trovato questo CSS sembra contenere SVG nel browser Chrome fino al punto in cui il contenitore è più grande dell'immagine:

div.inserted-svg-logo svg { max-width:100%; }

Sembra funzionare anche in FF + IE 11.


Questo ha risolto il problema per me. Ma stavo vedendo solo l'overflow in iOS. Grazie!
Evan Mattson,

5
Usando entrambi max-width: 100%e max-height: 100%renderai lo svg sempre ridimensionato al contenitore senza mai traboccare o perdere le sue proporzioni.
Gavin,

2
@Gavin max-height: 100%non funziona per me, risolto usando vhinvece di%
Pavel

2

cambiare il file SVG non è stata una soluzione giusta per me, quindi ho usato le relative unità CSS .

vh, vw, %Sono molto utili. Ho usato un CSS come height: 2.4vh;per impostare una dimensione dinamica per le mie immagini SVG.



0

La regolazione dell'attributo currentScale funziona in IE (ho testato con IE 11), ma non in Chrome.

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.