Gibt es eine Möglichkeit, SVG als Inhalt in einem Pseudoelement zu verwenden: vorher oder: nachher

245

Ich möchte einige SVG-Bilder vor ausgewählten Elementen platzieren. Ich benutze JQuery, aber das ist irrelevant. Ich möchte das Element: before als:

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

Wenn ich es wie oben gezeigt mache, wird nur die Zeichenfolge angezeigt. Ich habe die Spezifikationen überprüft und es scheint einige Einschränkungen hinsichtlich des Inhalts zu geben. Gibt es eine Lösung für diese Einschränkung? Nur der Inhalt CSS ist für meine Frage relevant.

Sonnig
quelle
1
Stimmt etwas nicht, wenn Sie es als Hintergrundbild verwenden?
Cimmanon
1
Ich möchte es verwenden, um ausgefallene Zeiger auf JQuery UI-Tooltips zu generieren. Ich mache das jetzt mit CSS Pseudo Elements Hack, aber das gibt mir nur Dreiecke. Das Hintergrundbild funktioniert in diesem Fall nicht, da ich etwas brauche, das außerhalb des Elements liegt.
Sonniger

Antworten:

251

Ja, du kannst! Habe das gerade getestet und es funktioniert großartig, das ist großartig! Es funktioniert immer noch nicht mit HTML, aber mit SVG.

In meiner index.html habe ich:

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

Und meine test.svg sieht so aus:

<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> 
dezman
quelle
18
Sofern SVGs nichts Besonderes sind, sollten Sie sie genauso behandeln können wie ein Bild : content: url(path/to/my.svg). Dies bedeutet jedoch nicht unbedingt, dass es mit der Tooltip-Bibliothek der jQuery-Benutzeroberfläche funktioniert.
Cimmanon
1
@ Cimmanon hmm, das ist süß, das möchte ich testen. Also in my.html oder was auch immer ich eine Menge HTML-Code zum Rendern haben könnte ... klingt fantastisch.
Dekman
2
Warum willst du das tun? Wenn Sie den SVG-Code bereits in der Datei haben, müssen Sie ihn nicht in eine Pseudoklasse einfügen. Der Sinn von Pseudoklassen besteht darin, DOM-Elemente zu reduzieren, wenn Sie ein wenig Inhalt hinzufügen möchten. In Ihrem Fall ist es jedoch nicht schlechter (und wahrscheinlich sauberer), wenn Sie Ihren SVG-Code normal verwenden, als ihn in ein Pseudo einzufügen -Klasse (was wahrscheinlich auch unmöglich ist). Es sei denn natürlich, Sie möchten Ihren SVG-Code an einer Reihe von Orten ablegen. In diesem Fall sollten Sie Ihren SVG-Code einfach in einer separaten Datei wie einem Bild aufbewahren.
Dekman
6
Leider glaube ich nicht, dass diese Lösung mit SVG-Sprites funktioniert. Zum Beispiel content: url(mysprite.svg#my-icon)wird Ihr Symbol nicht aufgerufen. Ich würde mich jedoch gerne als falsch erweisen :)
Jason
1
@ Watson, semantisch. Die HTML = Struktur, CSS = Präsentation. Wenn eine SVG dekorativ ist, sollte sie nicht in der HTML-Struktur enthalten sein, sondern in CSS.
Deathlock
137

Ja. Sie können die SVG als Hintergrundbild eines leeren: after oder: before hinzufügen. Bitte schön:

.anchor:before {
  display: block;
  content: ' ';
  background-image: url('../images/anchor.svg');
  background-size: 28px 28px;
  height: 28px;
  width: 28px;
}
DerZyklop
quelle
4
Ich finde dies eine der besten Lösungen, nachdem ich eine Weile gesucht habe. Sie können jeden einzelnen Aspekt des eingefügten Elements steuern und arbeiten auf normale Weise wie CSS-Stylesheets mit separater Logik. Großartig
Danielo515
... ahh, das hat meine Hoffnungen geweckt, bis mir klar wird, dass background-sizedies in Opera Mini nicht unterstützt wird. Das ist so frustrierend.
Deathlock
Hat super funktioniert. @deathlock, Hintergrundgröße sollte nicht benötigt werden, da Sie die Dimensionen im SVG selbst definieren, ich brauchte es nicht.
Eric Soyke
1
Sollte die akzeptierte Antwort sein, da die Frage "in einem
Pseudoelement
Ich musste <?xml version="1.0" encoding="utf-8"?>am Anfang meiner SVG-Datei hinzufügen , damit es funktioniert.
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;
}

