27 mars 2020

Médialab (2/3): No fonts, no images, no javascript

Ce billet fait partie d’une suite de billet sur le projet de refonte du site web du médialab de Sciences Po.

  • Le premier billet « Une décroissance heureuse » est une introduction au projet.
  • Le deuxième billet « no fonts, no images, no javascript » montre comment ces trois points ont été mis en application.
  • Le dernier billet « Exemples de pur CSS » se concentre sur des exemples de mises en applications de principes graphiques et interactifs en pur CSS.

No fonts ?

Pour la refonte du site du médialab, notre premier choix est de ne pas embarquer de fontes et de simplement utiliser les polices systèmes sur le site web.

font-family: sans-serif; sera donc notre seul appel de fontes.

La police sans-serif par défaut étant différent d’un système d’exploitation à l’autre et d’un navigateur à l’autre, nous prenons du temps à passer de l’un à l’autre pour vérifier que tout reste lisible.

Chrome 77.0 sous macOS High Sierra
Firefox 68.0.1 sous Linux Mint 19.2 Tina

Nous avons dû aussi prévoir des espaces plus lâche que nous le ferions habituellement pour être sûr que le texte entrerait toujours quelle que soit la police et le nombre de lignes. De plus, le contenu étant très hétérogène, notre système devait prendre en compte des textes variants sur plusieurs lignes pour un même type de contenu.

Pour rester harmonieux, nous avons utilisé pour les line-height, margin-top et padding-top uniquement des multiples d’une même valeur (nommée baseline dans notre cas) grâce aux variables et aux calculs CSS. Par exemple, pour les titres dans les listes, voici le CSS:

h1 {
    line-height: calc(var(--baseline) * 3);
    padding-top: calc(var(--baseline) * 1);
    padding-bottom: calc(var(--baseline) * 1.5);
}

Nous nous en sommes tenus là mais il faut savoir que le line-height est aussi calculé différemment d’un navigateur à l’autre. (Ce ne sont pas les mêmes valeurs qui sont utilisées dans le fichier fonte, lire cet article de Vincent De Oliveira très complet à ce propos). Nous n’avons donc pas pu aligner les choses aussi précisément que nous le souhaitions mais les rapports restent justes grâce à l’utilisation des variables.

Sur cette image, les textes ne sont pas parfaitement alignés d’une colonnes à l’autre

No images ?

Nous avons passé beaucoup de temps avec l’équipe du médialab à nous questionner sur la présence des images illustratives et leur traitement. Après plusieurs pistes, nous décidons d’en faire un élément fort de l’identité graphique low-tech.

Pour cela, nous nous inspirons de l’ASCII art où des images sont créées à partir de caractères typographiques. L’idée est de remplacer les images par des suites de caractères. Non seulement cela permet d’unifier des images très disparates à travers une homogénéité graphique mais, en plus, une suite de caractère est en principe plus légère qu’une image. Ce principe répond en plusieurs points au motto d’une frugalité graphique et est devenu un principe iconique du site web.

Au fil de nos recherches, nous trouvons un script de Ryan Mattox, ASCII Converter Full charset. Nous nous intéressons aussi aux Box-drawing characters, des caractères semi-graphiques utilisés dans les interfaces textuelles pour structurer l’information ou simplement créer du relief sur des machines 8bits. Unicode comprend un jeu de symboles géométrique sous forme de pavé rectangulaires plus ou moins extrudés pouvant être utilisés avec des polices de caractère de chasse fixe. Nous en choisissons trois particulièrement:

En partant de cette base et à l’aide de Guillaume Plique (médialab), nous modifions le script de Ryan Mattox pour créer notre propre générateur d’images en ASCII. En sortie, nous obtenons une suite de balises <pre>. Cet élément HTML permet de garder le formatage du texte et donc les espaces entre les caractères.

Chaque ligne de l’image est donc une balise <pre> contenant un certain nombre de caractères fixes (espaces compris). Pour nous laisser plus de liberté sur le site, nous définissons trois tailles d’images à utiliser selon la largeur que l’image prend dans l’écran: l’image small sera de 60 caractères de large (60 caractères pour chaque balise <pre>), la medium de 120 et la large de 240. Du côté du backend, une petite interface est prévue pour pouvoir recadrer les images originelles et visualiser le résultat. Nous ajoutons un seul paramètre (gamma) permettant de jouer sur les contrastes de l’image.

Continuant sur notre principe de « no font », nous stylisons simplement ces balises <pre> avec la propriété suivante:

pre {
	font-family: monospace;
	line-height: 0.1;
}

Après quelques essais d’intégration, nous nous apercevons que les interprétations sont diverses d’un navigateur à l’autre. Nous repérons particulièrement un problème sur Chrome où l’interprétation d’un des caractères semble parfois sauter.

