¿Cómo detectar cuál de las fuentes definidas se utilizó en una página web?

138

Supongamos que tengo la siguiente regla CSS en mi página:

body {
  font-family: Calibri, Trebuchet MS, Helvetica, sans-serif;
}

¿Cómo puedo detectar cuál de las fuentes definidas se utilizó en el navegador del usuario?

Edite para las personas que se preguntan por qué quiero hacer esto: la fuente que estoy detectando contiene glifos que no están disponibles en otras fuentes y cuando el usuario no tiene la fuente, quiero mostrar un enlace pidiéndole al usuario que descargue esa fuente para que puedan puedo usar mi aplicación web con la fuente correcta.

Actualmente estoy mostrando el enlace de descarga de la fuente para todos los usuarios, solo quiero mostrar esto para las personas que no tienen instalada la fuente correcta.

Palmadita
fuente
2
Una cosa a tener en cuenta es que algunos navegadores reemplazarán ciertas fuentes que faltan por fuentes similares, lo cual es imposible de detectar utilizando el truco JavaScript / CSS. Por ejemplo, los navegadores de Windows sustituirán a Arial por Helvetica si no está instalado. El truco mencionado por MojoFilter y dragonmatank seguirá informando que Helvetica está instalada, aunque no lo esté.
tlrobinson
13
Una pequeña nota de precaución: Si se ofrece un enlace para descargar Calibri, tenga en cuenta que a pesar de que se incluye dentro de varios productos de Microsoft, es no una fuente libre, y que está violando los derechos de autor, ofreciendo para su descarga.
Adam Hepton

Respuestas:

72

Lo he visto hecho de una manera dudosa, pero bastante confiable. Básicamente, un elemento está configurado para usar una fuente específica y una cadena está configurada para ese elemento. Si la fuente establecida para el elemento no existe, toma la fuente del elemento padre. Entonces, lo que hacen es medir el ancho de la cadena representada. Si coincide con lo que esperaban para la fuente deseada en lugar de la fuente derivada, está presente. Esto no funcionará para fuentes monoespaciadas.

Aquí es de dónde vino: Detector de fuentes Javascript / CSS (ajaxian.com; 12 de marzo de 2007)

MojoFilter
fuente
2
Otro enfoque usando measureTextdesde el canvaselemento: github.com/Wildhoney/DetectFont
Wildhoney
33

Escribí una herramienta JavaScript simple que puede usar para verificar si una fuente está instalada o no.
Utiliza una técnica simple y debe ser correcta la mayor parte del tiempo.

jFont Checker en github

Derek 朕 會 功夫
fuente
2
La detección de fuente no resuelve el problema. Puede usarlo para iterar a través de las fuentes declaradas y verificar qué es válido, pero proporciona poca o ninguna información sobre qué fuente se usa para un div determinado. Si crea div's de JS, ¿cómo podemos saber qué fuente se utiliza?
Jon Lennart Aasenden
1
@JonLennartAasenden Para obtener la fuente usada, creo que puedes usar la propiedad "computedStyle" (olvidé el nombre exacto pero es algo así).
Derek 朕 會 功夫
1
Escribí una clase que funciona en todos los navegadores. Está escrito en Smart Pascal que se compila a JS, por lo que realmente no puedo publicar la solución aquí, pero en resumen, tuve que extraer la cadena de la familia de fuentes, luego verificar que cada fuente fuera válida, tomar la primera que fuera válida y eso Funciona en todas partes. Trasporté el "detector de fuentes" a pascal inteligente e hice algunos ajustes.
Jon Lennart Aasenden
1
@JonLennartAasenden No parece que tu clase sea infalible. Los navegadores verificarán cada fuente con la prioridad dada, si está instalada, pero a veces optarán por usar una fuente de menor prioridad en la lista, si la fuente instalada de mayor prioridad tiene caracteres faltantes o glifos que no coinciden con los tamaños solicitados.
Brandon Elliott
10

