javascript - rem - tamaños letra css
Convertir em a px en Javascript(y obtener el tamaño de fuente predeterminado) (4)
La siguiente solución utiliza la búsqueda binaria y window.matchMedia para conocer el ancho de una ventana. Luego, dividimos el ancho de la ventana em con el ancho del píxel de la ventana para obtener el resultado final. Sin DOM involucrado, ¡sin efectos secundarios! En términos de rendimiento, lleva alrededor de 8 iteraciones a alrededor de 0,2 ms en mi comp.
const singleEmInPixels = getSingleEmInPixels();
console.log(`1em = ${singleEmInPixels}px`);
/**
* returns the amount of pixels for a single em
*/
function getSingleEmInPixels() {
let low = 0;
let high = 200;
let emWidth = Math.round((high - low) / 2) + low;
const time = performance.now();
let iters = 0;
const maxIters = 10;
while (high - low > 1) {
const match = window.matchMedia(`(min-width: ${emWidth}em)`).matches;
iters += 1;
if (match) {
low = emWidth;
} else {
high = emWidth;
}
emWidth = Math.round((high - low) / 2) + low;
if (iters > maxIters) {
console.warn(`max iterations reached ${iters}`);
break;
}
}
const singleEmPx = Math.ceil(window.innerWidth / emWidth);
console.log(`window em width = ${emWidth}, time elapsed = ${(performance.now() - time)}ms`);
return singleEmPx;
}
Hay situaciones en las que puede ser útil obtener el ancho de píxel exacto de una medición em
. Por ejemplo, supongamos que tiene un elemento con una propiedad CSS (como borde o relleno) que se mide en ems, y necesita obtener el ancho exacto de píxeles del borde o relleno. Hay una pregunta existente que toca este tema:
¿Cómo puedo obtener el tamaño de fuente predeterminado en píxeles usando JavaScript o JQuery?
Esta pregunta es para obtener el tamaño de fuente predeterminado , que es necesario para convertir un valor de em
relativo a em
valor de px
exacto.
Esta respuesta tiene una explicación bastante buena de cómo obtener el tamaño de fuente predeterminado de un elemento:
Dado que ems mide el ancho, siempre puedes calcular el tamaño exacto de la fuente de píxeles creando un div que tenga 1000 ems de longitud y dividiendo su propiedad de ancho del cliente entre 1000. Me parece recordar que los ems se truncan a la milésima más cercana, por lo que necesitas 1000 ems para evitar un truncamiento erróneo del resultado del píxel.
Entonces, usando esta respuesta como guía, escribí la siguiente función para obtener el tamaño de fuente predeterminado:
function getDefaultFontSize(parentElement)
{
parentElement = parentElement || document.body;
var div = document.createElement(''div'');
div.style.width = "1000em";
parentElement.appendChild(div);
var pixels = div.offsetWidth / 1000;
parentElement.removeChild(div);
return pixels;
}
Una vez que tiene el tamaño de fuente predeterminado, puede convertir cualquier ancho de em
a px
ancho simplemente multiplicando el ccsme por el tamaño de fuente predeterminado del elemento y redondeando el resultado:
Math.round(ems * getDefaultFontSize(element.parentNode))
Problema: idealmente se supone que getDefaultFontSize
es una función simple, libre de efectos secundarios que devuelve el tamaño de fuente predeterminado. Pero TIENE un desafortunado efecto secundario: ¡modifica el DOM! Anexa un niño y luego lo saca. Agregar el elemento secundario es necesario para obtener una propiedad válida de offsetWidth
. Si no agrega el div
infantil al DOM, la propiedad offsetWidth
permanece en 0 porque el elemento nunca se representa. Aunque eliminemos inmediatamente el elemento secundario, esta función aún puede crear efectos colaterales no deseados, como disparar un evento (como el evento onpropertychange
Internet Explorer o el evento DOMSubtreeModified
de W3C) que estaba escuchando en el elemento padre.
Pregunta: ¿Hay alguna forma de escribir una función getDefaultFontSize()
verdaderamente libre de efectos getDefaultFontSize()
que no getDefaultFontSize()
accidentalmente los controladores de eventos ni cause otros efectos secundarios no deseados?
Si necesita algo rápido y sucio (y basado en el tamaño de letra base del cuerpo, no en un elemento), yo iría con:
Number(getComputedStyle(document.body,null).fontSize.replace(/[^/d]/g, ''''))
Number( // Casts numeric strings to number
getComputedStyle( // takes element and returns CSSStyleDeclaration object
document.body,null) // use document.body to get first "styled" element
.fontSize // get fontSize property
.replace(/[^/d]/g, '''') // simple regex that will strip out non-numbers
) // returns number
Tengo una mejor respuesta. Mi código almacenará el valor de 1em en la unidad-px en la variable em
.
Coloque este
div
en cualquier lugar de su código HTML<div id="div" style="height:0;width:0;outline:none;border:none;padding:none;margin:none;"></div>
Coloque esta función en su archivo JavaScript
var em; function getValue(id){ var div = document.getElementById(id); div.style.height = 1em; em = div.offsetHeight; }
Ahora, siempre que llame a esta función ''getValue''
con id de esa prueba div en el parámetro, tendrá un nombre de variable em
que contendrá el valor de 1 em en px.
Editar: No, no hay.
Para obtener el tamaño de fuente renderizado de un elemento dado, sin afectar el DOM:
parseFloat(getComputedStyle(parentElement).fontSize);
Esto se basa en la respuesta a esta pregunta .
Editar:
En IE, tendrías que usar parentElement.currentStyle["fontSize"]
, pero esto no garantiza convertir el tamaño a px
. Así que eso está fuera.
Además, este fragmento no le proporcionará el tamaño de fuente predeterminado del elemento, sino su tamaño de fuente real , que es importante si realmente tiene una clase y un estilo asociados. En otras palabras, si el tamaño de letra del elemento es 2em
, obtendrá el número de píxeles en 2 ems. A menos que el tamaño de fuente se especifique en línea, no podrá obtener la proporción de conversión correcta.