Esiste un modo per utilizzare SVG come contenuto in uno pseudo elemento: prima o: dopo


246

Voglio posizionare alcune immagini SVG prima di alcuni elementi selezionati. Sto usando jQuery ma questo è irrilevante.

Vorrei che l' :beforeelemento fosse:

#mydiv:before {
  content: '<svg.. code here</svg>';
  display: block;
  width: 22px;
  height: 10px;
  margin: 10px 5px 0 10px;
}

Se lo faccio come mostrato sopra, visualizza solo la stringa. Ho controllato le specifiche e sembra che ci siano alcune restrizioni su quali contenuti possono essere. Esiste un modo per aggirare questa limitazione? Solo il contenuto CSS è rilevante per la mia domanda.


1
C'è qualcosa di sbagliato nell'usarlo come immagine di sfondo?
cimmanon,

1
Voglio usarlo per generare puntatori fantasiosi ai tooltip dell'interfaccia utente di JQuery. Lo faccio ora con hack di pseudo elementi CSS ma questo mi dà solo triangoli. L'immagine di sfondo non funzionerà in questo caso poiché ho bisogno di qualcosa che esca dall'elemento.
Soleggiato

Risposte:


253

Si, puoi! Ho appena provato questo e funziona alla grande, è fantastico! Non funziona ancora con HTML, ma funziona con svg.

Nel mio index.html ho:

<div id="test" style="content: url(test.svg); width: 200px; height: 200px;"></div>

E il mio test.svg è simile al seguente:

<svg xmlns="http://www.w3.org/2000/svg">
   <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>
   <polyline points="20,20 40,25 60,40 80,120 120,140 200,180" style="fill:none;stroke:black;stroke-width:3"/>
</svg> 

18
A meno che SVG sono speciali, si dovrebbe essere in grado di trattare loro lo stesso come si farebbe con un'immagine: content: url(path/to/my.svg). Ciò non significa necessariamente che funzionerebbe con la libreria dei tooltip dell'interfaccia utente jQuery.
cimmanon,

1
@Cimmanon hmm, è dolce, voglio provarlo. Quindi in my.html o qualsiasi altra cosa potrei avere un sacco di codice HTML per il rendering ... sembra fantastico.
Dezman,

2
Perché vorresti farlo? Se hai già il codice svg nel file, non è necessario inserirlo in una pseudo-classe. Lo scopo delle pseudo-classi è ridurre gli elementi DOM quando si desidera aggiungere un po 'di contenuto, ma nel tuo caso se usi semplicemente il tuo codice svg normalmente non sarà peggio (e probabilmente più pulito) che metterlo in uno pseudo -class (che è anche probabilmente impossibile). A meno che, naturalmente, se desideri inserire il tuo codice svg in diverse posizioni, nel qual caso dovresti semplicemente conservare il tuo codice svg in un file separato come un'immagine.
Dezman,

6
sfortunatamente, non credo che questa soluzione funzioni con gli sprite SVG. per esempio, content: url(mysprite.svg#my-icon)in realtà non tirerà su la tua icona. mi piacerebbe essere smentito, comunque :)
Jason

1
@watson, semantico. HTML = struttura, CSS = presentazione. Se un SVG è decorativo, non dovrebbe essere nella struttura HTML, dovrebbe essere in CSS.
Deathlock

137

Sì. È possibile aggiungere SVG come immagine di sfondo di un vuoto: dopo o: prima. Ecco qui:

.anchor:before {
  display: block;
  content: ' ';
  background-image: url('../images/anchor.svg');
  background-size: 28px 28px;
  height: 28px;
  width: 28px;
}

4
Trovo questa una delle migliori soluzioni, dopo aver cercato per un po '. Puoi controllare ogni singolo aspetto dell'elemento inserito e lavorare nel modo normale in cui funzionano i fogli di stile CSS, con logica separata. Fantastico
Danielo515,

... ahh questo mi ha fatto sperare, fino a quando ho capito che background-sizenon è supportato in Opera Mini. Questo è così frustrante.
Deathlock

Ha funzionato alla grande. @deathlock, la dimensione dello sfondo non dovrebbe essere necessaria poiché stai definendo le dimensioni nello stesso svg, non ne ho avuto bisogno.
Eric Soyke,

1
Dovrebbero essere le risposte accettate poiché la domanda dice "in uno pseudo elemento: prima o: dopo"
ZalemCitizen,

Ho dovuto aggiungere <?xml version="1.0" encoding="utf-8"?>all'inizio del mio file svg per farlo funzionare.
Nicolas Boisteault,

130
#mydiv:before {
    content: url("data:image/svg+xml; utf8, <svg.. code here</svg>");
    display:block;
    width:22px;
    height:10px;
    margin:10px 5px 0 10px;
}