@pat En realidad, Safari no da la fuente utilizada, Safari siempre devuelve la primera fuente en la pila independientemente de si está instalada, al menos en mi experiencia.

font-family: "my fake font", helvetica, san-serif;

Asumiendo que Helvetica es la que está instalada / utilizada, obtendrá:

  • "mi fuente falsa" en Safari (y creo que otros navegadores webkit).
  • "mi fuente falsa, helvetica, san-serif" en los navegadores Gecko e IE.
  • "helvetica" en Opera 9, aunque leí que están cambiando esto en Opera 10 para que coincida con Gecko.

Pasé por este problema y creé Font Unstack , que prueba cada fuente en una pila y devuelve solo la primera instalada. Utiliza el truco que menciona @MojoFilter, pero solo devuelve el primero si hay varios instalados. Aunque sufre la debilidad que menciona @tlrobinson (Windows sustituirá a Arial por Helvetica en silencio e informará que Helvetica está instalada), de lo contrario funciona bien.

philoye
fuente
9

Una técnica que funciona es mirar el estilo calculado del elemento. Esto es compatible con Opera y Firefox (y lo reconozco en safari, pero no lo he probado). IE (7 al menos), proporciona un método para obtener un estilo, pero parece ser lo que haya en la hoja de estilo, no el estilo calculado. Más detalles sobre quirksmode: Obtener estilos

Aquí hay una función simple para tomar la fuente utilizada en un elemento:

/**
 * Get the font used for a given element
 * @argument {HTMLElement} the element to check font for
 * @returns {string} The name of the used font or null if font could not be detected
 */
function getFontForElement(ele) {
    if (ele.currentStyle) { // sort of, but not really, works in IE
        return ele.currentStyle["fontFamily"];
    } else if (document.defaultView) { // works in Opera and FF
        return document.defaultView.getComputedStyle(ele,null).getPropertyValue("font-family");
    } else {
        return null;
    }
}

Si la regla CSS para esto era:

#fonttester {
    font-family: sans-serif, arial, helvetica;
}

Entonces debería devolver helvetica si está instalado, si no, arial y, por último, el nombre de la fuente sans-serif predeterminada del sistema. Tenga en cuenta que el orden de las fuentes en su declaración CSS es significativo.

Un truco interesante que también podrías probar es crear muchos elementos ocultos con muchas fuentes diferentes para tratar de detectar qué fuentes están instaladas en una máquina. Estoy seguro de que alguien podría hacer una ingeniosa página de recopilación de estadísticas de fuentes con esta técnica.

runeh
fuente
66
Esto devuelve la cadena completa del css como "Helvetica, Arial, sans-serif". No devuelve la fuente real que se está utilizando.
Tom Kincaid el
8

Una forma simplificada es:

function getFont() {
    return document.getElementById('header').style.font;
}

Si necesitas algo más completo, mira esto .

Facebiz
fuente
8

Hay una solución simple: solo use element.style.font:

function getUserBrowsersFont() {
    var browserHeader = document.getElementById('header');
    return browserHeader.style.font;
}

Esta función hará exactamente lo que quieras. En la ejecución, devolverá el tipo de fuente del usuario / navegador. Espero que esto ayude.

Naeem Ul Wahhab
fuente
Estoy intentando esto en Safari en un elemento que definitivamente tiene la fuente Arial y obtengo "" como fuente. ¿Alguna idea de por qué?
Alessandro Vermeulen
La razón más probable es que esto solo busca una fuente establecida, y si no hay una fuente establecida, probablemente esté usando Arial como fuente.
Josiah
1
@AlessandroVermeulen es porque element.style solo devuelve valores establecidos en atributos de estilo, y no devolverá ningún valor de otra parte (es decir, no se devolverán valores de elementos de estilo, CSS externo o agente de usuario predeterminado). Esta respuesta debe eliminarse porque es engañosa / incorrecta. ¡Increíble que haya obtenido una recompensa!
brennanyoung
Lo siento, pero no creo que esta sea la respuesta correcta. Si bien esto imprime el valor de esa propiedad CSS, no devuelve la fuente renderizada real que está utilizando el navegador.
fue el
7

