Polices en CSS

Alexandre Niveau
GREYC — Université de Caen
durée: ~35 minutes ?
TODO: update lien Dvorak + image 

Polices sur les pages web

  • Propriété CSS pour changer la police : font-family: Arial
  • Le navigateur cherche une police installée sur le système qui porte le même nom
  • Problème : tous les systèmes n'ont pas les mêmes polices installées…
  • Si on ne mettait qu'une seule police, on ne pourrait vraiment utiliser que celles qui sont présentes « partout » (Arial, Georgia, Times, Trebuchet, Verdana, Comic Sans…)

Font stack

  • Heureusement, font-family permet de spécifier plusieurs polices
    p {
      font-family: "Ma Police", Arial, sans-serif;
    }
  • Le navigateur essaie toutes les polices dans l'ordre, et s'arrête à la première qui convient (on parle de font stack, «pile de polices»)
  • La dernière option doit être une des cinq polices génériques (fallback fonts) :
    • serif (avec empattements)
    • sans-serif (sans empattements)
    • monospace (chaque caractère a la même largeur)
    • cursive (écriture manuscrite)
    • fantasy (décorative, notamment pour les titres)
    (article sur les types de police)

Webfonts

  • Grâce à la font stack, on peut préciser la police que l'on veut vraiment, ainsi qu'une série d'alternatives, pour couvrir le maximum de systèmes
  • C'est déjà pas mal… mais notre page n'aura pas son « véritable aspect » partout, et il faut faire attention à choisir des alternatives qui se ressemblent
  • Jusqu'au début des années 2010, on n'utilisait donc en pratique que les polices présentes « partout » (web-safe fonts)
  • À présent, il est possible d'utiliser des centaines de polices
  • Principe : les polices utilisées sur la page sont téléchargées en même temps que les autres éléments de la page

Déclaration d'une police

  • Supposons qu'on a un fichier contenant une police, fichier-police.woff (voir plus loin pour les formats de fichiers de police)
  • Pour pouvoir utiliser la police correspondante dans le CSS, il faut lui choisir un nom, par exemple Ma police
  • on doit déclarer (au début de la feuille de style) que la police Ma police est définie dans le fichier fichier-police.woff
  • Cette déclaration se fait avec la règle spéciale @font-face :
  • @font-face {
       font-family: "Ma police";
       src: url("fichier-police.woff");
    }
  • Dans la déclaration,
    • font-family indique le nom que vous donnez à la police (c'est vous qui décidez !) Remarque : les guillemets ne sont pas nécessaires si le nom ne contient pas d'espaces ou autres caractères spéciaux
    • src indique le chemin vers le fichier de police
  • NB : la règle spéciale @font-face ne sert que pour la déclaration des polices : la police de la page ne change pas !

Utilisation d'une police déclarée

  • Après que la police a été déclarée avec @font-face, vous pouvez utiliser le nom choisi dans vos règles CSS, à la place des noms de polices existantes.
    p {
      font-family: "Ma police", Arial, sans-serif;
    }
  • À part la déclaration, il n'y a aucune différence entre les polices standard et celles que vous avez déclarées vous-mêmes.
  • Attention, il faut quand même préciser des fallbacks : on ne sait jamais ce qui peut se passer (problèmes de téléchargement, utilisation de webfonts désactivée…)

Les formats de police

  • @font-face est standard depuis 1998 !
  • Il n'était pas utilisé car les navigateurs ne se sont mis d'accord sur un format de fichier qu'en 2009
  • Les différents formats :
    • EOT (embedded open type) : utilisé seulement par IE
    • TTF et OTF (true type font et open type font) : formats courants hors du web, mais n'étaient pas bien supportés par IE
    • SVG (scalable vector graphic) : format d'image vectorielle standard du W3C, ne marchait pas avec IE et Firefox… mais le seul qui marchait avec iOS < 4
    • WOFF (web open font format) : le format ouvert et standard validé par tous les navigateurs
    • WOFF2 : meilleure compression que WOFF, quasiment supporté partout

La déclaration multi-compatible

  • Pour être sûr que la police fonctionne avec un maximum de navigateurs (modernes et récents, bureau et mobile…), il faut « servir » la police dans un maximum de formats
  • La directive @font-face permet de spécifier plusieurs sources
  • Une syntaxe qui couvre la plupart des cas courants (source) :
    @font-face {
      font-family: "Ma police";
      src: url("myfont.woff2") format("woff2"),
           url("myfont.woff") format("woff"),
           url("myfont.ttf") format("truetype");
    }
    
    mais au vu du support actuel, n'utiliser que woff (et woff2, pour les plus modernes) est parfaitement acceptable (graceful degradation : le site sera moins beau sur les navigateurs non supportés, mais c'est un moindre mal).
