David Madore's WebLog: Je hais le CSS

Index of all entries / Index de toutes les entréesXML (RSS 1.0) • Recent comments / Commentaires récents

Entry #2322 [older|newer] / Entrée #2322 [précédente|suivante]:

(dimanche)

Je hais le CSS

Pour ceux qui ne connaissent pas le jargon des technologies du Web, CSS est le langage de « feuilles de style » définissant l'apparence des pages HTML, c'est-à-dire la manière dont la structure — censément sémantique — des éléments de la page va s'afficher graphiquement, c'est-à-dire, quelles en seront les couleurs, les polices, les tailles, les emplacements, et les autres effets. Si on veut se faire une idée d'à quoi un site ressemble sans CSS, on peut, dans Firefox, sélectionner dans les menus View → Page Style → No Style, et on aura la version HTML brute — j'imagine que les autres navigateurs permettent quelque chose de semblable. En principe, d'ailleurs, CSS ne concerne pas que les affichages mais aussi, par exemple, le rendu sur les synthétiseurs vocaux, et permet de dire quand tel élément est rendu par un synthétiseur vocal, il doit être prononcé avec une voix féminine, mais je ne sais pas si c'est purement théorique ou s'il y a vraiment des situations où ça marche, alors qu'au moins, pour l'affichage graphique, ça marchouille.

Ce langage est donc devenu quelque chose d'incontournable pour un site Web (si on veut faire le moindre changement par rapport à l'affichage totalement basique du HTML). Et le problème, c'est que ce langage est profondément merdique.

Je ne parle même pas des choses que CSS ne permet pas de faire : on ne peut pas, par exemple, choisir un peu finement la manière dont les lignes seront coupées (par exemple demander l'algorithme de Knuth-Plass de 1981 — on ne peut pas dire que ce soit une technologie ultra-récente ; bon, il est vrai que des gens l'ont implémenté en JavaScript) ; on ne peut même pas faire quelque chose d'aussi idiot que de flotter une image sur le côté en fixant la position verticale de l'image par rapport à son bord inférieur ; on ne peut pas vraiment mettre en page un texte en vers où on reprend une ligne interrompue à l'emplacement horizontale où la ligne précédente s'était finie (bon, peut-être que maintenant on peut, ça fait longtemps que j'avais voulu faire ça et que j'avais dû abandonner) ; on ne peut pas ajuster la taille d'une <iframe> automatiquement à son contenu ; on ne peut pas demander à une classe d'hériter une propriété d'autre chose que son parent immédiat (par exemple si j'ai une classe texte-vert et que je veux une classe que j'utiliserai dans celle-ci qui reprend la couleur normale extérieure à texte-vert sans avoir à faire d'hypothèse sur ce qu'est cette couleur). La liste est infiniment plus longue, mais je dis juste ce qui me passe par la tête. Pour chacune de ces choses, il y a des façons atrocement sales de contourner le problème avec du JavaScript dégueulasse qui va casser tout le temps et poser plein de problèmes pour plein de gens, donc on est tenté de faire semblant qu'il n'y a pas de problème.

Mais même pour des choses que CSS permet de faire, ce langage est atroce : on est devant un bricolage de propriétés dont on comprend mal l'interaction, et dont les règles précises sont extrêmement complexes (rien que la définition du bloc contenant est à s'arracher les cheveux : en mettant un html { position: relative; } dans une feuille de style, qui logiquement ne devrait rien faire du tout, on change la signification d'un <div style="position: absolute; top: 0px; bottom: 0px; width: 100%; height: 100%"> à cause de ces règles à la complexité byzantine). Et tout est à l'avenant : à chaque fois que je me plonge dans ce truc, j'en ressors dégoûté, et bien souvent j'abandonne ce que je voulais essayer de faire.

Mais le problème qui me paraît le plus insoluble, c'est celui du réglage des tailles. Je veux dire : la taille des polices texte, la longueur des lignes (relativement à cette taille et/ou relativement à la taille de l'écran), et les choses de ce genre comme la taille des images. Le problème est devenu d'autant plus aigu en cette dernière décennie que les navigateurs mobiles sont partout, donnant naissance à une profusion de combinaisons entre largeurs d'écran et résolutions.

