Le problème des cadres arrondis en HTML
Par Benjamin le vendredi 10 octobre 2008, 10:41 - technique - Lien permanent
Faire des cadres à coins arrondis en HTML qui s'adaptent à la taille du contenu n'est pas une sinécure. Les limitations actuelles de CSS conduisent souvent à un code HTML plus ou moins pollué par la mise en forme. Cet article présente un exemple de mise en oeuvre de la technique de décoration qui fait appelle à Javascript pour pallier à cet inconvénient.
Le problème des cadres à coins arrondis est vieux comme le Web. En HTML et CSS, alors qu'il est très simple de faire des cadres rectangulaires qui se redimensionnent tout seuls, il n'existe pas de façon simple de faire le même genre de cadres avec des coins arrondis ou plus généralement des cadres composés d'images.
En attendant la prochaine version de CSS qui devrait apporter une solution propre, il faut se résoudre à utiliser un contournement. Sur ce point il y a deux écoles : ceux qui utilisent des éléments TABLEs et ceux qui utilisent des DIVs avec du CSS. Aucune de ces deux méthodes n'est satisfaisante. La première car elle détourne l'élément TABLE de son usage normal (représenter des données tabulaires). La seconde car elle introduit une multitude d'éléments DIV qui ne portent aucun sens et polluent le HTML. En outre, les inconvénients existent aussi bien du côté client (code HTML pollué donc plus lourd et moins accessible) que du côté serveur (on se retrouve avec du spaghettiware HTML à maintenir).
Cet article présente un exemple d'utilisation d'une technique qui ne résout pas tous ces problèmes mais qui permet de faciliter la maintenance du code HTML. Cet exemple ne prend pas non plus parti dans la querelle des pro-DIV contre les pro-TABLE, mais arbitrairement, il s'appuie sur un layout en TABLEs. L'objectif est d'avoir un code HTML non pollué par la mise en forme, du point de vue du développeur (on ne peut hélas pas grand chose pour le client...).
Le principe consiste à utiliser du Javascript pour décorer le code HTML en ajoutant là où on le souhaite les fameux cadres à coins arrondis. Pour développer commodément la chose et s'assurer de la portabilité du code, le recours à la librairie Prototype n'est pas inintéressant, aussi ne s'en privera-t-on pas.
Voici donc une page d'exemple : page_sans_cadre.html dont le code source est le suivant :
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="fr_FR"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <p>Ceci est une page qui parle pour ne rien dire</p> <div class="important"> <p>Ceci est une zone encadrée que j'aimerais bien voir encadrée</p> <p>Et puis, je préfère les coins arrondis car c'est plus joli !</p> </div> <p>Ceci est le bas de la page...</p> </body> </html>
Le but du jeu est de faire un cadre à bord arrondis autour de la section importante (celle de class "important"). On peut bien sûr faire cela directement dans le code HTML, à coups de TABLE et CSS et en utilisant des images pour le cadre. On aboutit au code HTML suivant :
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html lang="fr_FR" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link href="./cadre.css" type="text/css" rel="stylesheet" /> </head> <body> <p>Ceci est une page qui parle pour ne rien dire</p> <table> <tbody> <tr> <td class="coin_haut_gauche"/> <td class="bord_haut"/> <td class="coin_haut_droit"/> </tr> <tr> <td class="bord_gauche"/> <td class="coeur'> <div class="important"> <p>Ceci est une zone encadrée que j'aimerais bien voir encadrée</p> <p>Et puis, je préfère les coins arrondis car c'est plus joli !</p> </div> </td> <td class="bord_droit"/> </tr> <tr> <td class="coin_bas_gauche"/> <td class="bord_bas"/> <td class="coin_bas_droit"/> </tr> </tbody> </table> <p>Ceci est le bas de la page...</p> </body> </html>
avec la feuille style suivante : cadre.css
Le résultat peut être visualisé ici : page_avec_cadre.html
Cela fonctionne, mais le fichier a doublé de volume, et c'est un devenu un cauchemar pour celui qui doit maintenir ce code...
La technique de décoration avec Javascript permet de revenir à un code très voisin du code d'origine. C'est en Javascript que le DOM sera modifié pour ressembler au code complexe ci-dessus. Avec Prototype, il suffit de quelques lignes pour enrober dans une table la section "importante". Voici le code utilisé :
function decore(){
var element = $$('.important')[0];
var td = element.wrap('td');
td.addClassName('coeur');
var tr= td.wrap('tr');
td.insert({before : '<td class="bord_gauche"></td>'});
td.insert({after : '<td class="bord_droit"></td>'});
var tbody = tr.wrap('tbody');
tbody.wrap('table');
tr.insert({before : '<tr><td class="coin_haut_gauche"></td><td class="bord_haut"></td><td class="coin_haut_droit"></td></tr>'});
tr.insert({after : '<tr><td class="coin_bas_gauche"></td><td class="bord_bas"></td><td class="coin_bas_droit"></td></tr>'});
}
Event.observe(window,'load',decore,false);
Voici la nouvelle forme du fichier HTML :
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="fr_FR"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script type="text/javascript" src="./prototype.js"></script> <script type="text/javascript" src="./test.js"></script> <link href="./test.css" type="text/css" rel="stylesheet" /> </head> <body> <p>Ceci est une page qui parle pour ne rien dire</p> <div class="important"> <p>Ceci est une zone encadrée que j'aimerais bien voir encadrée</p> <p>Et puis, je préfère les coins arrondis car c'est plus joli !</p> </div> <p>Ceci est le bas de la page...</p> </body> </html>
Vous remarquerez que l'on est revenu à une structure simple, non polluée par la mise en forme. Seule différence avec le code d'origine : les deux entités script de l'entête et bien sûr la feuille de style. Le résultat peut être vu ici : page_avec_cadre_decore.html
Si cet article vous a intéressé, n'hésitez pas à nous laisser un commentaire ou à vous abonner à notre flux RSS.
Peut-être serez-vous également intéressé par ces articles :
Commentaires
Que dire, sinon...
http://plugins.jquery.com/search/no...
;-)
Quatre plugins jquery qui te font ça en une ligne de code... Pourquoi donc avoir choisi prototype ? ;-)
Bonjour JulienW,
Effectivement, le plugin jquery corners permet de faire des choses bien sympathiques pour des cadres réguliers et unis. Par contre, je ne suis pas sûr qu'il permette de faire des cadres un peu plus fantaisistes (dégradés, ombres portées,...) ou des cadres qui s'appuient sur des images pour faire des bordures irrégulières.
Et puis, pour JQuery ou Prototype, comme on dit, les goûts et les couleurs... Je ne vais pas lancer un troll sur mon propre blog ;-)
Ah, pour faire cela, c'est plutôt le cinquième : "cornflex jQuery plugin".
Ceci dit, pour quand même avoir une note positive: c'est une belle application du principe d'enrichissement progressif :-)
Bonjour,
Je n'utilise que rarement Javascript parce que je ne le maitrise pas aussi j'ai quelques petites questions de débutante:
Concrètement, comment dois-je m'y prendre?
Je dois ajouter un fichier appelé prototype.js qui contient déjà du code? Je le récupère où?
Le bout de code javascript présenté sur ce blog est-il un bout de code de prototype.js qui a été modifié ou est-ce un bout de code qu'on doit ajouter dans un fichier séparé? test.js?
Merci de votre aide,
Mel
Bonjour Mel,
La librairie prototype peut être téléchargée sur son site officiel : http://www.prototypejs.org/. C'est un fichier Javascript (prototype.js) qu'il faut mettre sur le serveur HTTP et référencer dans le fichier HTML qui va l'utiliser
Le bout de code présenté dans ce blog, contenu dans le fichier test.js lui aussi référencé par la page HTML, a été écrit pour les besoins de l'exemple. C'est du code qui s'appuie sur prototype, mais ce n'est pas un morceau de prototype. Par mesure "d'hygiène", on sépare clairement prototype (le fichier prototype.js qu'on copie tel quel dans l'aborescence du serveur) du code spécifique à l'exemple (le fichier test.js développé pour l'exemple).