Création de lettrines variables en CSS

La question qui se pose est la suivante : comment gérer l'affichage d'une lettrine pour un titre ou un paragraphe dont l'image de fond correspondrait au premier caractère du contenu de ce titre ou de ce paragraphe ?

J'ai eu � relever ce « challenge » dans le cadre d'un projet pour lequel les titres de niveau 4 (<h4>) devaient être affichés de cette manière.

N'ayant aucune méthode en CSS pure pour déterminer la valeur du premier caractère du titre, il faut donc passer par un langage de script, la pseudo-classe first-letter permettant bien de modifier l'aspect de la première lettre de la balise associée mais indépendament de sa valeur...

Notre script va donc parser le contenu de la page pour ajouter dynamiquement une classe spécifique � notre titre, le nom de la classe étant directement lié � la valeur du premier caractère de ce titre; il s'agit de donc de remplacer <h4> par <h4 class="..."> et de définir ensuite une classe pour chaque cas (les 26 lettres de l'alphabet et les 10 chiffres).

Méthode PHP

La méthode PHP consiste � parser le contenu final de la page pour ajouter le nom de la classe � chaque élément <h4>; cela peut se faire soit en sortie de votre moteur de template, soit via les fonctions de bufferisation de sortie de PHP. Dans un cas comme dans l'autre, vous récupérez le contenu final de la page auquel vous appliquez le traitement suivant :

while ( preg_match('/<h4>(.*?)</h4>/is', $content, $match) ) {
    $firstLetter = strtolower(substr($match[1], 0, 1));
    $content = str_replace(
        $match[0], 
        '<h4 class="chr-'.$firstLetter.'">'.$match[1].'</h4>', 
        $content
    );
}

Méthode javascript

En javascript, vous devez utiliser la fonction getElementsByTagName pour avoir accès aux attributs et au contenu de votre titre. Votre script de traitement doit survenir au chargement de la page c'est � dire dans l'événement onload du body :

window.onload = function () {
    if ( document.getElementsByTagName ) {
        var x = document.getElementsByTagName('h4');
        for ( var i = 0; i < x.length; i++ ) {
            var label = x[i].childNodes[0].nodeValue;
            var firstLetter = (label.substr(0,1)).toLowerCase();
            x[i].className = 'chr-' + firstLetter;
        }
    }
}

Il faut noter au passage la vérification de l'existance de la méthode getElementsByTagName pour éviter des erreurs avec les navigateurs de la gérant pas (tous les navigateurs récents étant sensés le faire...).

La feuille de style

Nous pouvons ensuite ajouter les lignes suivantes dans la feuille de style :

h4.chr-a { background-image: url(images/a.png); }
h4.chr-b { background-image: url(images/b.png); }
h4.chr-c { background-image: url(images/c.png); }
/* etc. */
h4.chr-9 { background-image: url(images/9.png); }
h4.chr-0 { background-image: url(images/0.png); }

Pour information, le nom des classes a été préfixé car un tel nom ne peut pas commencer par un chiffre, <h4 class="9"> n'est donc pas valide.

PHP ou javascript ?

Quelle méthode choisir ? Quelle est la meilleure, la moins pire ?

Dans le cas du traitement PHP, tout se fait du coté du serveur, ce qui est transparent pour le client qui reçoit la page. L'affichage du code source HTML retourne la balise modifiée : <h4 class="chr-t">Titre du paragraphe</h4>.

Dans le cas de la méthode en javascript, le client reçoit le contenu "brut" et c'est lui qui doit effectuer les traitements au moment de l'affichage de la page. L'affichage du code source HTML retourne la balise modifiée : <h4>Titre du paragraphe</h4>. Ce type de traitement peut être plus lourd dans le cas où il y a beaucoup d'éléments sont concernées.

D'autre part, la méthode getElementsByTagName n'est pas connue pour des clients anciens ce qui pourrait provoquer des erreurs ou des défauts d'affichage (le script présenté plus haut est minimaliste et ne prend pas en compte ce cas, il faut ajouter un test sur la disponibilité de getElementsByTagName avant de l'utiliser; dans le cas où elle n'existe pas il faut alors définir un style alternatif).

La méthode PHP semble donc être la meilleure : indépendante vis � vis du navigateur client et transparente quant � l'exécution des traitements, elle peut même être intégrée dans un système de cache.

Remarque : une troisième méthode pourrait être l'utilisation des « behaviors », une fonctionnalité propre � Internet Explorer qui permet d'associer un script javascript � un style, le code javascript associé étant similaire � celui présenté plus haut :

h4 {
    behavior: url(first-letter.htc);
}

Je ne détaillerai pas cette méthode ici étant donné qu'elle n'est pas standard même s'il existe des tentatives pour que cette fonctionnalité soit prise en compte dans Mozilla.

Posté le lundi 09 août 2004 dans , .

Commentaires

Ajouter un commentaire

Il n'est plus possible de réagir à cette entrée directement mais si vous pensez que votre intervention peut être intéressante, envoyez-moi votre commentaire, je l'ajouterai ici en votre nom.