web-dev-qa-db-fra.com

Propriété de contenu CSS: est-il possible d'insérer du HTML au lieu de texte?

Je me demandais simplement s'il était possible de faire en sorte que la propriété CSS content insère du code html à la place de la chaîne sur :before ou :after un élément du type:

.header:before{
  content: '<a href="#top">Back</a>';
}

ce serait très pratique ... Cela pourrait se faire via Javascript mais utiliser css pour cela faciliterait vraiment les choses :)

216
zanona

Malheureusement, ce n'est pas possible. Selon le spec :

Le contenu généré ne modifie pas l'arborescence du document. En particulier, il n’est pas renvoyé au processeur de langage du document (par exemple, pour la réparation).

En d'autres termes, pour les valeurs de chaîne, cela signifie que la valeur est toujours traitée littéralement. Il n'est jamais interprété comme un balisage, quelle que soit la langue du document utilisée.

Par exemple, en utilisant le CSS donné avec le code HTML suivant:

<h1 class="header">Title</h1>

... donnera le résultat suivant:

<a href="#top"> Retour </a> Titre

195
BoltClock

Comme presque noté dans les commentaires à la réponse de @ BoltClock, dans des navigateurs modernes , vous pouvez en fait ajouter du balisage HTML aux pseudo-éléments en utilisant le (url()) en combinaison avec les svg <foreignObject> élément.

Vous pouvez soit spécifier une URL pointant sur un fichier svg réel, soit la créer avec une version de dataURI (data:image/svg+xml; charset=utf8, + encodeURIComponent(yourSvgMarkup))

Mais notez qu’il s’agit surtout d’un hack et qu’il existe beaucoup de limitations:

  • Vous ne pouvez pas charger de ressources externes à partir de ce balisage (pas de CSS, pas d'images, pas de média, etc.).
  • Vous ne pouvez pas exécuter de script.
  • Comme cela ne fait pas partie du DOM, le seul moyen de le modifier est de passer le balisage en tant que dataURI et de le modifier dans _document.styleSheets_. pour cette partie, DOMParser et XMLSerializer peut aider .
  • Même si la même opération nous permet de charger des supports encodés en URL dans des balises _<img>_, cela ne fonctionnera pas dans les pseudo-éléments (du moins à ce jour, je ne sais pas s'il est spécifié à un endroit quelconque de ne pas le faire. ' t, il peut donc s'agir d'une fonctionnalité non encore implémentée).

Maintenant, une petite démonstration de certains balises HTML dans un pseudo-élément:

_/* 
**  original svg code :
*
*<svg width="200" height="60"
*     xmlns="http://www.w3.org/2000/svg">
*
* <foreignObject width="100%" height="100%" x="0" y="0">
*       <div xmlns="http://www.w3.org/1999/xhtml" style="color: blue">
*               I am <pre>HTML</pre>
*       </div>
* </foreignObject>
*</svg>
*
*/_
_#log::after {
  content: url('data:image/svg+xml;%20charset=utf8,%20%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20height%3D%2260%22%20width%3D%22200%22%3E%0A%0A%20%20%3CforeignObject%20y%3D%220%22%20x%3D%220%22%20height%3D%22100%25%22%20width%3D%22100%25%22%3E%0A%09%3Cdiv%20style%3D%22color%3A%20blue%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%3E%0A%09%09I%20am%20%3Cpre%3EHTML%3C%2Fpre%3E%0A%09%3C%2Fdiv%3E%0A%20%20%3C%2FforeignObject%3E%0A%3C%2Fsvg%3E');
}_
_<p id="log">hi</p>_
42
Kaiido

Dans les médias paginés CSS3, cela est possible avec position: running() et content: element().

Exemple tiré du contenu généré par CSS pour le module de média paginé brouillon:

@top-center {
  content: element(heading); 
}

.runner { 
  position: running(heading);
}

.runner peut être n'importe quel élément et heading est un nom arbitraire pour l'emplacement.

EDIT: pour clarifier, il n’existe en principe aucun support de navigateur, ce qui était principalement destiné à servir de référence future/en plus des "réponses pratiques" déjà données .

5
sol