assicurati che il tuo svg non contenga doppie virgolette e uriencode tutti i simboli #.


8
Poiché gli SVG usano spesso virgolette doppie, puoi anche usare solo virgolette singole esterne. Il suggerimento di @Jenny è un ottimo modo per farlo se non vuoi usare un file SVG esterno.
Micros,

2
Questo è fantastico Sfortunatamente funziona solo con Chrome per me (testato su Chrome, Firefox e Edge).
Arsen,

2
OK funziona su FF. Ho solo bisogno di prestare attenzione alla parte "no #". Assicurati anche di usare il tag div (non sembra funzionare con span). Purtroppo ancora nessun successo per Edge.
Arsen,

Come tante soluzioni brillanti, non è supportato da IE11. url('file.svg')funziona comunque.
Bob Stein,

6
Quello che ho trovato importante è aggiungere xmlns='http://www.w3.org/2000/svg'nella parte <svg> per funzionare in Chrome 66.x. Ad esempio - chevron piccolo sarà: content:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24px' height='24px' fill='white'><path d='M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z' /></svg>");
darth0s

28

Facendo uso di sprite CSS e dati uri offre vantaggi extra interessanti come caricamento veloce e meno richieste E otteniamo il supporto IE8 usando image / base64:

Esempio di codepen usando SVG

HTML

<div class="div1"></div>
<div class="div2"></div>

CSS

.div1:after, .div2:after {
  content: '';
  display: block;
  height: 80px;
  width: 80px;
  background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20height%3D%2280%22%20width%3D%22160%22%3E%0D%0A%20%20%3Ccircle%20cx%3D%2240%22%20cy%3D%2240%22%20r%3D%2238%22%20stroke%3D%22black%22%20stroke-width%3D%221%22%20fill%3D%22red%22%20%2F%3E%0D%0A%20%20%3Ccircle%20cx%3D%22120%22%20cy%3D%2240%22%20r%3D%2238%22%20stroke%3D%22black%22%20stroke-width%3D%221%22%20fill%3D%22blue%22%20%2F%3E%0D%0A%3C%2Fsvg%3E);
}
.div2:after {
  background-position: -80px 0;
}

Per IE8, cambia in questo:

  background-image: url(data:image/png;base64,data......);

Ma questo non è scalabile, vero? Non posso ridimensionarlo a 16px o 320px a piacimento.
Deathlock

@deathlock Ovviamente ridimensiona, sebbene non sia il mio campione in quanto ha un set di dimensioni fisse, 80px larghezza / altezza.
Ason

1
@deathlock Posso chiederti se hai effettuato il downgrade perché l'esempio sopra non è stato ridimensionato?
Ason,

come lo faresti ridimensionare? E no, non l'ho fatto.
Deathlock,

@deathlock Grazie, ed ecco un modo per ridimensionare svg: jsfiddle.net/ess6ywce ... usando percent. Inoltre, cerca SO con scale svge troverai molti altri modi
Ason

22
<div class="author_">Lord Byron</div>

.author_ {  font-family: 'Playfair Display', serif; font-size: 1.25em; font-weight: 700;letter-spacing: 0.25em; font-style: italic;
  position:relative;
  margin-top: -0.5em;
  color: black;
  z-index:1;
  overflow:hidden;
  text-align:center;
 
}


