Czy istnieje sposób na użycie SVG jako treści w pseudoelemencie: przed lub: po


245

Chcę umieścić niektóre obrazy SVG przed niektórymi wybranymi elementami. Korzystam z JQuery, ale to nie ma znaczenia. Chciałbym, aby element: before był jako:

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

Jeśli zrobię to, jak pokazano powyżej, po prostu wyświetli ciąg. Sprawdziłem specyfikacje i wydaje się, że istnieją pewne ograniczenia co do treści. Czy istnieje obejście tego ograniczenia? Tylko treść css jest istotna dla mojego pytania.


1
Czy coś jest nie tak z użyciem go jako obrazu tła?
cimmanon

1
Chcę go używać do generowania fantazyjnych wskaźników do podpowiedzi interfejsu użytkownika JQuery. Robię to teraz z hackowaniem pseudoelementów CSS, ale to daje mi tylko trójkąty. Obraz tła nie będzie w tym przypadku działał, ponieważ potrzebuję czegoś, co wykracza poza element.
Sunny,

Odpowiedzi:


252

Tak, możesz! Właśnie przetestowałem to i działa świetnie, to jest niesamowite! Nadal nie działa z HTML, ale działa z SVG.

W moim index.html mam:

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

A mój test.svg wygląda następująco:

<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
Chyba pomostów żylnych są specjalne, powinieneś być w stanie je traktować tak samo jak byś obraz: content: url(path/to/my.svg). Nie musi to jednak oznaczać, że będzie działać z biblioteką podpowiedzi interfejsu użytkownika jQuery.
cimmanon

1
@ cimmanon hmm, to słodkie, chcę to przetestować. Więc w my.html lub czymkolwiek innym mogę mieć sporo kodu HTML do renderowania ... brzmi niesamowicie.
dezman

2
Dlaczego chcesz to zrobić? Jeśli masz już plik SVG w pliku, nie ma potrzeby umieszczania go w pseudoklasie. Istotą pseudoklas jest zmniejszenie elementów DOM, gdy chcesz dodać trochę treści, ale w twoim przypadku, jeśli zwyczajnie użyjesz swojego kodu svg normalnie, nie będzie gorzej (i prawdopodobnie czystsze) niż umieszczenie go w pseudo -klasa (co również prawdopodobnie jest niemożliwe). O ile oczywiście nie chcesz umieścić kodu svg w kilku lokalizacjach, w takim przypadku powinieneś po prostu przechowywać swój kod svg w osobnym pliku, takim jak obraz.
dezman

6
niestety nie wierzę, że to rozwiązanie działa ze sprite'ami SVG. na przykład content: url(mysprite.svg#my-icon)nie podciągnie twojej ikony. chciałbym jednak udowodnić, że się mylę :)
Jason

1
@watson, semantyczny. Struktura HTML = CSS = prezentacja. Jeśli plik SVG jest dekoracyjny, nie powinien znajdować się w strukturze HTML, powinien znajdować się w CSS.
deathlock

137

Tak. Możesz dodać SVG jako obraz tła pustego: po lub: przed. Proszę bardzo:

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

4
Po pewnym czasie uważam to za jedno z najlepszych rozwiązań. Możesz kontrolować każdy aspekt wstawianego elementu i działa w normalny sposób arkusze stylów CSS, z oddzielną logiką. Świetnie
Danielo515,

... ahh, to wzbudziło moje nadzieje, dopóki nie uświadomiłem sobie, że background-sizenie jest obsługiwane w Opera Mini. To jest bardzo frustrujące.
deathlock

Działa świetnie. @deathlock, rozmiar tła nie powinien być potrzebny, ponieważ definiujesz wymiary w samym pliku svg, nie potrzebowałem go.
Eric Soyke

1
Powinny być zaakceptowane odpowiedzi, ponieważ pytanie brzmi „w pseudoelemencie: przed lub: po”
ZalemCitizen

