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

246

Je me demande simplement s'il est possible de faire en sorte que la contentpropriété CSS insère du code html à la place :beforeou :afterun élément comme:

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

ce serait assez pratique ... Cela pourrait être fait via Javascript mais utiliser css pour cela faciliterait vraiment la vie :)

zanona
la source
@Kaiido OMG ... ce n'est pas le cas, je n'ai pas vérifié la date de la question, j'ai fait référence à votre réponse ... vraiment désolé, supprimera ces deux commentaires :)
Ason

Réponses:

210

Malheureusement, ce n'est pas possible. Par la spécification :

Le contenu généré ne modifie pas l'arborescence des documents. En particulier, il n'est pas renvoyé au processeur de langage de document (par exemple, pour une nouvelle analyse).

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 du 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>

... entraînera la sortie suivante:

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

BoltClock
la source
1
d'accord, mais si vous imaginez qu'il prend déjà en charge les images avec les urlattributs, l'ajout d'un lien ne serait pas si différent dans cette perspective.
zanona
12
@ludicco: C'est parce que les images elles-mêmes ne sont pas des éléments DOM (sans compter <img>), elles sont simplement dessinées sur des éléments existants, donc en appliquant des images d'arrière-plan ou de liste, vous ne modifiez pas vraiment le DOM.
BoltClock
1
je l'ai eu merci, donc je pense que je vais devoir passer cette idée et aller directement à js, cheers
zanona
6
@ludicco: Bonne question. Même moi, je cherchais dans SO en espérant que c'était possible.
Robin Maben
1
@watson: Je viens de voir votre réponse à l'autre question. Vous avez raison; Je devrais probablement préciser dans ma réponse que vous ne pouvez pas ajouter de balisage arbitraire - vous devez spécifier un fichier externe via à la url()place, comme avec toute autre image.
BoltClock
54

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

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

Mais notez qu'il s'agit principalement d'un hack et qu'il existe de nombreuses 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.
  • Étant donné que cela ne fera pas partie du DOM, la seule façon de le modifier est de passer le balisage en tant que dataURI et de modifier ce dataURI dans document.styleSheets. pour cette partie, DOMParseret XMLSerializerpeut aider .
  • Bien que la même opération nous permette de charger des médias encodés en URL dans des <img>balises, cela ne fonctionnera pas dans les pseudo-éléments (au moins à ce jour, je ne sais pas si c'est spécifié quelque part où cela ne devrait pas, donc cela peut être une fonctionnalité non encore implémentée).

Maintenant, une petite démonstration d'un balisage 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>

Kaiido
la source
J'ai trouvé votre réponse, et c'est une solution à certains de mes propres problèmes. Pouvez-vous expliquer comment formater une URL pointant vers un fichier? J'ai essayé url('/relativePathToMySvg/mySvg.svg')et cela n'a pas fonctionné
Frank
@Frank, selon les spécifications, l'utilisation d'un chemin relatif sera relative au chemin de votre fichier css, c'est-à-dire que si vous avez votre fichier css /root/css/yourFile.css, alors un funcIRI relatif comme yourFile.svgpointera vers /root/css/yourFile.svg/. Mais, je pense que je me souviens que certains UA précédents avaient un bogue et le rendaient par rapport à la baseURI du document. Donc, le moyen le plus sûr consiste simplement à utiliser un chemin absolu.
Kaiido
1
@BoltClock, vraiment? J'en suis vraiment désolé. Je suis tombé sur cette question de 6 ans par une autre et j'ai senti que je devais la poster en tant que mise à jour, mais peut-être devrais-je être encore plus clair que votre réponse est bonne et était définitivement correcte il y a 6 ans? Ou si vous avez de bonnes formulations qui pourraient correspondre à un en-tête, n'hésitez pas à modifier ma réponse.
Kaiido
1
Agréable. J'ai utilisé: content: url('../../images/como-funciona.svg');et cela fonctionne bien
Eliut Islas
Voici un article précédent, qui a une réponse à moi, qui plonge un peu plus dans le sujet: est-il-possible-d'afficher-un-document-html-ou-fragment-html-au-contenu-css
Ason
7

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

Exemple tiré du brouillon du module de contenu généré par CSS pour les médias paginés :

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

.runner { 
  position: running(heading);
}

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

EDIT: pour clarifier, il n'y a fondamentalement pas de support de navigateur, donc cela devait principalement servir de référence future / en plus des «réponses pratiques» déjà données.

sol
la source
Hé, pourriez-vous expliquer cela un peu plus. Je m'intéresse à votre théorie mais n'arrive pas à la faire exécuter. Comment pourrais-je inclure, disons, une balise d'ancrage en utilisant cette méthode ou une div.
Neil
le problème est qu'il n'y a actuellement pas de support de navigateur, mais des moteurs de rendu HTML dédiés l'implémentent selon les spécifications. La prochaine mauvaise nouvelle est qu'il ne semble pas y avoir une bonne implémentation open source; la plupart sont des produits SaaS comme princexml.com .
sol