Esta es la solución más elegante que he creado. Utiliza la búsqueda binaria, haciendo 10 iteraciones. La forma ingenua era hacer un ciclo while y aumentar el tamaño de la fuente en 1 hasta que el elemento comenzara a desbordarse. Puede determinar cuándo un elemento comienza a desbordarse utilizando element.offsetHeight y element.scrollHeight . Si scrollHeight es más grande que offsetHeight, tiene un tamaño de fuente que es demasiado grande.
La búsqueda binaria es un algoritmo mucho mejor para esto. También está limitado por el número de iteraciones que desea realizar. Simplemente llame a flexFont e inserte la identificación div y ajustará el tamaño de fuente entre 8px y 96px .
He pasado algún tiempo investigando este tema y probando diferentes bibliotecas, pero finalmente creo que esta es la solución más sencilla y directa que realmente funcionará.
Tenga en cuenta que si lo desea, puede cambiar el uso offsetWidth
y scrollWidth
, o agregar ambos a esta función.
// Set the font size using overflow property and div height
function flexFont(divId) {
var content = document.getElementById(divId);
content.style.fontSize = determineMaxFontSize(content, 8, 96, 10, 0) + "px";
};
// Use binary search to determine font size
function determineMaxFontSize(content, min, max, iterations, lastSizeNotTooBig) {
if (iterations === 0) {
return lastSizeNotTooBig;
}
var obj = fontSizeTooBig(content, min, lastSizeNotTooBig);
// if `min` too big {....min.....max.....}
// search between (avg(min, lastSizeTooSmall)), min)
// if `min` too small, search between (avg(min,max), max)
// keep track of iterations, and the last font size that was not too big
if (obj.tooBig) {
(lastSizeTooSmall === -1) ?
determineMaxFontSize(content, min / 2, min, iterations - 1, obj.lastSizeNotTooBig, lastSizeTooSmall) :
determineMaxFontSize(content, (min + lastSizeTooSmall) / 2, min, iterations - 1, obj.lastSizeNotTooBig, lastSizeTooSmall);
} else {
determineMaxFontSize(content, (min + max) / 2, max, iterations - 1, obj.lastSizeNotTooBig, min);
}
}
// determine if fontSize is too big based on scrollHeight and offsetHeight,
// keep track of last value that did not overflow
function fontSizeTooBig(content, fontSize, lastSizeNotTooBig) {
content.style.fontSize = fontSize + "px";
var tooBig = content.scrollHeight > content.offsetHeight;
return {
tooBig: tooBig,
lastSizeNotTooBig: tooBig ? lastSizeNotTooBig : fontSize
};
}