Traduction : Remplacement Dynamique de Texte

J’ai lu l’autre jour via le blog de Tristan un article très intéressant traitant de notre responsabilité en tant qu’utilisateur de logiciels libres.
Cela m’a fait réfléchir, et comme je ne me sens pas de pondre un script de fou et/ou de découvrir une perle encore cachée en CSS… je me suis dit que mes années de lecture en anglais allaient être mises à contribution et que j’allais participer en traduisant en français un article qui me semble très utile, et à propos duquel on m’a plusieurs fois demandé de l’aide (notamment parce qu’il est utilisé sur mon site, pour créer les dates et titres des blocs de la barre latérale), justement parce qu’il était en anglais.

Voici donc la traduction de l’article de Stewart Rosenberger sur A List Apart, intitulé Dynamic Text Replacement, et qui traite d’un procédé permettant de remplacer dynamiquement, à la volée, des « bouts de texte » par leur équivalent image dans la police/couleur/taille que vous aurez choisi, tout en respectant les standards et l’accessibilité. Il s’agit de deux scripts, un PHP et un JavaScript, associés à deux trois règles CSS, et vous voilà parti ! Les commentaires des deux scripts ont eux aussi été traduits en français.
Lisez la suite pour en savoir plus !


Début de la traduction (article d’origine ici)

[edit du 08/04/05 : petites corrections, merci Bertrand !]

L’application de styles à du texte est la première cause de migraine du webdesigner. Seule une poignée de polices sont disponibles universellement, et les effets visuels sophistiqués sont quasiment impossibles à réaliser en utilisant uniquement le couple CSS/HTML standard. Se contenter des polices traditionnelles pour le corps de texte est intelligent, mais quand on en vient aux titres, de courts blocs de texte destinés à attirer l’attention, il serait agréable d’avoir plus de choix. Nous nous sommes habitués à ce problème et le contournons en utilisant au maximum de leur potentiel le peu de polices à notre disposition, ou en remplaçant entièrement nos titres par des images.

La plupart des sites qui remplacent le texte par des images le font avec des images faites à la main, ce qui n’est pas si terrible quand il y a un petit nombre de titres, mais qui devient vite ingérable sur un site mis à jour plusieurs fois par jour. Quelle que soit la manière dont le remplacement est fait, chaque image a besoin d’être liée au texte qu’elle remplace. Cette liaison se manifeste généralement sous la forme d’une balise <img>, une feuille de style intégrée, ou un attribut id idoine. Et avec le temps, au travers de changements de mise en page, de refontes, cette liaison doit être gérée par quelqu’un.

Nous pouvons oublier ces âneries. Plus de tag <img> ou <span>, plus d’attribut id ou de temps perdu dans Photoshop, et plus de hacks CSS qui font désordre. En utilisant JavaScript et PHP, nous pouvons générer des titre-images accessibles avec n’importe quelle police de notre choix. Et nous n’avons pas besoin de changer la structure de notre HTML ou de notre CSS !

Visualisez la démo pour voir le Remplacement Dynamique de Texte en action. Puis lisez la suite pour découvrir comment ajouter cette fonctionnalité à votre site.

PHP

Ce petit script PHP (disponible ici) livrera une image PNG dynamique à notre navigateur à chaque fois qu’on lui demandera. Avant de le mettre en application, cependant, nous devons le personnaliser pour notre application spécifique. C’est le but des 7 premières lignes du script :

$font_file = 'font.ttf' ;
$font_size = 56 ;
$text_color = '#ffffff' ;
$background_color = '#000000' ;
$transparent = true ;
$cache_images = true ;
$cache_folder = 'cache' ;
  • la variable $font_file doit être remplie par le chemin local (pas l’URL) d’une police TrueType (TTF) ou Open Type (OTF) sur votre serveur web. C’est la police qui sera utilisée pour la création de vos images; vous devrez la télécharger sur votre serveur depuis votre ordinateur.
  • $font_size, et ce sans surprise, se réfère à la taille de la police en points.
  • $text_color et $background_color sont les codes couleurs hexadecimaux qui indiquent respectivement la couleur du texte et celle du fond de l’image.
  • Quand $transparent a pour valeur true, les bords du texte de l’image seront mélangés/fondus avec la couleur de fond afin d’empêcher l’anti-aliasing, et la couleur de fond réelle sera entièrement invisible.
  • En définissant $cache_images comme true, et $cache_folder comme le chemin local vers un répertoire accessible en écriture sur votre serveur web, ce script enregistrera chaque image qu’il créée, les conservant pour une utilisation ultérieure. Ceci peut considérablement accélérer l’affichage des images pour vos visiteurs, et se révèle particulièrement important sur des serveurs partagés ou connaissant un fort trafic.

