Logo Julien Wilhelm, Awebsome

19 avril 2020

JavaScript (h)ate(s) my CSS

Julien Wilhelm

Dans le cadre d'un contrat, j'avais désigné une Interface Utilisateur (UI) reposant sur JavaScript.

Le problème

Les éléments HTML avaient été stylés de sorte d'être prêts à l'emploi pour le script, mais ne délivraient à l'écran qu'une partie du contenu quand JavaScript était désactivé. Le service minimum n'était donc pas assuré aux utilisateurs JS unfriendly.

La méthode conventionnelle

La logique habituelle aurait voulu que je travaille une base fonctionnelle sans script et reconfigurée sous condition (en l'occurrence, suivant la disponibilité de JavaScript ou non). Mais je suis plutôt réfractaire aux approches progressives. La transformation qui s'opère pour passer d'un état (sans script) à un autre (avec script) se fait souvent en dépit du bon sens, en remodelant du tout au tout une page après que son DOM ait été généré ou pire : en ignorant des ressources qui n'ont plus lieu d'être alors qu'elles ont été chargées et n'auront jamais servi. Les performances et la clarté du code source sont les premières à pâtir de cette méthodologie. Les utilisateurs peuvent également s'en trouver pénalisés, car le délai est plus ou moins allongé avant la prise de focus. Ces petits riens n'ont pas leur place dans les projets Web que je conduis.

La solution écoresponsable selon Awebsome

C'est en précisant à nouveau les impératifs que je m'étais fixés, à savoir...

  • Faire du JavaScript first avec des éléments prêts à l'emploi auxquels je n'ai plus qu'à attacher des évènements.
  • Disposer d'un fallback en l'absence de JavaScript SANS complexifier le code source ni surcharger les styles.
  • N'employer que le strict nécessaire dans tous les cas.

...Que j'ai compris que mon problème ne venait pas de JavaScript, mais de CSS, à cause de la cohabitation difficile des styles propres aux deux versions de mon UI (avec /sans script).

Ce constat dressé, il était évident que je devais créer deux feuilles de style indépendantes et en différer la sélection par le navigateur Web pour faire exclusivement appel à la bonne.

La méthode Awebsome pour différer la sélection d'une feuille de style, même sans JavaScript
La méthode Awebsome pour différer la sélection d'une feuille de style, même sans JavaScript.

Mon approche, côté document HTML :

  • Insérer une balise style dans le <head> du document où passer la propriété opacity de l'élément <body> à 0. L'objectif est d'empêcher l'affichage de contenu non stylisé et d'alléger l'application à retardement du CSS.
  • Insérer la feuille de style propre à l'UI de base dans une balise <noscript> située dans le <head> du document HTML.
  • Insérer la feuille de style propre à l'UI améliorée dans une balise <script> située dans le <head> du document HTML.
  • Surtout, n'insérer aucune feuille de style en dehors des balises <script> et <noscript> - sauf pour répondre à un tout autre usage, bien entendu.

Dans les feuilles de style CSS externes, il suffit de repasser la propriété opacity de l'élément <body> à 1 pour révéler le contenu du site Web une fois le CSS parsé.

Ainsi :

  • Si JavaScript est activé, la feuille de style mobile-js.css est déclarée dans le <head>, récupérée puis appliquée.
  • Si JavaScript est désactivé, la feuille de style mobile-nojs.css est récupérée puis appliquée.
  • Dans les deux cas, seule une feuille de style adaptée à l'usage est téléchargée.

Est-ce que ça vaut vraiment le coup de faire ça ?

J'ai déjà livré quelques éléments de réponses. Dans l'optique d'un développement JavaScript first tel que présenté ici - et plutôt que de me répéter - voici une liste non exhaustive des "pour" et des "contre" personnellement mesurés.

Pour :

  • Seules les ressources exploitées sont téléchargées par le navigateur Web (pas de changement de feuille de style en cours de route).
  • Le code source du projet est plus intelligible, car son comportement n'est pas fondamentalement modifié une fois lancé, juste conforté.
  • Les sélecteurs CSS sont plus efficients du fait qu'il n'y a rien à verrouiller dans l'hypothèse d'une reconfiguration de la page.
  • Les feuilles de style sont plus légères puisqu'il n'y a rien à déconstruire.

Et des "contre" :

  • Il est nécessaire d'avoir autant de feuilles de style que d'usage, ce qui peut être une contrainte en matière de maintenabilité.

Ayant eu moins de mal à mettre en oeuvre cette méthode qu'à la définir, je suis plutôt confiant quant à son utilité. Au-delà de ses vertus écoresponsables, elle permet d'affiner plus justement notre réponse à un besoin donné tout en déculpabilisant l'approche JavaScript first - sous réserve de prévoir un fallback, bien sûr ! Bien appliquée, j'ai dans l'idée qu'elle peut contribuer à rendre bien meilleure l'Expérience Utilisateur (UX) de projets gourmands.