J’ai souvent eu l’occasion à travers mes divers projets Web mobile (responsive), d’avoir à réduire la taille des polices de titre car même un simple mot ne passait pas en largeur. Pour éviter d’avoir une césure sur chaque mot du titre, le plus simple était de s’autoriser une réduction approximative du corps. (approximative… façon de parler). Je vous propose des solutions relative.
CSS3 à la rescousse
Il existe une unité encore peu connue car prise en charge par nos navigateurs depuis peu de temps, il s’agit des unités relative au viewport. Pour comprendre ce qu’est le viewport, je vous invite à lire cette article de Raphaël Goetter : Comprendre le viewport dans le Web mobile.
Pour résumer, nous allons proposer un corps de texte qui dépend de la largeur de la fenêtre du navigateur.
Vous connaissez certainement les unités px
, em
, rem
ou pt
pour dimensionner vos corps de texte ? Rajoutez à cette liste :
vw
: « Viewport Width », correspond à l’unité relative à la largeur de votre écranvh
: « Viewport Height », correspond à l’unité relative à la hauteur de votre écranvmin
(vm
pour IE9) : « Viewport Min », correspond à l’unité relative à la plus petite des deux dimensions (largeur ou hauteur selon l’orientation)vmax
: « Viewport Max », correspond à l’unité relative à la plus grande des deux dimensions (largeur ou hauteur selon l’orientation)
Très bien, mais que représente une unité de vw
, par exemple ?
C’est assez simple mais pas forcément intuitif de prime abord : 1 unité représente 1% de la dimension de référence.
Prenons un exemple plus parlant.
Si j’écris ce morceau de code CSS appliqué à mon titre de niveau 1 :
h1 {
font-size: 10vw;
}
Mon corps de texte aura un équivalent de 10% de la largeur de mon viewport, à savoir la largeur de la fenêtre de votre navigateur.
Sur l’écran que j’utilise actuellement, la définition est de 1920px de large, mon titre de niveau 1 aura alors une font-size
équivalente à 192px
.
Bien que la spécification du W3C sur ces unités prévoit qu’au changement de dimensions du viewport, les dimensions des éléments bénéficiant des unités vw, vh, vmin et vmax soient mis à jour, il semblerait que Chrome n’en fasse qu’à sa tête (Safari également probablement, mais je n’ai pas la version 6 sur PC 😉 )
Il vous faudra donc recharger la page sur la page de démonstration à chaque redimensionnement de la fenêtre du navigateur.
Voir la démonstration
J’ai ajouté un petit script JavaScript pour auto rafraichir le calcul, basé sur l’évènement « resize » de la fenêtre.
Pour les curieux, le voici, il est basé sur jQuery.
<script>
$(window).resize(function() {
$('h1, h2').css('z-index', 'auto'); //auto reflow
});
</script>
Le support est encore partiel, mais ces unités sont utilisables pour bientôt, et déjà pour la cible iPhone, Chrome 20+, Firefox 19+, Opera 15.0+ et IE10+.
Voir le support sur CanIuse
Pour les curieux, voici également une petite expérimentation de respect d’un ratio 16:9 en fonction du viewport.
Solution de secours en JS
Il existe une alternative en JavaScript – comme souvent – qui se nomme FitText.js, qui est un plugin jQuery (hélas).
Cette solution fonctionne a priori partout sauf sur IE et propose de rajouter dynamiquement un attribut style sur un élément en faisant varier la taille de font-size en pixels.
- Téléchargez la ressource sur Github
- Appelez la librairie jQuery et le script Fittext depuis votre document HTML
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <script src="jquery.fittext.js"></script>
- Puis ciblez les éléments textuels que vous souhaitez contraindre
<script> $(".responsive_headline").fitText(); // basique $(".responsive_h3").fitText(1.2); // compression proportionnelle $(".responsive_headline").fitText(0.8); // décompression proportionnelle $(".responsive_headline").fitText(1.2, { minFontSize: '20px', maxFontSize: '40px' }); // compression avec taille max et taille min </script>
Voir la démonstration sur fittextjs.com
C’est probablement la meilleure alternative aujourd’hui, cependant elle ne fonctionne pas sur Internet Explorer.
Conclusion
Ces essais manquent de tests, n’hésitez pas à me faire vos retours dans les commentaires sur différents navigateurs (Safari 6 Mac, Android, etc.).
Merci à vous !
« Il existe une alternative en JavaScript – comme souvent – qui se nomme FitText.js, qui est un plugin jQuery (hélas). » Pourquoi « hélas » ?
J’allais justement me pencher sur le problème des largeur de titres, donc merci 🙂
Hello,
Oui je ne suis pas allé au bout de mon idée : jQuery sur mobile ça me semble bien lourd, surtout s’il faut le charger juste pour gérer du texte. Je pense qu’une solution JS sans framework aurait été la bienvenue.
Bon courage pour ton projet 🙂
FitText sans jquery => https://github.com/adactio/FitText.js
Merci ! 🙂
Ah oui d’accord ! Merci 🙂
Excellent. Je cherchais cette technique depuis un moment. Merci.
Quelle est la différence avec -webkit-text-size-adjust ?
Salut Julien,
-webkit-text-size-adjust
ne s’adresse qu’à webkit, plus précisément à Safari iPhone.Contrairement à l’unité
vw
et suivantes,-webkit-text-size-adjust
ne sert qu’à préciser un calcul en pourcentage d’une taille de police initiale, et non en fonction de la largeur de l’écran.Je ne sais pas si mon explication est très claire… ^^ »
Si si, je me doutais que le préfixe renvoyait à chrome et safari mais je vois mieux la différence. Merci.
Je risquerais de dire des bêtises, mais le « adjust » n’est pas compris par Chrome il me semble, c’est vraiment du iOS Safari (à moins qu’il soit compris par Chrome sur iOS).
Je ne suis pas bon en typographie, mais je me souviens d’une règle de typographie utile, qui dit qu’une ligne de texte doit faire entre 45 et 75 caractères pour être confortable à lire (généralement on retient 66).
Logiquement on pourrait mixer em et vw pour avoir du texte qui respecte toujours cette règle quelle que soit la largeur disponible : comment calculerait tu cela ?
100 / 66 = 1,5 vw ?
Hello JPVincent 🙂
Je ne pense pas qu’on puisse trouver un mode de calcul aussi simple, puisque l’unité prend comme référence la largeur de l’écran et non la largeur disponible dans son parent direct. Si tu commences à avoir du texte dans une boîte flottante, avec des marges et padding, tu vas vite te retrouver avec des calculs faussés.
Mais effectivement c’est un excellent moyen de conserver un nombre de mots par ligne confortable pour la lecture.
PS : j’espère ne pas avoir mal compris ton commentaire…
effectivement ça ne marche que sur du mono colonne, du coup tu as un design vraiment fluide, mais ça n’aide pas au responsive layout.
Ma question pouvait sembler bizarre, parce que j’en suis au stade des interrogations sur ces intégrations fluides, je n’ai pas encore vraiment mis les mains dedans
J’ai voulu tester sur mon prochain site, juste pour voir, mais il y a l’air d’avoir une incompatibilité avec le maximum scale. Voici ma règle:
Donc, jusque là, rien d’anormal (à mon avis). Par contre, avec des dimensions en rapport avec le viewport, cela annule le maximum scale.
A voir chez d’autres gens.
Salut,
Bizarrement le code a sauté…
Sur quel terminal/installation as-tu testé ?
Avec quelle solution ? (CSS ou JS)
Pourquoi un maximum-scale ?
Quelle est ta cible ?
J’ai testé sur mon iPhone 4S (pas encore sur mon iPad 2), le tout en comme tu l’as indiquer.
J’ai mis un maximum scale, car le design est responsive et que la typo se veut clair et agréable à lire. Voila pourquoi j’ai mis un maximum scale, afin que l’utilisateur n’est pas à zoomer, car tout s’affiche en grand pour le confort de l’oeil.
Bonsoir,
Le problème du minimum et maximum-scale, c’est qu’en les utilisant tu prétends connaître le confort de lecture de tous tes visiteurs. Or c’est impossible. Peut-être que l’utilisateur aura besoin de zoomer au delà de la limite que tu lui imposes…
Le problème survient en utilisant la technique CSS ou JS ? Ne pas oublier que pour le moment le corps ne s’adapte pas automatiquement au zoom et dezoom à cause d’un bug webkit. Il faut utiliser le petit hack de reflow en JS pour que ça fonctionne.
Salut,
désolé de pas t’avoir répondu avant. En ce qui concerne le maximum scale, il s’agit d’une webapp, donc pas besoin de zoom normalement ^^.
Sinon, il s’agit de la solution css.
Hello,
Je n’ai pas pu reproduire le bogue de mon côté :/ Navré.
Pour revenir sur cette histoire de maximum scale, un mec qui a 3 sur 10 à chaque œil ne pourra pas lire le contenu de ta web app sur un corps de texte équivalent à 18px car il ne peut pas zoomer (les chiffres ne sont peut-être pas réalistes).
S’il te contacte (s’il y arrive) pour ce problème tu vas lui répondre quoi ? Qu’il « n’a pas besoin de zoom normalement » ?
L’accessibilité n’est pas une option. Si tu portes des lunettes qui te permettent une bonne correction, et qu’un jour tu les casses, tu verras à quel point l’accessibilité numérique peut t’être utile 😉
Bonne journée.
T’as tout à fait raison, mais comme il s’agissait d’une webapp, on peut constater que les apps ne zoom pas.
Sinon, c’est pas grave pour ce bug, le maximum scale n’est pas une bonne pratique ^^.
Salut salut 🙂
Merci pour l’article.
J’ai voulu tenter un truc fou :
-webkit-transform: perspective(156vw);
Et bien raté, le 156vw est interprété comme 156px -_-‘ Dommage 😉
A+
Salut 🙂
Ah oui tu as tenté un truc de fou en effet 😀
L’unité ne s’applique pas à toutes les propriétés oui. J’ai pas vu ce que disais le w3c à ce propos.
salut Geoffrey
tout d’abord je te souhaite une très bonne année et pleins de bonheur.
je me permets de te demander sur ce sujet quelle option tu adopte sur tes sites ? car ton tuto est super complet, mais il ne laisse pas apparaitre ta préférence !
bonne journée 🙂
Hello,
Merci et bonne année également 🙂
En fait tout dépend du support souhaité par le client.
En général je préfère les solutions sans JS, je fais donc en sorte d’avoir un texte « qui rentre » de base, puis j’améliore la lisibilité avec la technique CSS (si elle est comprise par le terminal du visiteur, bien sûr).
Tout est une histoire de compromis, comme toujours 🙂
Je confirme que ça marche parfaitement sur Firefox 19.
Par contre, je ne considère pas que ton exemple est un équivalent de FitText.
Ton « font-size: 12vw; » appliqué au h1 ne fonctionne que pour « CreativeJuiz », notamment parce qu’il y a deux « i » fins dedans. Avec des lettres plus larges (essaie d’en mettre autant mais que des « M » par exemple), ça ne tiendra pas dans la largeur disponible. Il faudra réduire la valeur. Ce n’est donc pas généralisable.
Le problème est toujours le même, il faudrait pouvoir définir la largeur d’une phrase, avec une instruction similaire à background-size « contain » ou « cover » :
p.fittext {
word-wrap: none;
text-size: contain;
}
Bonjour Nicolas,
Merci pour l’info du support de Firefox 19.
Je ne comprends pas bien ton intervention.
Bien sûr que la taille choisie ne fonctionne que pour le texte choisi, tout comme un design de 960px de large ne fonctionnera que pour cette largeur et sera repensé pour des tailles supérieures ou inférieures.
Cette technique n’a pas pour but de contraindre un texte à s’afficher sur une ligne quel que soit le nombre de caractères, c’est impensable, je n’imagine même pas les dégâts sur la lisibilité en production sur un CMS.
Le jour où tu penseras avoir résolu ton « problème » tu en amèneras un nouveau : celui de la lisibilité.
Bonne journée 🙂
Oups, coquille, c’est ceci qu’il faudrait écrire :
p.fittext {
white-space: nowrap;
text-size: contain;
}
Geoffrey, cette technique ne serait intéressante bien entendu que sur de la titraille, cela se veut juste une version standardisée et sans JS de FitText… 😉
Il y a bien WebKit qui avait tenté un « text-size-adjust », je ne sais pas ce que ça donnerait avec une valeur en vm*. En fait je n’ose ni tester ni y accorder du crédit :p
Merci pour ton intervention et proposition 🙂
Une fois de plus, text-size-adjust s’intéresse à la hauteur du texte, pas à sa largeur, donc cela ne me semble pas utilise dans le cas présent.
Ok merci pour l’info, j’ai un peu de mal avec « largeur » et « hauteur » d’un texte, pour moi c’est une « taille de corps ». Mais je comprends l’idée et ça ne concerne effectivement pas cette problématique 🙂
Moi j’ai opter pour la solution JS, car de toute façon je fait appel à jquery pour d’autres script.
Maintenant je devrais peux être supprimer tout le JS pour la version smartphone ? Je ne me rend pas trop compte. Je ne suis pas encore au point de ce côté, peux être est ce du à mon rejet malgré mon métier de webdesigner des smartphones,(que je trouve extrêmement polluant, inutile etc.. je préfère les téléphones qui ne font que téléphoner sans couleur. De plus en plus dur à trouver)
Bref je devie..
Conclusion, je suis assez satisfait de FitText. Je l’ai utilisé sur l’ensemble du site, bien qu’il recommande de ne pas le faire… Ai je eu tort ? je ne sais pas pourquoi j’imagine temps de calcul ? Mais je n’ai rien constaté d’alarmant.
Seul défault par rapport à chrome il recalcul la taille par étape et non de manière parfaitement fluide, Ce qui m’a causé parfois quelques souci.
Pour IE pas de problème constaté cela fonctionne. Sur IE7 8 9 et 10
Cordialement.
Bonjour
font-size: 12vw;
Ne marche pas avec Firefox 13.0.1, ni avec IE 8.0, les antiquités que l’administrateur des pc de ma boite nous fournit généreusement…
merci, pour ce post, ça répond à mes interrogations sur le design responsive et la police.
juste pour info, ça ne fonctionne pas sur Opera (Version 12.14)
Merci pour cette information 🙂
Bonjour,
J’aurai une question, peut-être idiote ! Est-ce que ça ne revient pas au même d’écrire « font-size: 10%; » ? Puisque 10vw = 10%.
Hello,
Non puisque le 10% du font-size prend en référence la cascade CSS, il s’agit donc de 10% de la taille de base de la font. 10vw prend en référence la largeur de la vue sur l’écran, le référent n’étant donc pas le même, on ne peut pas confondre les deux.
D’accord oui ! Merci beaucoup pour tes explications 😉 Oui effectivement ce n’est pas la même chose ! :$
Merci Geoffrey pour ce petit tuto !
Je suis actuellement en train de refaire le site de mon auto-entreprise et je voulais savoir à la base s’il était possible de définir soi-même les tailles de tous les éléments de son site par rapport à la taille du navigateur sans js.
Et après quelques tests, je confirme c’est possible grâce à ces fameuses unités liés au viewport.
Voici le résultat : http://www.honet-design.fr/test.php
C’est surtout la valeur vmin qui m’a été utile ici : les zoom n’ont aucun effet, les changements de taille du navigateur sont totalement pris en compte, c’était mon but initial 😀
Cependant, on se rend rapidement compte que l’accessibilité devient mauvaise sur les appareils ou le vh est plus grand que le vw.
Sans parler du fait que ca ne fonctionne que sous FF19.
Mais les tests était rigolo à faire ^^
Salut salut,
Merci de partager tes tests avec nous 🙂
Effectivement le test est pas mal et présente bien les limites de la chose. C’est comme cela qu’on peut se rendre compte des possibilités de nos outils et langages préférés.
Bonne continuation dans ta refonte !
Merci pour cet article !
En revanche sur Chrome j’avoue que ça ne fonctionne pas chez moi.
v27 sur un win 7. J’ai essayé de chercher éventuellement une option à activer dans les flags de chrome, mais sans succès.
Ah oui d’accord, je vois ça. Ben c’est encore une régression de Chrome d’une version à l’autre j’imagine.
Aaaaaah ! Chrome, ce nouvel IE.
En tout cas c’est supporté par Firefox, et pas besoin de script pour lui (et pas de régression, juste une progression :p), il respecte la spec.
Sympa comme technique.
C’est frustrant quand on développe des web apps en mobile first, on doit attendre sans cesse le support des navigateurs et des nouvelles recommandations du W3C pour avoir un site de plus en plus responsive.
Je rêve de partir deux ans au soleil et de revenir avec un HTML5 et CSS3 « terminé ».
Bonsoir à tous j’ai un problème avec jquery.fittext, en gros quand j’applique la formule et que je visualise mon site sur firefox ça marche du feu de dieu mais dès que j’essaie de le visualiser sur chrome, je suis obligé d’actualiser la page pour que le fittext marche et j’avoue que pour l’instant je bloque, si quelqu’un à la réponse je le remercie par avance
Navré je n’avais jamais vu passer ton commentaire pourtant validé :/
As-tu essayé avec le FitText sans JS proposé par Gaetan ?
Merci.
ça fait plus d’1 an et ce n’est qu’aujourd’hui que je vois cette possibilité, à la date d’aujourd’hui je suppose que cette norme à été adopté par tous les navigateurs en tout cas c’est tout le pire que je puisse souhaiter. Ce code m’a rendu énormément service et je pouvais pas passer à coter d’un grand merci et de reconnaissance.
Hello,
Il n’est jamais trop tard 🙂
Le support est bien meilleur mais ça n’est pas encore suffisamment répandu et parfois bogué. Mais c’est à utiliser dans le sens de l’amélioration progressive.
Bonne continuation.
bonjour,
est-ce-que la situation a évolué concernant les navigateurs? car les unités relatives au viewport, c’est vraiment ce qui manquait pour les sites responsive. pour l’instant je suis dans l’expectative car je souhaiterais utiliser uniquement vw, et si je regarde sur http://caniuse.com/#search=vw vw semble supporté par tous les navigateurs récents, mais si je regarde sur cette page http://www.quirksmode.org/css/units-values/mobile.html
il semble que ce ne soit pas prêt du tout pour ce qui concerne les navigateurs mobiles.
merci d’avance pour votre réponse.
Bonjour,
Le support commence uniquement et partiellement sur iOS 6 et Android 4.4.
On peut donc commencer à l’utiliser dans le cadre d’une amélioration progressive.
Bon dimanche
Je suis tombé sur ton article pour trouver une solution à devoir déclarer une taille de police pour chaque taille d’écran mais vu la compatibilité (ou plutôt la non compatibilité) je crois qu’il va falloir continuer comme avant 🙁
Merci en tout cas, je ne connaissais pas.
Hello,
Cela dépend de ta cible et de l’utilité que tu en as. Pour les petits terminaux ou les tablettes, c’est plutôt bien supporté globalement.
En guise d’amélioration progressive c’est plutôt pas mal.
Bon appétit !
Et pour faire le contraire ? Si je veux grossir plus l’ecran est petit ?
Bonjour
Aujourd’hui, en 2016, la bonne interprétation de l’unités « vw » est largement implantée nativement sur tous les navigateurs courants 🙂 Bientôt la fin des bidouilles propriétaires (less, web-kit et Cie).
Enjoy! Merci W3C CSS3 instruction list
Hello,
Oui aujourd’hui c’est assez largement utilisable désormais 🙂
Super ! ^_^
Bonjour,
Est-il possible d’utiliser la solution en CSS pour CMS comme prestashop svp ?
Car j’ai pas mal d’onglet dans mon menu et selon les navigateurs, il se met soit sur une ligne soit sur 2. Du coup je pense que cette méthode pourrait me premettre de résoudre mon problème.
Qu’en pensez-vous ?
Vous en remerciant par avance.
Julien
Bonjour et merci pour cet article. Je débute vraiment en responsive et css. C’est pourquoi j’ai une question un peu bête:
Peut-on attribuer à une police, une vmin et une vmax?
ex:
p{
font-size: 1vmin 4vmax;
}
et si oui comment déclarer les 2 unité (vmin et vm) pour que cela fonctionne sur tous les navigateurs?
Merci d’avance pour votre réponse 🙂
Bonjour,
Non il n’est pas possible d’attribuer des dimensions de la sorte hélas 🙂
Il n’y a pas de questions bêtes lorsque l’on débute, seulement des questions qui permettent d’avance ;p