.author_:after{
   left:20px;
  margin:0 -100% 0 0;
  display: inline-block;
  height: 10px;
  content: url(data:image/svg+xml,%0A%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22120px%22%20height%3D%2220px%22%20viewBox%3D%220%200%201200%20200%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%3E%0A%20%20%3Cpath%20stroke%3D%22black%22%20stroke-width%3D%223%22%20fill%3D%22none%22%20d%3D%22M1145%2085c17%2C7%208%2C24%20-4%2C29%20-12%2C4%20-40%2C6%20-48%2C-8%20-9%2C-15%209%2C-34%2026%2C-42%2017%2C-7%2045%2C-6%2062%2C2%2017%2C9%2019%2C18%2020%2C27%201%2C9%200%2C29%20-27%2C52%20-28%2C23%20-52%2C34%20-102%2C33%20-49%2C0%20-130%2C-31%20-185%2C-50%20-56%2C-18%20-74%2C-21%20-96%2C-23%20-22%2C-2%20-29%2C-2%20-56%2C7%20-27%2C8%20-44%2C17%20-44%2C17%20-13%2C5%20-15%2C7%20-40%2C16%20-25%2C9%20-69%2C14%20-120%2C11%20-51%2C-3%20-126%2C-23%20-181%2C-32%20-54%2C-9%20-105%2C-20%20-148%2C-23%20-42%2C-3%20-71%2C1%20-104%2C5%20-34%2C5%20-65%2C15%20-98%2C22%22%2F%3E%0A%3C%2Fsvg%3E%0A);
}
.author_:before {
  right:20px;
  margin:0 0 0 -100%;
  display: inline-block;
  height: 10px;
  content: url(data:image/svg+xml,%0A%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22120px%22%20height%3D%2220px%22%20viewBox%3D%220%200%201200%20130%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%3E%0A%20%20%3Cpath%20stroke%3D%22black%22%20stroke-width%3D%223%22%20fill%3D%22none%22%20d%3D%22M55%2068c-17%2C6%20-8%2C23%204%2C28%2012%2C5%2040%2C7%2048%2C-8%209%2C-15%20-9%2C-34%20-26%2C-41%20-17%2C-8%20-45%2C-7%20-62%2C2%20-18%2C8%20-19%2C18%20-20%2C27%20-1%2C9%200%2C29%2027%2C52%2028%2C23%2052%2C33%20102%2C33%2049%2C-1%20130%2C-31%20185%2C-50%2056%2C-19%2074%2C-21%2096%2C-23%2022%2C-2%2029%2C-2%2056%2C6%2027%2C8%2043%2C17%2043%2C17%2014%2C6%2016%2C7%2041%2C16%2025%2C9%2069%2C15%20120%2C11%2051%2C-3%20126%2C-22%20181%2C-32%2054%2C-9%20105%2C-20%20148%2C-23%2042%2C-3%2071%2C1%20104%2C6%2034%2C4%2065%2C14%2098%2C22%22%2F%3E%0A%3C%2Fsvg%3E%0A);
}
	<div class="author_">Lord Byron</div>

Strumento utile per codificare l' URL-encoder SVG


5

Fai attenzione, tutte le altre risposte hanno qualche problema in IE.

Consente questa situazione: pulsante con icona anteposta. Tutti i browser lo gestiscono correttamente, ma IE prende la larghezza dell'elemento e ridimensiona il contenuto precedente per adattarlo. JSFiddle

#mydiv1 { width: 200px; height: 30px; background: green; }
#mydiv1:before {
    content: url("data:url or /standard/url.svg");
}

La soluzione è impostare la dimensione su prima dell'elemento e lasciarlo dove si trova:

#mydiv2 { width: 200px; height: 30px; background: green; }
#mydiv2:before {
    content: url("data:url or /standard/url.svg");
    display: inline-block;
    width: 16px; //only one size is alright, IE scales uniformly to fit it
}

Il background-image+background-size soluzioni funzionano, ma sono un po 'invariate, poiché è necessario specificare le stesse dimensioni due volte.

Il risultato in IE11:

Rendering IE


5

Per estendere ulteriormente questo argomento. Nel caso in cui desideri aggiungere Font Awesome 5 icone devi aggiungere qualche CSS aggiuntivo.

Le icone di default hanno classi svg-inline--fae fa-w-*.

Ci sono anche corsi di modificatori, come fa-lg, fa-rotate-*e altri. È necessario controllare il svg-with-js.cssfile e trovare il CSS corretto per quello.

Devi aggiungere il tuo colore all'icona CSS altrimenti sarà nero per impostazione predefinita, ad esempio fill='%23f00'dove %23è codificato #.

h1::before{

  /* svg-inline--fa */
  display:inline-block;
  font-size:inherit;
  height:1em;
  overflow:visible;
  vertical-align:-.125em;
  
  /* fa-w-14 */
  width:.875em;
  
  /* Icon */
  content:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3E%3Cpath fill='%23f00' d='M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48zM264 408c0 22.1-17.9 40-40 40s-40-17.9-40-40v-48c0-22.1 17.9-40 40-40s40 17.9 40 40v48z'%3E%3C/path%3E%3C/svg%3E");
  
  /* Margin */
  margin-right:.75rem;
}
<h1>Lorem Ipsum</h1>


-1
.myDiv {
  display: flex;
  align-items: center;
}

.myDiv:before {
  display: inline-block;
  content: url(./dog.svg);
  margin-right: 15px;
  width: 10px;
}

3
Dovresti spiegare un po 'di più la tua risposta. Proprio da questo, è davvero difficile dire come o perché la tua risposta funziona.
ifconfig,
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.