Cet article est une « craduction »(1) de l’excellent article Why Inline CSS And JavaScript Code Is Such A Bad Thing dans lequel Robert Nyman explique pourquoi il est bon de séparer la structure HTML, la présentation CSS et l’interactivité Javascript dans le processus de conception d’un site web. Chaque partie devrait faire l’objet d’un fichier distinct où l’intrusion des deux autres devrait être limitée au strict minimum. Yalla, en avant les jeunes !
Lorsque je passe en revue des sites web, y compris ceux auxquels je participe en collaboration avec d’autres personnes, je tombe souvent sur des choses que les développeurs web devraient éliminer de leur pratique : mettre du code CSS et Javascript au beau milieu du code HTML.
### Qu’est-ce qu’un style CSS ou un Javascript en ligne ?
C’est lorsque le code HTML est truffé de CSS et de Javascript, mélangeant ainsi la structure (HTML), la présentation (CSS) et l’intéractivité (Javascript). Comme ceci :
### Pourquoi est-ce si mauvais ?
Mise à part les notions de propreté du code et de facilité de lecture en général, il existe d’autres raisons moins subjectives :
* **Poids de la page HTML** — En vous débarassant des éléments en ligne superflus, vous optimisez vos fichiers.
* **Caching impossible** — Le code HTML n’est pas mis en cache contrairement aux fichiers CSS ou Javascript externes. Les éléments en ligne sont donc chargés systématiquement : la présentation et les intéractions présentes dans votre code HTML ne seront pas chargées aussi rapidement que si elles l’étaient à partir du cache du navigateur.
* **Faible accessibilité** — Les interactions Javascript en ligne comme l’événement `onclick` vu plus haut, s’appliquent souvent à des éléments qui ne possède pas de comportement associé par défaut (un lien possède un attribut `href` permettant d’accéder à la ressources désirée, etc.) : votre lien ne mènera nulle part si Javascript n’est pas activé.
* **Difficulté à maintenir le code** — Tous les développeurs web seront d’accord pour reconnaitre qu’il est plus facile de s’y retrouver lorsque le code est centralisé plutôt qu’éparpillé au quatre coins du site web.
#### Tout le monde n’a pas Javascript de nos jours ?
Premièrement, non, tout le monde n’a pas Javascript. Deuxièmement, certaines personnes désactivent volontairement le JS sur leur navigateur (par ex. l’extension Firefox NoScript a été téléchargée 31 millions de fois à ce jour). Troisièmement, dans certains cas, l’utilisateur ne choisit pas son environnement et Javascript peut ne pas être disponible. Ces circonstances sont :
* Les programmes anti-virus ou les pare-feu (firewall) qui peuvent être parfois trop sévères dans leur jugement vis-à-vis du code Javascript.
* Certains proxy d’entreprise qui filtrent le code (lire An important lesson learned about AJAX and accessibility à ce sujet).
* Autres réglages d’accès à internet propres à certaines entreprises empêchant d’exécuter le code Javascript dans de bonnes conditions.
### Voici comment vous devriez développer
Un développeur d’interface normalement constitué sait qu’il ou elle devrait faire l’effort de produire une structure séparant totalement le contenu (la page HTML proprement dite) de la présentation (CSS) et des interactions (Javascript). Autrement dit, il ne devrait y avoir ni styles CSS en ligne ni Javascript au milieu de votre code HTML.
Une seule voie possible : ne dépendre que des attributs `id` et `class` pour déclencher vos actions.
Réécrivons proprement l’exemple à ne pas suivre vu plus haut :
/* Code CSS dans un fichier séparé (base.css) */
#container {
width: 800px;
margin: 1em auto:
font: bold 1em/1.2 Verdana, Arial, Helvetica, sans-serif;
}
#navigation {
float: left;
width: 400px;
padding: 1em 2em;
font-size: 0.9em;
}
/* Code JavaScript dans un fichier séparé (base.js) */
window.onload = function () {
document.getElementById(« get-news »).onclick = function () {
// Get news through AJAX
};
}
La classe, non ?
#### Bien utiliser les attributs `id` et `class`
A la base, c’est très simple. Un `id` n’apparait qu’une fois par page, tandis que l’attribut `class` peut être répété autant de fois qu’on le désire. *Grosso modo*, j’utilise les `id` pour les grands blocs structurels, comme *container*, *navigation*, *main-content*, etc. Pour le reste, j’utilise des classes.
Connecter du code CSS à un élément présent dans le document HTML possédant un attribut `class` est très simple. Toutefois, lorsqu’il s’agit de Javascript et de l’accès au DOM notamment, les fonctions ne sont pas toujours entièrement implémentées dans les navigateurs. Pour y remédier, je recommande l’utilisation de la fonction getElementsByClassName qui contient par ailleurs quelques fonctionnalités inédites.
#### Manipulation des événements en Javascript
Le code du dernier exemple s’inspire de la bonne vieille méthode prévue par le bon vieux DOM niveau 1 pour appliquer des actions sur un élément. Cela fonctionne très bien quand il s’agit d’appliquer une action par élément. C’est moins évident si plusieurs événements sont associées à un élément. Il y a même de fortes chances pour que le code de quelqu’un d’autre écrase votre événement, à moins que ce soit le contraire !
Pour ne pas se prendre la tête avec les différences d’implémentation de la gestion des événements entre les navigateurs (et croyez-moi il y en a quelques-une), je recommande l’utilisation d’une bibliothèque Javascript comme DOMAssistant ou jQuery.
### Et les grands, comme Google, ils font comment ?
Bon, maintenant, j’ai réussi à vous convaincre de la justesse de mes arguments et vous êtes prêt à vous plonger dans le monde merveilleux des nouvelles méthodes de développement, mais juste par curiosité, vous jetez un oeil sur le site web le plus populaire au monde, Google, et vous pensez :
Mais, attend une minute, Robert, t’es pas en train de nous rouler dans la farine !
La page d’accueil de Google et plus spécialement la page affichant les résultats de la recherche, est truffée de styles CSS en ligne et d’événements Javascript en veux-tu en voilà. Si Google le fait, ça doit être le top, non ? Ben non. Google a peut-être des développeurs Javascript talentueux, voire même des génies dans d’autres domaines, mais en matière d’intégration HTML et CSS, ils sont un peu à la « ramasse ».
Il y a environ deux ans, mon ami Roger a réécrit proprement le code de Google en expliquant sa démarche en détail dans son billet.
Il faut considérer le taux extrêmement élevé de visiteurs que Google accueille chaque jour pour comprendre que leur mot d’ordre est performance, performance et… performance (ceux qui veulent approfondir la question plus profondément peuvent lire Improve your web site performance – tips & tricks to get a good YSlow rating). Mais bien que pour l’équipe de Google l’élimination de chaque requête HTTP superflue est crucial, ce n’est pas une excuse pour ne pas avoir un code propre et valide.
Au final, je pense que le bénéfice apporté par l’utilisation de code CSS ou Javascript inline (dans le code HTML) est négligeable, et parallèlement, dès que nous parlons de visiteurs fidélisés (par exemple, je visite Google tous les jours), l’utilisation de fichiers externes serait plus bénéfique et considérablement meilleur pour les performances tout comme pour la charge de bande passante. Egalement, en comparaison, la page de Google Mobile est dans un bien meilleur état, donc le fait que la page classique soit si pauvre a bien une raison valable –- je pense que c’est dû à quelque chose qui a été négligé et pas encore été revu (et ils sont probablement terrifiés à l’idée de revoir toute leur page).
### Conclusion
Ainsi, comme ce texte vous y invite, assurez-vous d’inclure tout votre code CSS et Javascript à partir de fichiers externes. Commencez dès aujourd’hui ! Déplacez tous les éléments en ligne que vous trouverez et vous verrez que vous vous sentirez mieux, et votre équipe aussi 😉
(1) Une « craduction » est une traduction rapide et approximative qui a pour objectif principal de faire passer le message. Vous pouvez participer à la mesure de vos moyens dans les commentaires ou en me contactant directement.
PS : Merci à Jean Lançon pour son aide dans la dernière ligne droite 😉
en avant les discussions trollesques 🙂
perso j’utilise du JS dans la page pour lancer mes méthodes d’initialisation de mes modules. Contexte :
– dans le cadre du « progressive enhancement », mes modules sont du bon HTML cliquable, par dessus lequel une classe JS dédiée doit se lancer
– cette classe doit se lancer le plus vite possible pour que l’utilisateur bénéficie si possible de la version JS (par exemple lancer un coup d’AJAX plutôt que de changer de page)
– pour lancer ces bouts de JS, il n’y a que 2 solution pure JS :
– attendre l’event body.onload
– attendre l’event document.ready
dans le premier cas, l’event est natif aux browsers mais le temps de télécharger images/CSS/JS, ça peut prendre beaucoup de temps.
dans le 2nd cas l’event n’était pas natif jusqu’à récemment, donc les librairies façon jQuery l’ont émulé : c’est le fameux $(document).ready. C’est pas terrible pour les perfs d’une part (c’est un timer dans une boucle qui teste si document est bien là, et les timers en JS ça fait mal) et si ton HTML est long à s’afficher complètement (une page de résultat de recherche par exemple) malgré les flush() PHP, il est possible que l’utilisateur ait cliqué ailleurs, sur un module sans JS, alors que le code JS est pourtant disponible.
la seule solution restante, qui possède aussi des avantages en terme d’organisation du code, est donc de mettre dans le HTML après chaque module l’appel au constructeur JS de ce module.
sinon, entièrement d’accord pour le reste : les JS ou CSS inline sont à bannir
J’utile également certains appels js juste après l’endroit dans le code HTML où ils doivent s’appliquer pour éviter certains problèmes de mise en pages. Notamment pour appliquer une classe CSS via JS pour atteindre un élément (ex. appliquer une classe .last sur des éléments générés par le CMS).
hum, le formattage m’a un peu flingué mon texte, il est limite lisible 😐
C’est pas plutôt par soucis de compatibilité avec les dinosaures que Google utilise un code aussi crade ?
Ca me semble louche qu’une boite qui a les moyens de réunir 30 développeurs niveau Nightmare pour coder une page de 100 lignes de code ne prenne pas le temps de le faire proprement.
Sinon merci tout ces détails, ça me troue le c*l que certains développeurs mettre encore du code inline.
Perso, ça ne m’étonne pas tant que ça : l’intégration web est un métier compliqué et Google n’embauche que des ingénieurs bac +1000 ^__^v
pas mieux : google ont longtemps été champion pour recruter des armées d’ingénieurs software ou des scientifiques, RAF du Web pur. Il n’y a que depuis 1 ou 2 ans qu’ils recrutent de vrais webdevs / ingés frontend, qui sortent des librairies JS, des recommandations performances et autre.
Et ils n’ont pas les mêmes contraintes que le site moyen, il y a surement des raisons historiques à leur code bizarre. Cela dit, ils ont redesigné récemment la HP et la page de recherche, ils auraient pu en profiter pour faire un peu de ménage ..
Je ne suis pas un Google Fan, mais leur code ne me choque pas.
Quand NOUS (développeurs web) réalisons un projet web, la compatibilité inter-navigateurs web et le respect des standard sont des éléments clef :
– par respect pour les visiteurs et utilisateurs (affichage universel, accessibilité)
– pour faciliter les transitions vers d’autres technologies et permettre une évolutivité et une portabilité du projet
– pour réduire les coûts de maintenance
– pour obtenir un meilleur référencement (controversé)
En gros, pour que le projet soit pérenne (de par sont évolutivité), portable, accessible et retro-compatible.
Être conforme aux normes, ce n’est pas tout.
Pour Google, c’est une autre affaire. La firme ne possède pas les mêmes contraintes qu’un site lambda.
Tout comme l’explique un employé de Google : Michael Thingmand dans cette vidéo :
Why doesn’t google.com validate?
http://youtu.be/FPBACTS-tyg
Quand un développeur standard essaye de rendre compatible son site avec une dizaine de navigateurs web et mobile (maximum) Google essaye de le rendre compatible avec des centaines de technologies marginales.
Et vu le nombre de requêtes, il est compréhensible que la page soit la plus légère possible.
Errata :
L’employé de Google en question est Matt Cutts. Michael Thingmand étant la personne ayant posé la question sur son blog.