La raison pour laquelle le problème est insoluble, c'est que c'est avant tout une question de préférence utilisateur : ce n'est pas à moi de décider la taille de caractères avec laquelle afficher mon site Web, ou la largeur des lignes — moi, ce que je veux pouvoir décider, c'est si une image est flottée à gauche ou à droite ou centrée, si tel texte doit s'afficher dans une couleur différente, etc. (et de fait, ça, CSS le permet relativement bien).

Fondamentalement, la difficulté est que CSS est prévu pour les cas où on contrôle tous les paramètres (i.e., la feuille de style spécifie tout : taille des polices, taille des lignes, etc.), dès qu'on commence à laisser des choses non-spécifiées (parce qu'on ne veut pas préjuger de ce que l'internaute lecteur préfère), le langage est foncièrement inadapté.

Concernant la longueur des lignes, le problème est vraiment grave : énormément de sites Web ont des bandeaux sur les côtés (une habitude que je trouve horripilante, même si c'est un moindre mal par rapport aux bandeaux « sticky » — c'est-à-dire non défilants — collés en haut de fenêtre), du coup beaucoup d'internautes prennent l'habitude d'avoir des fenêtres très larges pour pouvoir s'accommoder de ces bandeaux sans réduire les lignes de texte utile à une largeur ridicule ; mais du coup, s'ils vont voir un site sans bandeaux latéraux, comme le mien, ils risquent de trouver les lignes trop longues et d'en être gênés ou d'être agacés de devoir changer la taille de leur fenêtre : que puis-je y faire ? inventer des bandeaux sur le côté, peut-être vierges, juste pour me conformer à cette habitude crétine d'en mettre partout ? Je ne sais pas quoi faire. Pour l'instant, mon attitude est donc de ne pas spécifier quoi que ce soit sur la longueur des lignes dans la feuille de style.

Un problème relativement semblable se pose pour la taille des caractères : personnellement, comme j'ai une mauvaise vue (mon ophtalmo prétend que j'ai 10/10 aux deux yeux après correction, mais je crois que soit il ment, soit 10/10 est vraiment un minimum et qu'on ne peut trouver qu'on ne voit bien que si on a au moins 14/10), j'ai sans arrêt envie d'augmenter la taille des polices des sites Web que je visite. (Une subtilité est que je n'ai généralement pas envie d'augmenter la taille des images : heureusement, Firefox permet, dans View → Zoom → Zoom Text Only, de choisir si le zoom augmente uniquement la taille du texte ou tout sur la page ; malheureusement, certains sites se comportent assez mal quand on zoome le texte et pas les images, et CSS est un peu responsable de ce désastre.) Je ne peux pas vraiment en vouloir aux sites Web que je visite de ne pas avoir prévu une taille plus grosse, parce que j'imagine que beaucoup d'internautes préfèrent plus petit que ce que je mets, mais le problème est quand même que rien n'a été prévu pour tenir compte de ces différences de goût. Question accessibilité aux malvoyants, c'est nul.

Et sur un navigateur mobile, c'est encore pire : il n'y a généralement pas vraiment moyen de changer la taille du texte. On peut certes zoomer, mais le zoom se fait en gardant un rapport constant taille de ligne sur taille des caractères (contrairement à ce qui se passe quand on zoome dans un navigateur sur ordinateur fixe), du coup on ne voit plus des lignes complètes et c'est essentiellement impossible de lire un site comme ça. (Il y a là un vrai défi pour les concepteurs des interfaces utilisateur des navigateurs : il y a trois types de zoom différents — le zoom du texte seul, le zoom du texte plus image mais pas de la largeur totale de la page, et le zoom de tout, et il faudrait fournir un moyen intuitif de faire tout ça séparément, alors même que les utilisateurs n'arriveront souvent pas à comprendre la différence.) J'arrive donc à la situation absurde que je n'arrive pas à lire mon propre site sur mon propre téléphone mobile, parce que les caractères sont trop petits, et je ne sais pas vraiment régler le programme.