Sur l’image ci-dessous, on voit bien la différence entre l’interprétation de Chrome 78.0 pour OSX (à gauche) et celle de Firefox 70.0 pour OSX (à droite) :

Vous pouvez-vous même tester l’affichage avec ce codepen. La différence est encore plus évidente si l’on zoom, on voit bien l’un des caractères qui est parfois mal interprété:

Pour résoudre ce problème, notre solution a été de faire une exception à notre règle « no font » (embarquer aucune fonte sur le site). Nous avons donc redessiné les trois caractères que nous utilisons dans un fichier de police spécifique. Ce fichier ne contient que ces glyphes (qui étaient au nombre de quatre au départ), son poids restant un enjeu (5ko).

Nous nous heurterons aussi à quelques problèmes de line-height, que nous réussissons à fixer grâce à une série de calculs CSS complexes (utilisant la propriété calc).

Enfin, nous décidons d’utiliser la couleur rouge – charismatique chromie du médialab – sur toutes les images du site.

Pour les mise en forme des pages, nous avons souhaité appuyer le côté illustratif des images et la force qu’elles peuvent avoir en tant que simple élément graphique. Pour cela, les images sont cachées sur la plupart des pages et ne se dévoilent qu’au survolement de la souris. Nous jouons aussi avec les contre-formes des glyphes pour mêler texte et image et donner une forte identité au site.

Seules les images d’illustrations des articles ont été remplacées par du texte. Pour les photos des membres de l’équipe, le seul traitement qui semblait acceptable était un classique noir et blanc, respectant la liberté de chacun de se figurer en public comme il le souhaite. Dans les articles, les figures indispensables à la compréhension sont laissées sans traitement graphique.

Il est à noter que la transformation des images en suite de glyphes rend certes le site plus léger en termes de poids, mais pas nécessairement en terme d’affichage. Nous avons ajouté beaucoup d’éléments au DOM en utilisant plusieurs balises <pre> (à la place d’une seule balise <img>). Or, les navigateurs doivent interpréter chaque élément du DOM: plus il y a d’éléments et plus ceux-ci ont des styles associés, plus le temps d’affichage sera long et prendra de la bande passante. Pour ce projet, il nous paraissait évident que les illustrations en grand format chargent beaucoup plus rapidement en format texte que si elles avaient été des formats image, nous n’avons donc pas creusé cette question. C’est cependant une chose intéressante à pointer, qui mériterait plus d’analyse sur d’autres projets.

D’autre part, la substitution de l’image par le texte empêche une utilisation aisée du lazyload. Notre choix répond à un contexte et au pari du « No JavaScript » (voir point suivant); or JavaScript est aujourd’hui le seul moyen viable pour bénéficier du chargement paresseux. Nul doute que l’implémentation prochaine de ce dernier au sein des fonctionnalités natives des navigateurs tendra à modifier les termes de l’équation.

No javascript ?

Depuis quelques années, CSS contient de plus en plus de propriétés rendant obsolète JavaScript pour certaines interactions et animations. Ces propriétés sont directement implémentées dans les navigateurs et sont donc plus rapides en termes de calcul (il y a moins de latence pour les utilisateurs). De plus, l’utilisation massive de JavaScript et de librairies qui y sont attachées (comme jQuery) a mauvaise presse en termes de dépendance et d’accessibilité. Il suffit qu’un lien casse ou qu’un script soit mal écrit pour que l’utilisateur ne puisse plus utiliser et lire un site.

C’est avec toutes ces réflexions en tête que nous avons décidé de nous passer de JavaScript sur l’ensemble du site. Pas question cependant de se passer de certaines interactions bien utiles (sliders, tri de liste, etc.) Nous avons donc utilisé autant que possible HTML et CSS pour construire ces fonctionnalités.

Nous le disons d’emblée: ce choix nous a parfois mis en difficulté dans son application. Il nous a fallu faire preuve d’inventivité et déployer un certain nombre d’astuces, parfois en utilisant certains éléments HTML à la limite du contre-emploi. Autre défaut, ce choix a engagé une feuille de style minifié de 308ko (poids tout de même moindre que si nous avions utilisé certaines bibliothèques JavaScript). Dernier aveu, quelques lignes de JavaScript ont finalement été indispensables à un endroit de la version mobile du site. Indice: à cet endroit, une même action de l’utilisateur nécessite deux réactions, chose impossible en pur CSS.

Malgré tout cela, nous n’avons jamais autant appris de CSS que par cet exercice. Cela nous sera assurément utile dans bien d’autres projets et nous en profitons donc pour partager nos trouvailles à une plus grande communauté.

Nous ne pourrons pas revenir sur tout notre code CSS, il nous faudrait encore bien une dizaine de billets. Concentrons-nous plutôt sur quelques fonctionnalités du site et voyons comment nous les avons gérées entièrement en CSS. Rendez-vous donc au prochain billet pour quelques lignes de code.

Billet écrit à quatre mains par Julie et Benjamin