Stellen Sie sicher, dass Ihr SVG keine doppelten Anführungszeichen enthält, und geben Sie keine # -Symbole ein.

Jenny
quelle
8
Da SVGs häufig doppelte Anführungszeichen verwenden, können Sie auch nur äußere einfache Anführungszeichen verwenden. @ Jennys Vorschlag ist eine großartige Möglichkeit, wenn Sie keine externe SVG-Datei verwenden möchten.
Micros
2
Das ist toll. Leider funktioniert es nur mit Chrome für mich (getestet auf Chrome, Firefox und Edge).
Arsen
2
OK, es funktioniert mit FF. Ich musste nur auf den Teil "no #" achten. Stellen Sie außerdem sicher, dass Sie das div-Tag verwenden (scheint nicht mit span zu funktionieren). Leider immer noch kein Erfolg für Edge.
Arsen
Wie so viele brillante Lösungen wird es von IE11 nicht unterstützt. url('file.svg')funktioniert jedoch.
Bob Stein
6
Was ich für wichtig hielt, ist das Hinzufügen xmlns='http://www.w3.org/2000/svg'des Teils <svg>, um in Chrome 66.x zu funktionieren. Zum Beispiel - kleiner Chevron wird sein: 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

Die Verwendung von CSS-Sprites und Daten-Uri bietet zusätzliche interessante Vorteile wie schnelles Laden und weniger Anfragen UND wir erhalten IE8-Unterstützung durch die Verwendung von image / base64:

Codepen-Beispiel mit 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;
}

Ändern Sie für IE8 Folgendes:

  background-image: url(data:image/png;base64,data......);
Einen Sohn
quelle
Aber das ist nicht skalierbar, nicht wahr? Ich kann die Größe nicht nach Belieben auf 16px oder 320px ändern.
Deathlock
@deathlock Natürlich skaliert es, obwohl nicht mein Beispiel, da es eine feste Größe hat, 80px breit / hoch.
Ason
1
@deathlock Darf ich fragen, ob Sie herabgestimmt haben, weil das obige Beispiel nicht skaliert wurde?
Ason
Wie würden Sie es skalieren lassen? Und nein, habe ich nicht.
Deathlock
@deathlock Danke, und hier ist eine Möglichkeit, svg zu skalieren: jsfiddle.net/ess6ywce ... mit Prozent. Suchen Sie auch SO mit scale svgund Sie werden viele weitere Möglichkeiten finden
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>

Praktisches Tool für die SVG-Codierung von URL-Encodern

Alexei Zababurin
quelle
5

Seien Sie vorsichtig, alle anderen Antworten haben ein Problem im IE.

Lassen Sie uns diese Situation haben - Schaltfläche mit vorangestelltem Symbol. Alle Browser behandeln dies korrekt, aber der IE nimmt die Breite des Elements und skaliert den vorherigen Inhalt entsprechend. JSFiddle

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

Die Lösung besteht darin, die Größe auf vor dem Element zu setzen und es dort zu belassen, wo es ist:

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

Die background-image+ background-size-Lösungen funktionieren ebenfalls, sind jedoch wenig unhandlich, da Sie die gleichen Größen zweimal angeben müssen.

Das Ergebnis in IE11:

IE-Rendering

zbycz
quelle
5

Um dieses Thema weiter auszubauen. Wenn Sie Font Awesome 5- Symbole hinzufügen möchten, müssen Sie zusätzliches CSS hinzufügen.

Symbole haben standardmäßig Klassen svg-inline--faund fa-w-*.

Es gibt auch Sonderklassen wie fa-lg, fa-rotate-*und andere. Sie müssen die svg-with-js.cssDatei überprüfen und das richtige CSS dafür finden.

Sie müssen dem CSS-Symbol Ihre eigene Farbe hinzufügen, da es sonst standardmäßig schwarz ist, z. B. fill='%23f00'wo %23es codiert ist #.

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>

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

.myDiv:before {
  display: inline-block;
  content: url(./dog.svg);
  margin-right: 15px;
  width: 10px;
}
Michael Alfandre
quelle
3
Sie sollten Ihre Antwort etwas näher erläutern. Nur deshalb ist es wirklich schwer zu sagen, wie oder warum Ihre Antwort funktioniert.
ifconfig