le format n'est pas nécessaire, mais si on ne le met pas le navigateur est obligé de télécharger le fichier pour vérifier son format, ce qui est ballot s'il ne sait pas le lire.

Police déjà installée localement

  • Si la police a des chances d'être déjà installée sur certaines machines (police système Windows, MacOSX, Linux…), il est dommage de la faire télécharger à tout le monde
  • On peut utiliser la fonction local :
    @font-face {
      font-family: "Ubuntu";
      src: local("Ubuntu"),
           url("ubuntu.woff") format("woff");
    }
    
    Le navigateur commence par regarder s'il existe une police installée correspondant au nom donné, et regarde les sources suivantes seulement si ce n'est pas le cas.
  • Problème de local : la police installée sous ce nom a peu de chances d'avoir exactement les mêmes caractéristiques

En pratique…

  • Le site FontSquirrel propose un générateur de webfont : on lui fournit un fichier TTF ou OTF, et il construit les fichiers dans les autres formats et génère même le CSS
  • Il propose également une grande sélection de polices utilisables gratuitement sur le web
  • Une autre ressource très utilisée : Google Fonts — ils fournissent un fichier CSS qui charge les polices choisies directement depuis leur serveur
    • Avantage : votre serveur travaille moins (+ de bande passante disponible)
    • Inconvénients :
      • vous êtes dépendants de Google, qui peut décider à tout moment de retirer une police ou de modifier son service
      • Google peut observer les déplacements des internautes sur votre site

Plusieurs styles pour une même police

  • Une bonne police pour le corps du texte doit exister en plusieurs styles, comme le gras ou l'italique
  • Il ne suffit pas de grossir le trait ou d'incliner les lettres !
  • Le CSS généré par FontSquirrel donne un nom différent à chaque style
  • C'est ennuyeux, car le navigateur ne saura pas que MaPoliceItalique est la version italique de MaPolice
  • Il faut lier les différents styles de police

Lier les styles

  • Pour cela, il suffit de donner le même nom (font-family) à tous les styles d'une même police, tout en précisant leur style et/ou leur graisse
    @font-face {
        font-family: 'DroidSerif';
        src: url('DroidSerif-Regular-webfont.ttf') format('truetype');
        font-weight: normal;
        font-style: normal;
    }
    @font-face {
        font-family: 'DroidSerif';
        src: url('DroidSerif-Italic-webfont.ttf') format('truetype');
        font-weight: normal;
        font-style: italic;
    }
    @font-face {
        font-family: 'DroidSerif';
        src: url('DroidSerif-Bold-webfont.ttf') format('truetype');
        font-weight: bold;
        font-style: normal;
    }
    @font-face {
        font-family: 'DroidSerif';
        src: url('DroidSerif-BoldItalic-webfont.ttf') format('truetype');
        font-weight: bold;
        font-style: italic;
    }
  • Ces instructions ne modifient pas la police ! Elles servent à expliquer au navigateur de quelles types de police il s'agit.

Problèmes des polices

  • Il y a quelques années, pendant le téléchargement de la police, le texte était affiché avec la police de fallback
  • FOUT, flash of unstyled text
  • Les designers n'aimaient pas les FOUT et cherchaient des techniques pour les éviter
  • En réaction à ça les principaux navigateurs ont changé de stratégie : ils n'affichent pas du tout le texte tant que la police n'est pas chargée, ou que trois secondes se sont écoulées
  • les FOUT sont remplacés par des FOIT, flash of invisible text
  • Est-ce une bonne solution à votre avis ?
Démo FOIT/FOUT

Solution au problème ?

Captures d'écrans d'une page sur Antonín Dvořák utilisant des polices incomplètes
Captures d'écran de la page du site de France Musique sur Antonín Dvořák, qui utilise des polices incomplètes (cliquer sur l'image pour agrandir)
  • Il y a des solutions pour contourner le choix des navigateurs, mais pour l'instant elles nécessitent JavaScript… (une propriété CSS font-display est à l'étude)
  • En tout cas, pour réduire le temps de téléchargement, il faut faire très attention au poids de ses polices
  • Une technique pour réduire le poids : enlever tous les caractères a priori inutiles
  • Attention aux conséquences : quels caractères sont-ils vraiment inutiles ? (voir figure)
  • La meilleure solution est d'abord de ne pas abuser des polices !
  • Une police (avec ses variantes de style) pour le texte et une pour le titrage (souvent uniquement dans un seul style) suffisent largement dans la plupart des cas.