Pour installer ce script, téléchargez-le sur un serveur web configuré avec le support du PHP. Pour être plus précis, il vous faudra la version 4.3 ou supérieure de PHP, compilée avec le support de la librairie graphique GD, 1.6 ou supérieure. Si tout cela ne vous parle pas, envoyez par e-mail ces spécifications à votre hébergeur et il vous fera savoir si votre serveur est compatible.

Edit du 24 avril 2005 (merci Bebop !) :
NB : Pour ces dernières versions récentes de la librairie GD, il faut ajouter “./” au début du chemin de la police.

Ce qui donne :

$font_file = './font.ttf';

au lieu de

$font_file = 'font.ttf';

Bien que nous ayons utilisé PHP pour construire les images dans cette implémentation, votre site n’a pas besoin d’utiliser activement le PHP pour tirer parti de cette technique. Quelle que soit la manière dont vous générez vos pages HTML, qu’elles soient éditées à la main ou à travers un CMS, vous pouvez utiliser cette technique tant que vous insérez un tag <script> dans la partie <head> de vos documents. J’expliquerai ce point plus en détail ci-dessous.

Veuillez noter que ce qui peut être fait avec PHP peut souvent être fait avec d’autres outils. Perl, ASP, Java servlets, et d’autres langages de programmation serveur seraient aussi de bons candidats pour la génération d’images personnalisées. PHP est un choix excellent grâce à sa grande disponibilité, son indépendance à la plateforme utilisée, et un apprentissage facile. Considérez des alternatives si vous avez besoin de quelque chose que PHP ne peut vous fournir ou si vous choisissez de créer votre script de génération d’image à partir de zéro. Il serait sûrement plus simple, cependant, de simplement adapter le code PHP présenté ici.

Une chose que notre personnalisation du script n’inclut pas est le texte qui doit être utilisé pour la génération des images. C’est parce que le texte que nous utilisons pour générer les images sera passé au script via son URL. Par exemple, charger l’URL heading.php?text=Les%20URLs%20Sont%20Fun retournera une image représentant “Les URLs Sont Fun”. Et elles le sont ! Mais nous n’aurons pas besoin d’écrire les URLs nous-même puisque le JavaScript s’en chargera pour nous.

JavaScript

Téléchargez le fichier source JavaScript ici.

Cette technique emprunte beaucoup de la méthode de Remplacement des Images par Javascript (JIR) de Peter-Paul Koch. Le principe de base de JIR est très simple. Beaucoup de codeurs de CSS exploitent des bugs de navigateurs pour cacher des styles CSS à ces navigateurs. Ces hacks sont proches de déclarations conditionnelles dans leur code, transformant les CSS en un langage de programmation assez brut. Plutôt que d’utiliser ce « langage-des-bugs », Koch et d’autres ont avancé l’idée que JavaScript, un vrai langage de programmation, pouvait effectuer la même tâche de manière plus intelligente et accessible. C’est merveilleux pour notre démarche, car JavaScript apporte aussi plus de flexibilité. Plus précisément, nous l’utiliserons pour remplacer le texte par des images qui n’existent même pas encore.

Quand la page est chargée pour la première fois, le script essaye de charger une petite image (1x1 pixels) de test (téléchargez un exemple ici). Si ce test fonctionne, on peut en conclure que le navigateur du visiteur est capable d’afficher des images, sinon il n’aurait pas gâché de bande passante à la télécharger. C’est le cœur du fonctionnement de JIR. En testant le support des images, nous pouvons immédiatement déterminer si nos visiteurs ont besoin de titres stylisés ou non. Si non, le script s’arrête à cet endroit.

Partant du principe que le navigateur prend en charge les images, donc, le script attend que la page soit entièrement chargée, parce qu’il ne peut remplacer du texte qui n’a pas encore été téléchargé. Une fois que le HTML est complètement chargé, notre script va chercher les éléments spécifiés (<h2>, <span>, etc.) et remplacer le texte qu’ils contiennent par un tag <img>. Ce tag <img> dynamique a pour attribut alt le texte d’origine, et comme attribut src l’URL du script PHP que nous avons installé. Le script PHP renvoie alors une image PNG personnalisée, et voilà : des titres personnalisés !

