Como detectar qual fonte definida foi usada em uma página da web?

138

Suponha que eu tenha a seguinte regra CSS na minha página:

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

Como posso detectar qual das fontes definidas foi usada no navegador do usuário?

Edite para as pessoas que se perguntam por que quero fazer isso: A fonte que estou detectando contém glifos que não estão disponíveis em outras fontes e quando o usuário não tiver a fonte, desejo exibir um link solicitando que o usuário faça o download dessa fonte para que pode usar meu aplicativo da web com a fonte correta.

Atualmente, estou exibindo o link da fonte de download para todos os usuários. Quero exibi-lo apenas para pessoas que não têm a fonte correta instalada.

Pat
fonte
2
Um aspecto a ter em mente é que alguns navegadores substituirão determinadas fontes ausentes por fontes semelhantes, o que é impossível de detectar usando o truque JavaScript / CSS. Por exemplo, os navegadores Windows substituem o Helvetica por Arial, se não estiver instalado. O truque mencionado pelo MojoFilter e pelo dragonmatank ainda informa que o Helvetica está instalado, mesmo que não esteja.
Tlrobinson
13
Uma pequena nota de cautela: Se você está oferecendo um link para baixar Calibri, estar ciente de que, embora seja empacotado dentro de vários produtos da Microsoft, é não uma fonte livre, e você está violando direitos autorais, oferecendo-lo para download.
Adam Hepton 01/09/08

Respostas:

72

Eu já vi isso de uma maneira duvidosa, mas bastante confiável. Basicamente, um elemento é configurado para usar uma fonte específica e uma string é definida para esse elemento. Se a fonte definida para o elemento não existir, será usada a fonte do elemento pai. Então, o que eles fazem é medir a largura da string renderizada. Se corresponder ao que eles esperavam para a fonte desejada, em oposição à fonte derivada, ela estará presente. Isso não funcionará para fontes monoespaçadas.

De onde veio: Javascript / CSS Font Detector (ajaxian.com; 12 de março de 2007)

MojoFilter
fonte
2
Outra abordagem usando measureTexto canvaselemento: github.com/Wildhoney/DetectFont
Wildhoney
33

Eu escrevi uma ferramenta JavaScript simples que você pode usar para verificar se uma fonte está instalada ou não.
Ele usa uma técnica simples e deve estar correta na maioria das vezes.

Verificador de jFont no github

Derek 朕 會 功夫
fonte
2
A detecção da fonte não resolve o problema. Você pode usá-lo para iterar as fontes declaradas e verificar o que é válido, mas fornece pouca ou nenhuma informação sobre qual fonte é usada para uma determinada div. Se você cria div's a partir de JS, como podemos saber qual fonte é usada?
Jon Lennart Aasenden
1
@JonLennartAasenden Para obter o tipo de letra utilizado Eu acredito que você pode usar a propriedade "computedStyle" (esqueci o nome exacto mas é algo parecido.)
Derek朕會功夫
1
Eu escrevi uma classe que funciona em todos os navegadores. Está escrito em Smart Pascal, que é compilado em JS, então não posso postar a solução aqui - mas, em resumo, tive que extrair a string da família de fontes, verificar se cada fonte era válida, pegar a primeira que era válida - e que funciona em qualquer lugar. Eu carreguei o "detector de fontes" para o pascal inteligente e fiz alguns ajustes.
Jon Lennart Aasenden
1
@JonLennartAasenden Não parece que sua turma é à prova de falhas. Os navegadores verificam cada fonte na prioridade dada, se instalada, mas às vezes optam por usar uma fonte de menor prioridade na lista, se a fonte instalada de maior prioridade tiver caracteres ou glifos ausentes que não correspondam aos tamanhos solicitados.
22416 Brandon Elliott #:
10

@pat Na verdade, o Safari não fornece a fonte usada, o Safari sempre retorna a primeira fonte na pilha, independentemente de estar instalada, pelo menos na minha experiência.

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

Supondo que Helvetica seja o instalado / usado, você obterá:

  • "minha fonte falsa" no Safari (e acredito que outros navegadores de webkit).
  • "minha fonte falsa, helvética, san-serif" nos navegadores Gecko e IE.
  • "helvetica" no Opera 9, embora eu tenha lido que eles estão mudando isso no Opera 10 para combinar com o Gecko.

Eu resolvi esse problema e criei o Font Unstack , que testa cada fonte em uma pilha e retorna apenas a primeira instalada. Ele usa o truque mencionado pelo @MojoFilter, mas somente retorna o primeiro se vários estiverem instalados. Embora ele sofra da fraqueza mencionada pelo @tlrobinson (o Windows substitui o Helvetica por Arial silenciosamente e informa que o Helvetica está instalado), ele funciona bem.

philoye
fonte
9

Uma técnica que funciona é observar o estilo calculado do elemento. Isso é suportado no Opera e no Firefox (e eu reconheço no safari, mas não testei). O IE (pelo menos 7) fornece um método para obter um estilo, mas parece ser o que estava na folha de estilo, não o estilo calculado. Mais detalhes sobre o modo quirks: obter estilos

Aqui está uma função simples para pegar a fonte usada em um 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;
    }
}

Se a regra CSS para isso fosse:

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