Musiałem dodać <?xml version="1.0" encoding="utf-8"?>na początku mojego pliku svg, aby działał .
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;
}

upewnij się, że Twój plik SVG nie zawiera podwójnych cudzysłowów i uriencode # symboli.


8
Ponieważ pliki SVG często używają podwójnych cudzysłowów, możesz również użyć zewnętrznych pojedynczych cudzysłowów. @ Sugestia Jenny to świetny sposób na zrobienie tego, jeśli nie chcesz używać zewnętrznego pliku SVG.
Micros

2
To jest świetne. Niestety działa tylko z Chrome dla mnie (testowane w Chrome, Firefox i Edge).
Arsen,

2
OK, działa na FF. Musiałem tylko zwrócić uwagę na część „nie #”. Upewnij się także, że używasz znacznika div (wydaje się, że nie działa z rozpiętością). Niestety wciąż nie ma sukcesu dla Edge.
Arsen,

Podobnie jak wiele świetnych rozwiązań, nie jest obsługiwany przez IE11. url('file.svg')działa jednak.
Bob Stein

6
To, co uznałem za ważne, to dodanie xmlns='http://www.w3.org/2000/svg'części <svg> do pracy w przeglądarce Chrome 66.x. Na przykład - mały szewron będzie: 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

Korzystanie ze sprite'ów i danych CSS daje dodatkowe interesujące korzyści, takie jak szybkie ładowanie i mniej żądań ORAZ otrzymujemy obsługę IE8 za pomocą image / base64:

Próbka Codepen przy użyciu 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;
}

W przypadku IE8 zmień na:

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

Ale to nie jest skalowalne, prawda? Nie mogę dowolnie zmieniać jego rozmiaru na 16 lub 320 pikseli.
deathlock

@deathlock Oczywiście skaluje się, choć nie moja próbka, ponieważ ma ustalony rozmiar, szerokość 80 pikseli / wysokość.
Ason

1
@deathlock Czy mogę zapytać, czy przegłosowałeś, ponieważ powyższa próbka się nie skalowała?
Ason

jak byś to skalował? I nie, nie zrobiłem tego.
deathlock

@deathlock Dzięki, a oto jeden sposób na skalowanie SVG : jsfiddle.net/ess6ywce ... przy użyciu procenta. Przeszukuj SO za pomocą, scale svga znajdziesz wiele innych sposobów
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>

Wygodne narzędzie do kodowania adresów URL SVG


5

Uważaj, wszystkie pozostałe odpowiedzi mają jakiś problem w IE.

Pozwala mieć taką sytuację - przycisk z wcześniej przygotowaną ikoną. Wszystkie przeglądarki obsługują to poprawnie, ale IE przyjmuje szerokość elementu i skaluje zawartość przed, aby go dopasować. JSFiddle

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

Rozwiązaniem jest ustawienie rozmiaru przed elementem i pozostawienie go tam, gdzie jest:

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

Rozwiązania background-image+ background-sizerównież działają, ale są mało przydatne, ponieważ musisz dwukrotnie określić te same rozmiary.

Wynik w IE11:

Renderowanie IE


5

Aby rozszerzyć ten temat. Jeśli chcesz dodać ikony Font Awesome 5 , musisz dodać dodatkowy CSS.

Ikony domyślnie mają klasy svg-inline--fai fa-w-*.

Istnieją również modyfikator zajęcia takie jak fa-lg, fa-rotate-*i inne. Musisz sprawdzić svg-with-js.cssplik i znaleźć odpowiedni CSS do tego.

Musisz dodać własny kolor do ikony css, w przeciwnym razie domyślnie będzie czarny, na przykład fill='%23f00'gdzie %23jest zakodowany #.

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
Powinieneś trochę wyjaśnić swoją odpowiedź. Po prostu naprawdę trudno powiedzieć, jak i dlaczego działa twoja odpowiedź.
ifconfig
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.