Otra solución sería instalar la fuente automáticamente a través de lo @font-facecual podría negar la necesidad de detección.

@font-face { 
font-family: "Calibri"; 
src: url("http://www.yourwebsite.com/fonts/Calibri.eot"); 
src: local("Calibri"), url("http://www.yourwebsite.com/fonts/Calibri.ttf") format("truetype");
}

Por supuesto, no resolvería ningún problema de derechos de autor, sin embargo, siempre puede usar una fuente gratuita o incluso hacer su propia fuente. Necesitará tanto .eoty .ttfarchivos para funcionar mejor.

PaulnOZ
fuente
3

Calibri es una fuente propiedad de Microsoft, y no debe distribuirse de forma gratuita. Además, exigir a un usuario que descargue una fuente específica no es muy fácil de usar.

Sugeriría comprar una licencia para la fuente e incrustarla en su aplicación.

Mark Kimitch
fuente
3
+1 para incrustar fuentes. Esto resuelve el problema sin tener que detectar nada.
Andrew Grothe
1
Sugeriría verificar Google Fonts para algo similar antes de comprar cualquier cosa.
OJFord
Excepto que, si el usuario está en una máquina con Windows, puede ver Calibri. Este es el punto completo de las listas de reserva.
dudewad
1
Y su respuesta no está relacionada con la pregunta, y debe ser un comentario.
dudewad
2

Estoy usando Fount. Solo tiene que arrastrar el botón Fount a la barra de marcadores, hacer clic en él y luego hacer clic en un texto específico en el sitio web. Luego mostrará la fuente de ese texto.

https://fount.artequalswork.com/

Woppi
fuente
1

Puede colocar Adobe Blank en la familia de fuentes después de la fuente que desea ver, y luego no se representarán los glifos que no estén en esa fuente.

p.ej:

font-family: Arial, 'Adobe Blank';

Hasta donde yo sé, no hay un método JS para saber qué glifos en un elemento se representan con qué fuente en la pila de fuentes para ese elemento.

Esto se complica por el hecho de que los navegadores tienen configuraciones de usuario para las fuentes serif / sans-serif / monospace y también tienen sus propias fuentes alternativas codificadas que usarán si no se encuentra un glifo en ninguna de las fuentes de un pila de fuentes Por lo tanto, el navegador puede representar algunos glifos en una fuente que no está en la pila de fuentes o en la configuración de fuente del navegador del usuario. Chrome Dev Tools le mostrará cada fuente renderizada para los glifos en el elemento seleccionado . Entonces, en su máquina puede ver lo que está haciendo, pero no hay forma de saber qué está sucediendo en la máquina de un usuario.

También es posible que el sistema del usuario pueda desempeñar un papel en esto, por ejemplo, Window realiza la sustitución de fuentes a nivel de glifo.

entonces...

Para los glifos que le interesan, no tiene forma de saber si serán representados por el navegador del usuario / sistema de respaldo, incluso si no tienen la fuente que especifique.

Si desea probarlo en JS, puede renderizar glifos individuales con una familia de fuentes que incluya Adobe Blank y medir su ancho para ver si es cero, PERO tendría que repetir cada glifo y cada fuente que desea probar , pero aunque puede conocer las fuentes en una pila de fuentes de elementos, no hay forma de saber qué fuentes está configurado para usar el navegador del usuario, por lo que, al menos para algunos de sus usuarios, la lista de fuentes con las que itera estará incompleta. (Tampoco es una prueba futura si salen nuevas fuentes y comienzan a usarse).

Sam Hasler
fuente