Em seguida, ele deve retornar helvética, se estiver instalado, caso contrário, arial e, por último, o nome da fonte sans-serif padrão do sistema. Observe que a ordem das fontes na sua declaração CSS é significativa.

Um truque interessante que você também pode tentar é criar muitos elementos ocultos com muitas fontes diferentes para tentar detectar quais fontes estão instaladas em uma máquina. Tenho certeza de que alguém poderia criar uma página de coleta de estatísticas de fontes bacana com essa técnica.

runeh
fonte
6
Isso retorna a string completa do css como "Helvetica, Arial, sans-serif". Não retorna a fonte real que está sendo usada.
Tom Kincaid
8

Um formulário simplificado é:

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

Se você precisar de algo mais completo, verifique isso .

Facebiz
fonte
8

Existe uma solução simples - basta usar element.style.font:

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

Esta função fará exatamente o que você deseja. Em execução Retornará o tipo de fonte do usuário / navegador. Espero que isso ajude.

Naeem Ul Wahhab
fonte
Estou tentando isso no Safari em um elemento que definitivamente possui a fonte Arial e estou recebendo "" como a fonte. alguma ideia do por que?
Alessandro Vermeulen
O motivo mais provável é que isso só verifique se há uma fonte definida e, se não houver uma fonte definida, provavelmente está usando Arial como a fonte.
1937 Josiah
1
@AlessandroVermeulen é porque element.style retorna apenas valores definidos em atributos de estilo e não retornará nenhum valor de outro lugar (ou seja, valores de elementos de estilo, css externo ou padrão de agente do usuário não serão retornados). Esta resposta deve ser removida porque é enganosa / incorreta. Inacreditável que tenha uma recompensa!
Brennanyoung 16/05/19
Sinto muito, mas não acho que essa seja a resposta certa. Enquanto isso imprime o valor dessa propriedade CSS, ele não retorna a fonte renderizada real que está sendo usada pelo navegador.
gonejun 9/07
7

Outra solução seria instalar a fonte automaticamente, o @font-faceque pode negar a necessidade de detecção.

@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");
}

É claro que isso não resolveria nenhum problema de direitos autorais, no entanto, você sempre pode usar uma fonte de freeware ou até criar sua própria fonte. Você precisará dos arquivos .eot& .ttfpara funcionar melhor.

PaulnOZ
fonte
3

Calibri é uma fonte de propriedade da Microsoft e não deve ser distribuída gratuitamente. Além disso, exigir que um usuário baixe uma fonte específica não é muito fácil de usar.

Sugiro que você compre uma licença para a fonte e a incorpore ao seu aplicativo.

Mark Kimitch
fonte
3
+1 para incorporação de fontes. Isso resolve o problema sem precisar detectar nada.
Andrew Grothe 22/03
1
Sugiro que verifique se há algo semelhante no Google Fonts antes de comprar qualquer coisa.
OJFord 20/01/14
Exceto que, se o usuário estiver em uma máquina Windows, ele poderá visualizar o Calibri. Este é o ponto inteiro das listas de fallback.
Dudewad
1
E sua resposta não está relacionada à pergunta e deve ser um comentário.
Dudewad
2

Estou usando o Fount. Você só precisa arrastar o botão Fonte para sua barra de favoritos, clicar nele e, em seguida, clicar em um texto específico no site. Ele mostrará a fonte desse texto.

https://fount.artequalswork.com/

Woppi
fonte
1

Você pode colocar o Adobe Blank na família de fontes após a fonte que deseja ver e, em seguida, quaisquer glifos que não estiverem nessa fonte não serão renderizados.

por exemplo:

font-family: Arial, 'Adobe Blank';

Tanto quanto sei, não existe um método JS para dizer quais glifos em um elemento estão sendo renderizados por qual fonte na pilha de fontes para esse elemento.

Isso é complicado pelo fato de os navegadores terem configurações de usuário para fontes serif / sans-serif / monospace e também terem suas próprias fontes de fallback back codificadas que serão usadas se um glifo não for encontrado em nenhuma das fontes de uma fonte. pilha de fontes. Portanto, o navegador pode renderizar alguns glifos em uma fonte que não está na pilha de fontes ou na configuração de fonte do navegador do usuário. As Ferramentas de desenvolvimento do Chrome mostrarão cada fonte renderizada para os glifos no elemento selecionado . Portanto, na sua máquina, você pode ver o que está fazendo, mas não há como saber o que está acontecendo na máquina do usuário.

Também é possível que o sistema do usuário possa desempenhar um papel nisso, como por exemplo, a Janela substitui a fonte no nível de glifo.

tão...

Para os glifos nos quais você está interessado, não há como saber se eles serão renderizados pelo navegador / sistema substituto do usuário, mesmo se eles não tiverem a fonte especificada.

Se você quiser testá-lo em JS, poderá renderizar glifos individuais com uma família de fontes, incluindo o Adobe Blank e medir sua largura para ver se é zero, mas você precisará iterar completamente cada glifo e cada fonte que deseja testar , mas embora você possa conhecer as fontes em uma pilha de fontes de elementos, não há como saber quais fontes o navegador do usuário está configurado para usar. Portanto, para pelo menos alguns de seus usuários, a lista de fontes pelas quais você itera estará incompleta. (Também não é à prova do futuro se novas fontes surgirem e começarem a ser usadas.)

Sam Hasler
fonte