Un navigateur mobile fonctionne en faisant semblant qu'il a une résolution généralement plus grande que ce qu'il a : par exemple, il peut rendre la page à une résolution de 900 pixels de large (i.e., comme un navigateur sur ordinateur fixe le ferait avec une fenêtre d'une telle largeur) et ensuite appliquer le niveau de zoom qui fait tenir cette largeur dans la largeur du téléphone ou de la tablette. Ce nombre de 900 (dans mon exemple) est tiré de l'élément <meta name="viewport"> que l'auteur de la page Web peut choisir d'utiliser. Ce même élément permet aussi de demander de rendre à la taille naturelle (i.e., la vraie résolution) de l'appareil mobile. Malheureusement, le mécanisme est complètement con (le fait qu'il ait été inventé par Apple n'y est sans doute pas étranger) : on peut spécifier soit un nombre exact, du genre 900, soit le nombre naturel (qu'on ne contrôle pas du tout), mais on ne peut pas spécifier un multiple du nombre naturel ; par exemple, on ne peut pas demander à afficher la page sur une largeur qui serait égale à 1.5 fois le vrai nombre de pixels de la largeur du mobile (on peut spécifier un niveau de zoom, mais ce n'est pas du tout pareil, parce que ça ne change pas la largeur sur laquelle la page sera rendue). Or spécifier un nombre exact est généralement très con : ça veut dire avoir le même rendu sur tous les mobiles et toutes les tablettes quelle que soit leur taille (et l'orientation dans laquelle on les tient). Mais demander le vrai nombre de pixels est aussi problématique : si un site Web s'affiche sur un écran de téléphone de 320 pixels de large sans aucun dézoom, il va vraiment falloir changer la feuille de style, et c'est là que CSS repointe le bout de son nez hideux. De mon point de vue, afficher mon site Web sur une largeur égale à 1.5 fois la résolution du mobile serait à peu près l'idéal, mais non, ce n'est pas possible.

CSS devrait permettre de faire des choses intelligentes si le nombre de pixels de large est trop petit, par exemple, diminuer la taille des polices : il y a toutes sortes de mécanismes pour faire des tests sur la résolution ou d'autres attributs de l'affichage. Mais ensuite, on ne peut pas vraiment en faire quoi que ce soit d'utile. Changer la taille des polices, ça va. Mais changer la taille des images ? Pour autant que je sache, ce n'est pas possible, si une image est déclarée <img width="666" height="444"> dans le HTML (et on est bien obligé de déclarer largeur et hauteur si on veut que le navigateur laisse le bon espace tant que l'image n'est pas encore chargée), de faire du CSS pour qu'elle s'affiche, disons, à 50% ou 75% de sa taille déclarée — voilà vraiment une limitation idiote. (On pourrait peut-être s'en sortir en utilisant des variables CSS, ou la fonction attr, mais rien de tout ça n'est supporté par un nombre non-négligeable, voire non-nul, de navigateurs. On peut aussi sans doute s'en sortir avec du JavaScript immonde, mais ça voudra dire que la page sera modifiée avant affichage et donc probablement mal affichée dans plein de situations.)

Bref, j'ai fait ce que j'ai pu en ajoutant à mes pages une balise <meta content="width=device-width, initial-scale=1" name="viewport" /> (pour afficher à taille naturelle sur mobile), et à ma feuille de style les règles ad hoc suivantes (pour diminuer la taille du texte et certaines marges quand la largeur est très petite)

@media (max-width: 640px) {
  body { font-size: 12px; }
  .weblog-entry { padding: .5em; }
  .pic { margin-right: .5em; margin-bottom: .5em; }
  .pic-right { margin-left: .5em; margin-bottom: .5em; }
  .pic-embed { margin-right: .5em; margin-bottom: .5em; margin-top: .5em; }
  .pic-embed-right { margin-left: .5em; margin-bottom: .5em; margin-top: .5em; }
}
@media (min-width: 641px) and (max-width: 780px) {
  body { font-size: 14px; }
}
@media (min-width: 781px) {
  body { font-size: 16px; }
}

— mais peut-être que j'ai empiré les choses plus qu'autre chose. Si des gens ont des idées sur comment contourner les limitations insupportables du CSS, surtout, faites-moi part de vos idées.

Ajout : J'oubliais d'ajouter une précision à propos du redimensionnement des images (voir aussi ce lien, dont aucune des réponses ne convient vraiment) : on peut presque le faire en utilisant les transformations CSS, spécifiquement, en écrivant img { transform: scale(0.5,0.5); } sauf que… l'espace occupé par l'image reste quand même identique (bon, je comprends qu'il y a une difficulté à calculer la bounding box si on autorise n'importe quelle transformation, mais quand même, ils auraient pu prévoir une variante de scale pour laquelle la boîte est transformée aussi !).

↑Entry #2322 [older|newer] / ↑Entrée #2322 [précédente|suivante]

Recent entries / Entrées récentesIndex of all entries / Index de toutes les entrées