Adapter la taille du texte au menu : un jeu d'enfant

shapegame

J’ai récemment été confronté à un casse-tête : adapter la taille du texte d’un menu horizontal, en fonction du nombre d’entrées dans celui-ci. Facile, il suffit de gérer ça au calcul de la page… Seulement voilà, un nom de page ça peut faire 5 caractères comme 20. En cherchant sur le net je suis tombé sur beaucoup de plugins jquery (fit-text, text-fill…), mais aucun ne faisait exactement ce que je voulais. Alors j’ai utilisé une petite moulinette javascript, détaillée ci-après…

D’abord, la structure HTML. Inutile de s’y attarder, un classique ul/li avec un positionnement horizontal. Donnons au menu l’identifiant – qu’est-ce que c’est original – « menu ».
Coté CSS, on fixe à ul#menu une largeur fixe.
Maintenant, la partie javascript.  On va commencer par initialiser deux variables :

var nblettres = 0;
var menuWidth = $('ul#menu').width();

Ensuite, on compte le nombre de lettres dans les liens du menu :

$('ul#menu li a').each(function(){
	nblettres += $(this).html().length;
});

Ensuite, on essaie de se débrouiller avec ces infos en utilisant le bon vieux raisonnement par essais successifs : largeur du menu, nombre de lettres…
Première intuition : on divise la largeur par le nombre de lettres. Cela donne un nombre à virgule, donc on le tronque avec Math.floor() :

Math.floor(menuWidth/(nblettres)

Le problème, c’est que dans la pratique et en fonction du nombre de lettres, il y a un gap trop important entre trop petit et trop grand. Deuxième intuition donc : pondérer le résultat avec un facteur arbitraire. Ce facteur a été trouvé par essais successifs, 0.86 :

Math.floor(menuWidth/(nblettres*0.86)

J’obtiens la bonne taille, qui permet de remplir correctement tout le menu peu importe le nombre d’entrées / lettres qu’il y a dedans. Voici le code complet avec l’affectation de la taille via jquery :

var nblettres = 0;
var menuWidth = $('ul#menu').width();
$('ul#menu li a').each(function(){
 nblettres += $(this).html().length;
});
$('ul#menu').css("font-size", Math.floor(menuWidth/(nblettres*0.86))+"pt");

J’espère que ça pourra aider ceux qui se sont posés la question… Si vous avez des remarques ou des idées, n’hésitez pas 🙂

Laisser un commentaire

Votre adresse courriel ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire le pourriel. En savoir plus sur comment les données de vos commentaires sont utilisées.