Existe-t-il un moyen d'utiliser SVG comme contenu dans un pseudo-élément: avant ou: après


246

Je veux placer des images SVG avant certains éléments sélectionnés. J'utilise jQuery mais ce n'est pas pertinent.

Je voudrais que l' :beforeélément soit le suivant:

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

Si je le fais comme indiqué ci-dessus, il affiche simplement la chaîne. J'ai vérifié les spécifications et il semble y avoir des restrictions sur le contenu. Y a-t-il un moyen de contourner cette restriction? Seul le contenu CSS est pertinent pour ma question.


1
Quelque chose ne va pas avec son utilisation comme image de fond?
cimmanon

1
Je veux l'utiliser pour générer des pointeurs de fantaisie vers les info-bulles de l'interface utilisateur JQuery. Je fais ça maintenant avec des pseudo-éléments CSS piratés mais ça ne me donne que des triangles. L'image d'arrière-plan ne fonctionnera pas dans ce cas car j'ai besoin de quelque chose qui sort de l'élément.
ensoleillé

Réponses:


253

Oui, vous pouvez! Je viens de tester cela et cela fonctionne très bien, c'est génial! Cela ne fonctionne toujours pas avec html, mais c'est le cas avec svg.

Dans mon index.html j'ai:

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

Et mon test.svg ressemble à ceci:

<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
À moins SVGs sont spéciaux, vous devriez être en mesure de les traiter de la même chose que vous feriez une image: content: url(path/to/my.svg). Cela ne signifie pas nécessairement que cela fonctionnerait avec la bibliothèque d'infobulles jQuery UI.
cimmanon

1
@cimmanon hmm, c'est gentil, je veux tester ça. Donc dans my.html ou quoi que ce soit, je pourrais avoir un tas de code html à rendre ... ça a l'air génial.
dezman

2
Pourquoi voudriez-vous faire ça? Si vous avez déjà le code svg dans le fichier, il n'est pas nécessaire de le mettre dans une pseudo-classe. L'intérêt des pseudo-classes est de réduire les éléments DOM lorsque vous souhaitez ajouter un peu de contenu, mais dans votre cas, si vous utilisez simplement votre code svg normalement, ce ne sera pas pire (et probablement plus propre) que de le mettre dans un pseudo -classe (ce qui est également probablement impossible). Sauf si bien sûr si vous voulez mettre votre code svg dans un tas d'emplacements, auquel cas vous devez simplement conserver votre code svg dans un fichier séparé comme une image.
dezman

6
malheureusement, je ne pense pas que cette solution fonctionne avec les sprites SVG. par exemple, content: url(mysprite.svg#my-icon)ne fera pas apparaître votre icône. j'aimerais qu'on me prouve le contraire, cependant :)
Jason

1
@watson, sémantique. La structure HTML =, CSS = présentation. Si un SVG est décoratif, il ne devrait pas être dans la structure HTML, il devrait être en CSS.
Deathlock

137

Oui. Vous pouvez ajouter le SVG comme image d'arrière-plan d'un vide: après ou: avant. Voici:

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

4
Je trouve celle-ci l'une des meilleures solutions, après avoir cherché pendant un certain temps. Vous pouvez contrôler chaque aspect de l'élément inséré et travailler de la manière habituelle avec les feuilles de style CSS, avec une logique séparée. Génial
Danielo515

... ahh cela a fait naître mes espoirs, jusqu'à ce que je réalise que ce background-sizen'est pas supporté dans Opera Mini. C'est tellement frustrant.
Deathlock

Fonctionne très bien. @deathlock, la taille de l'arrière-plan ne devrait pas être nécessaire car vous définissez les dimensions dans le svg lui-même, je n'en avais pas besoin.
Eric Soyke

1
Doit être les réponses acceptées puisque la question dit "dans un pseudo-élément: avant ou: après"
ZalemCitizen

J'ai dû ajouter <?xml version="1.0" encoding="utf-8"?>au début de mon fichier svg pour le faire fonctionner.
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;
}

assurez-vous que votre svg ne contient pas de guillemets doubles et uriencode tous les symboles #.


8
Étant donné que les SVG utilisent souvent des guillemets doubles, vous pouvez également utiliser des guillemets simples externes. La suggestion de @ Jenny est un excellent moyen de le faire si vous ne souhaitez pas utiliser un fichier SVG externe.
Micros

2
C'est bien. Malheureusement, cela ne fonctionne qu'avec Chrome pour moi (testé sur Chrome, Firefox et Edge).
Arsen

2
OK ça marche sur FF. Juste besoin de faire attention à la partie "non #". Assurez-vous également d'utiliser la balise div (ne semble pas fonctionner avec span). Malheureusement toujours pas de succès pour Edge.
Arsen

Comme tant de solutions brillantes, il n'est pas pris en charge par IE11. url('file.svg')fonctionne cependant.
Bob Stein

6
Ce que j'ai trouvé important, c'est d'ajouter xmlns='http://www.w3.org/2000/svg'la partie <svg> pour fonctionner dans Chrome 66.x. Par exemple - petit chevron sera: 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

L'utilisation des sprites CSS et de l'uri de données offre des avantages supplémentaires intéressants comme un chargement rapide et moins de demandes ET nous obtenons le support IE8 en utilisant image / base64:

Exemple de codepen utilisant 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;
}

Pour IE8, passez à ceci:

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

Mais ce n'est pas évolutif, non? Je ne peux pas le redimensionner à 16px ou 320px à volonté.
Deathlock

@deathlock Bien sûr, il évolue, mais pas mon échantillon car il a un ensemble de taille fixe, 80px large / haut.
Ason

1
@deathlock Puis-je vous demander si vous avez voté contre parce que l'échantillon ci-dessus n'a pas évolué?
Ason

comment le feriez-vous évoluer? Et non, je ne l'ai pas fait.
Deathlock

@deathlock Merci, et voici une façon de faire évoluer svg: jsfiddle.net/ess6ywce ... en utilisant le pourcentage. En outre, recherchez SO avec scale svget vous trouverez de nombreuses autres façons
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>

Outil pratique pour l'encodage d' URL SVG encodage


5

Soyez prudent, toutes les autres réponses ont un problème dans IE.

Permet d'avoir cette situation - bouton avec icône ajoutée. Tous les navigateurs gèrent cela correctement, mais IE prend la largeur de l'élément et met à l'échelle le contenu avant pour l'adapter. JSFiddle

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

La solution consiste à définir la taille sur l'élément avant et à le laisser où il se trouve:

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

Les solutions background-image+ background-sizefonctionnent également, mais sont peu pratiques, car vous devez spécifier deux fois les mêmes tailles.

Le résultat dans IE11:

Rendu IE


5

Pour approfondir ce sujet. Si vous souhaitez ajouter des icônes Font Awesome 5, vous devez ajouter du CSS supplémentaire.

Les icônes par défaut ont des classes svg-inline--faet fa-w-*.

Il y a aussi des classes comme modificateur fa-lg, fa-rotate-*et d' autres. Vous devez vérifier le svg-with-js.cssfichier et trouver le CSS approprié pour cela.

Vous devez ajouter votre propre couleur à l'icône css sinon elle sera noire par défaut, par exemple fill='%23f00'%23est encodée #.

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
Vous devriez expliquer un peu plus votre réponse. Juste à partir de cela, il est vraiment difficile de dire comment ou pourquoi votre réponse fonctionne.
ifconfig
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.