Cette fonctionnalité n'est pas implémentée par Internet Explorer jusqu'à la version 7. Par conséquent, ce qui suit ne concerne que la version 8 d'IE, ainsi que Firefox, Opera, Safari, Konqueror et tout autre navigateur implémentant les pseudo-éléments :before et :after, ainsi que la propriété content.

Afficher la valeur d'un attribut HTML en CSS

Un exemple pratique est d'afficher la valeur d'un attribut HTML, comme celle de l'attribut hreflang de l'élément a, qui permet de signaler que le lien mène à une page dans une langue différente de celle utilisée par la page contenant le lien en question. Autrement dit, prenons le bout de code HTML suivant :

<p>Du texte comportant un lien vers une page en langue étrangère,
comme la <a href="http://www.w3.org" hreflang="en">page d'accueil du W3C</a>.</p>

Nous souhaitons afficher, après le texte du lien, que ce dernier mène vers une page en anglais. Pour cela, nous recourons au sélecteur d'attribut (afin de vérifier que l'élément a contient bel et bien un attribut hreflang), au pseudo-élément :after (pour générer du contenu après l'élément sélectionné) et, pour la valeur de la propriété content, à la fonction CSS attr(), qui retourne, sous forme de chaîne de caractères, la valeur de l'attribut mentionné dans son paramètre. Ce qui, en CSS, donne la règle suivante :

a[hreflang]:after {
  content: "\0000a0("attr(hreflang)")";
}

La fonction attr() est entourée, de part et d'autre, par une chaîne de caractères, délimitée par des guillemets (qui peuvent être simples ou doubles). La première chaîne de caractères comporte un code hexadécimal à six chiffres, précédé d'une barre oblique inverse : c'est une façon de coder les caractères spéciaux, comme l'espace insécable dans ce cas, selon la norme ISO 10646.

La règle ci-dessus ajoutera donc au texte du lien une espace insécable, suivie d'une parenthèse ouvrante, de la chaîne en (la valeur de l'attribut hreflang) et d'une parenthèse fermante, soit «  (en) ».

Nous pourrions très bien ne pas vérifier que l'élément a possède l'attribut désiré. Mais, avec une règle CSS n'utilisant pas de sélecteur d'attribut, comme suit :

a:after {
  content: "\0000a0("attr(hreflang)")";
}

n'importe quel élément a sera concerné, y compris ceux qui sont dépourvus de l'attribut hreflang, auquel cas la fonction attr() retournera une chaîne vide, ce qui générera le contenu «  ()».

Le contenu généré est parfaitement compris par Firefox, Opera, Safari, Konqueror et IE 8.

Générer une image en CSS

Il est également possible du contenu en CSS à partir d'une URL, comme une image, par exemple pour orner un lien externe d'une image évoquant ce type de lien.

<p>Du texte, avec un lien externe orné d'une image&nbsp;:
<a href="http://www.victor-brito.fr" rel="external">Victor Brito, intégrateur et développeur Web</a>.</p>

Nous affichons pour tous les éléments a ayant un attribut rel de valeur external une image suggérant qu'il s'agit d'un lien externe, ce qui, en CSS, donne le code suivant :

a[rel="external"]:after {
  content: url('lien-externe.png');
  margin-left: 1ex;
}

Soit dit en passant, une marge à gauche est ajoutée, afin d'éviter que l'image ne colle au texte du lien.

L'image est bel et bien affichée.

Générer du texte en CSS, sauf dans certains cas

Prenons un autre cas plus complexe. Nous avons une liste de tags et partons du bout de code HTML suivant :

<ul id="tags">
  <li>CSS</li>
  <li>génération de contenu</li>
  <li>pseudo-éléments</li>
</ul>

D'abord, nous alignons la présentation des différents tags. Nous en profitons également pour supprimer les puces et les marges par défaut des éléments li.

#tags {
  list-style: none;
}
#tags li {
  display: inline;
  padding: 0;
  margin: 0;
}

Nous souhaitons que la liste des tags soit identifiée en tant que telle. Pour cela, nous générons le texte « Tags : », en l'appliquant avant l'élément ul, au moyen du pseudo-élément :before.

#tags:before {
  content: "Tags\0000a0: ";
}

En outre, nous voulons bien distinguer les différents tags en intercalant un caractère imprimable (par exemple, un tiret) encadré de deux espaces. Nous générons le tout avant chaque élément li, ce qui donne, en CSS :

#tags li:before {
  content: " - ";
}

Chaque tag est, ainsi, précédé d'un tiret, y compris le premier. Dans ce dernier cas, la génération de contenu donne un résultat plutôt laid (« Tags : - CSS »). Heureusement, il est possible d'annuler l'application du contenu généré ; pour cela, nous sélectionnons le premier élément li au moyen de la pseudo-classe :first-child, qu'on peut cumuler avec d'autres pseudo-classes et des pseudo-éléments. Quant à la propriété content, nous l'utilisons encore, cette fois-ci avec la valeur none.

#tags li:first-child:before {
  content: none;
}

Lorsque la propriété content a pour valeur none, cela signifie que le pseudo-élément n'est pas généré, quoi qu'il contienne. Toutefois, cette valeur n'est pas comprise par Firefox 2, Opera et Safari (ainsi que Google Chrome, qui, rappelons-le, utilise le même moteur de rendu que Safari pour les CSS). Or, comme nous utilisons l'un des deux pseudo-éléments :before et :after, il est possible d'utiliser la valeur par défaut de content, à savoir normal : en effet, la spécification CSS 2.1 du W3C, à la section sur la propriété content, dit ceci à propos de la valeur normal : computes to 'none' for the :before and :after pseudo-elements, ce qui veut dire que la valeur normal se comporte comme la valeur none lorsqu'elle est appliquée aux pseudo-éléments :before et :after. Nous pouvons donc corriger la règle CSS précédente comme suit :

#tags li:first-child:before {
  content: normal;
}

Seulement voilà : Safari ne comprend pas la valeur normal et continue à afficher un tiret avant le premier tag. Pour corriger ce problème, il est possible d'indiquer comme valeur à content une chaîne vide.

#tags li:first-child:before {
  content: "";
}

Génération de contenu en CSS et accessibilité

Même si cette fonctionnalité paraît pratique, voire sympathique, il vaut mieux éviter d'en abuser si l'on souhaite générer du contenu textuel. En effet, une page Web doit rester consultable lorsque les feuilles de style sont désactivées ou ne sont pas prises en charge (même partiellement), que l'on utilise un navigateur graphique ou que l'on recoure à des aides techniques, qui peuvent ne pas prendre en charge les CSS, fût-ce partiellement. Par conséquent, il faut veiller à ce que le contenu généré en CSS ne soit pas du contenu essentiel à la page Web consultée et à sa compréhension.

Page de test

Vous pouvez consulter la page de test de génération de contenu en CSS pour avoir un aperçu du résultat sous votre navigateur.