Pesant un bon 8Kb, il se passe beaucoup de choses dans ce coin du ring, mais il n’y a en fait que deux lignes à modifier pour que le script fonctionne :

replaceSelector("h2","heading.php",true);
var testURL = "test.png" ;

La fonction replaceSelector accepte trois paramètres : le premier est le sélecteur CSS qui indique quels éléments doivent être remplacés. Ce sélecteur peut être presque n’importe quel sélecteur CSS valide, id, class, sélecteurs d’éléments et d’attributs inclus.

Le deuxième paramètre est l’URL de notre script PHP.

Le troisième paramètre est une valeur vrai/faux (true/false) qui indique si le retour à la ligne automatique doit être activé pour ce remplacement. Quand ce paramètre a pour valeur true, les titres sont séparés en plusieurs images, une par mot. Quand il vaut false, une image unique est générée pour chaque titre.

replaceSelector devrait être appelée une fois pour chaque groupe d’éléments que vous voulez remplacer par une image personnalisée. Les URL de ces lignes peuvent être absolues (http://...) ou relatives à votre fichier HTML (chemin/nomdefichier).

La variable testURL doit être définie par l’URL de votre petite image (1x1 px) de test.

Une fois que ces lignes sont correctement paramétrées, vous pouvez télécharger le fichier JavaScript sur votre serveur web, et l’appliquer à vos pages en ajoutant la ligne suivante dans le <head> de vos documents.

<script type="text/JavaScript" src="replacement.js"></script>

Assurez-vous que l’attribut src dans cette ligne pointe vers l’endroit où vous avez placé votre fichier JavaScript.

C’est tout ce qu’il est nécessaire de faire pour que le Remplacement Dynamique de Texte fonctionne, nous pouvons donc nous arrêter là si nous le souhaitons.
Mais il existe quelques améliorations que nous pourrions mettre en place pour aller plus loin.

Versions Imprimées

Comme vu auparavant sur ALA, beaucoup de sites emploient dorénavant des feuilles de styles spécifiques à l’impression afin d’offrir à leurs visiteurs de meilleures versions papier de leur contenu. Dans beaucoup de cas, ceci implique d’inverser le processus de remplacement des images afin que la version imprimée d’une page utilise les polices réelles plutôt que des graphiques, qui ont souvent un mauvais rendu sur les imprimantes hautes résolutions. Malheureusement, JavaScript ne peut résoudre ce problème. Une fois que nous avons remplacé notre texte par une image, il est impossible d’inverser ce processus spécialement pour l’impression, et nous devons donc trouver une autre solution.

Au lieu d’essayer d’inverser notre processus de remplacement, nous pouvons planifier un peu à l’avance. En plus d’insérer un tag <img> dans nos titres, nous pouvons aussi insérer un tag <span> qui contient le texte de titre d’origine. Et nous pouvons donner à l’attribut display la valeur none, afin que le <span> ne soit pas affiché à l’écran. Maintenant nous avons deux copies de notre texte d’origine. Une dans une image visible, l’autre dans un <span> caché. En donnant à chacun de ces éléments des attributs class identifiables (“replacement” et “print-text”, respectivement), et en ajoutant une feuille de style spécifique à l’impression, nous pouvons interchanger leurs propriétés d’affichage à l’impression.

La feuille de style suivante (télécharger un exemple ici) pourrait être utilisée pour générer une version imprimée appropriée de votre page :

span.print-text { display: inline !important; } img.replacement { display: none; }

Une fois que nous avons téléchargé cette feuille de style sur notre serveur web, nous avons seulement besoin de changer deux lignes dans notre JavaScrit pour la rendre fonctionnelle :

var doNotPrintImages = false;
var printerCSS = "replacement-print.css";

En donnant à la variable doNotPrintImages la valeur true, et à printerCSS la valeur de l’URL de notre feuille de style, le script insèrera automatiquement le tag <link> approprié dans le <head> de notre document.

Sans clignotement

Comme notre script ne peut commencer à remplacer les éléments qu’une fois le document entièrement chargé, il y aura souvent un flash rapide de contenu non stylisé pendant que navigateur attends que le processus de remplacement commence. C’est moins un problème qu’un inconvénient mineur, mais comme il est possible d’y échapper, autant y remédier. Avec l’aide d’une autre petite feuille de style, nous pouvons faire précisément cela.

Avant que le corps du document ne commence à être chargé, nous pouvons dynamiquement insérer une feuille de style qui cachera entièrement ces éléments. Comme les feuilles de style sont appliquées au fur et à mesure que le document est rendu, aucun contenu ne sera visible pendant cette période. Une fois que notre technique de remplacement a fini de s’exécuter, nous pouvons neutraliser cette feuille de style, et nos titres fraîchement stylisés seront à nouveau visibles.

Par exemple, si votre page était paramétrée pour remplacer les tags <h2>, la feuille de style suivante (disponible ici) les cacherait jusqu’à l’achèvement de notre technique de remplacement :

h2 { visibility: hidden; }

Cependant, il y a un léger problème avec cette approche. Notre technique entière dépend du chargement d’une image de test afin d’indiquer si le navigateur supporte ou non les images. Si l’image ne se charge pas, notre technique ne sera jamais activée. Et si notre technique n’est pas activée, la feuille de style qui cache nos titres non stylisés ne sera jamais neutralisée. A cause de cela, les visiteurs qui ont désactivé le support des images dans leur navigateur, mais qui peuvent quand même utiliser JavaScript et les CSS, ne verront rien d’autre qu’un espace vide où nos titres auraient dû se trouver.

Nous améliorerons l’expérience de navigation déjà difficile de cette minorité en ajoutant une valeur d’arrêt minuté au script. Si l’image de test n’a pas été chargée avec succès après une ou deux secondes (ou après la durée que vous souhaitez), le script neutralisera automatiquement cette feuille de style et les titres apparaîtront. Ces une ou deux secondes sont un dérangement léger pour ces personnes exceptionnellement rares, mais cela résout le problème de clignotement pour les autres 99,99% de nos visiteurs. Le plus important est que nous maintenions l’accessibilité pour tout le monde.

Pour permettre cette personnalisation (optionnelle), et pour enlever le bref flash de contenu non stylisé, vous devez éditer trois lignes dans le fichier JavaScript :

var hideFlicker = false;
var hideFlickerCSS = "replacement-screen.css";
var hideFlickerTimeout = 1000;

Donnez comme valeur true à la variable hideFlicker et l’URL de votre fichier CSS à la valeur hideFlickerCSS.

hideFlickerTimeout devrait avoir pour valeur le nombre maximum de millisecondes (c-à-d : 1/1000 seconds) que le script doit attendre avant de neutraliser cette feuille de style.

Notes et Suggestions

Certaines versions plus anciennes de Mozilla, Netscape 6.2 inclus, contenaient un bug qui déclenchait le chargement des images même si l’utilisateur avait indiqué de ne pas les afficher. C’était bien entendu une aberration et fût fixé dès la version 1.4. Même si cette technique devrait normalement fonctionner sans problème dans ces navigateurs, le script ne diagnostiquera pas correctement le support (ou non) des images et échouera quand les visiteurs utilisant ces navigateurs auront désactivé le support des images. Je ne considère pas qu’il s’agisse d’une occurrence suffisamment fréquente pour être un inconvénient sérieux, mais il faut le noter par souci d’exhaustivité. Il n’y a pour l’instant aucun contournement à ce problème.

Utilisez cette technique avec un service de traduction, comme ceux de Google ou Altavista. Tant que votre police supporte les caractères étrangers, les images dynamiques seront traduites aussi. Le texte que vous remplacez n’a pas besoin d’être dans un tag de titre (<h1>, <h2>, etc.) ; il peut être dans n’importe quel élément de la page. Avec l’aide de quelques ajustements assez simples, et des manipulations des valeurs de float, cette technique pourrait créer des lettrines dynamiques pour chaque paragraphe auquel vous l’appliquez.

Vous pouvez aussi remplacer vos tags <a>, et offrir à votre page des hyperliens stylisés, quoique faire fonctionner des rollovers demande plus de personnalisation.

Au lieu de remplacer du contenu par des tag <img> générés dynamiquement, cette technique pourrait totalement éviter l’utilisation du PHP et insérer des animations Flash dynamiques à la place.

Remerciements

Peter Paul Koch, pour sa technique de Remplacement des Images par JavaScript.

Simon Willison, pour sa fonction getElementsBySelector.

Stuart Langridge, pour ses Techniques JavaScript Discrètes.

Traduit avec la permission de A List Apart Magazine et l’auteur. Translated with the permission of A List Apart Magazine and the author.

Commentaires