Як визначити, який із визначених шрифтів використовувався на веб-сторінці?


138

Припустимо, на моїй сторінці є таке правило CSS:

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

Як я можу виявити, який із визначених шрифтів використовувався у веб-переглядачі користувача?

Редагуйте для людей, які цікавляться, чому я хочу це зробити: Шрифт, який я виявляю, містить гліфи, які не доступні в інших шрифтах, і коли у користувача немає шрифту, я хочу відобразити посилання з проханням користувача завантажити цей шрифт, щоб вони можна використовувати мій веб-додаток з правильним шрифтом.

На даний момент я показую посилання для завантаження шрифту для всіх користувачів, я хочу відображати це лише для людей, у яких не встановлений правильний шрифт.


2
Слід пам’ятати, що деякі браузери замінять певні відсутні шрифти аналогічними шрифтами, що неможливо виявити за допомогою трюку JavaScript / CSS. Наприклад, браузери Windows замінять Arial на Helvetica, якщо він не встановлений. Згаданий трюк MojoFilter та dragonmatank все ще повідомлять, що Helvetica встановлений, хоча це не так.
tlrobinson

13
Невелика нотка обережності: Якщо ви пропонуєте посилання для завантаження Calibri, пам’ятайте, що він постачається в межах декількох продуктів Microsoft, але це не безкоштовний шрифт, і ви порушуєте авторські права, пропонуючи його для завантаження.
Адам Хептон

Відповіді:


72

Я бачив, що це робиться на якийсь неприємний, але досить надійний спосіб. В основному, елемент встановлюється для використання певного шрифту, а для цього елемента - рядок. Якщо набір шрифту для елемента не існує, він бере шрифт батьківського елемента. Отже, те, що вони роблять, - це вимірювати ширину виведеного рядка. Якщо він відповідає тому, що вони очікували для потрібного шрифту, на відміну від похідного шрифту, він присутній. Це не буде працювати для одноразових шрифтів.

Ось звідки це: Детектор шрифтів Javascript / CSS (ajaxian.com; 12 березня 2007 р.)


2
Ще один підхід, що використовується measureTextз canvasелемента: github.com/Wildhoney/DetectFont
Wildhoney

33

Я написав простий інструмент JavaScript, за допомогою якого ви можете перевірити, встановлений чи ні шрифт.
Він використовує просту техніку і повинна бути правильною більшу частину часу.

jFont Checker на github


2
Виявлення шрифту не вирішує проблему. Ви можете використати його для повторення продуманих оголошених шрифтів та перевірки того, що є дійсним, але це дає мало інформації про те, який шрифт використовується для будь-якого діла. Якщо ви створюєте div з JS, як ми можемо знати, який шрифт використовується?
Джон Леннарт Аасенден,

1
@JonLennartAasenden Щоб отримати використаний шрифт, я вважаю, що ви можете використовувати властивість "computedStyle" (я забув точну назву, але це щось подібне.)
Derek 朕 會 功夫

1
Я написав клас, який працює у всіх браузерах. Це написано на Smart Pascal, який компілюється в JS, тому я не можу дійсно розмістити тут рішення - але коротше кажучи, мені довелося витягнути рядок сімейства шрифтів, а потім перевірити, чи кожний шрифт дійсний, схопимо перше, що було дійсним - і це працює скрізь. Я переніс "детектор шрифтів" на розумний паскаль і зробив декілька налаштувань.
Джон Леннарт Аасенден

1
@JonLennartAasenden Це не здається, що ваш клас дурний. Браузери перевірять кожен шрифт у вказаному пріоритеті, якщо він встановлений, але іноді вирішать використовувати шрифт із нижчим пріоритетом у списку, якщо у вищому пріоритеті встановлений шрифт містить відсутні символи чи гліфи, які не відповідають запитуваному розміру.
Брендон Елліотт

10

@pat Насправді, Safari не дає використаного шрифту, натомість Safari завжди повертає перший шрифт у стеку, незалежно від того, встановлений він, принаймні, з мого досвіду.

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

Якщо припустити, що Helvetica встановлена ​​/ використана, ви отримаєте:

  • "мій підроблений шрифт" в Safari (і я вважаю, інші веб-браузери).
  • "мій підроблений шрифт, helvetica, san-serif" у веб-переглядачах Gecko та IE.
  • "helvetica" в Opera 9, хоча я читав, що вони змінюють це в Opera 10, щоб відповідати Gecko.

Я вирішив цю проблему і створив Font Unstack , який тестує кожен шрифт у стеку і повертає лише перший встановлений. Він використовує трюк, про який згадує @MojoFilter, але перший повертає лише якщо встановлено кілька. Хоча він і страждає від слабкості, про яку згадує @tlrobinson (Windows замінить Arial на Helvetica мовчки і повідомить, що Helvetica встановлена), інакше це працює добре.


9

Методика, яка працює, полягає в перегляді обчисленого стилю елемента. Це підтримується в Opera та Firefox (і я відновлююсь у сафарі, але не перевіряв). IE (принаймні, 7) надає метод отримання стилю, але, схоже, все, що було в таблиці стилів, а не обчислений стиль. Детальніше про quirksmode: Отримати стилі

Ось проста функція захоплення шрифту, який використовується в елементі:

/**
 * 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;
    }
}

Якщо правило CSS для цього було:

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

Тоді він повинен повернути helvetica, якщо це встановлено, якщо ні, arial, і, нарешті, ім'я шрифту системи за замовчуванням sans-serif. Зауважте, що впорядкування шрифтів у вашій CSS-декларації є суттєвим.

Цікавий хакер, який ви також можете спробувати, - це створити безліч прихованих елементів з великою кількістю різних шрифтів, щоб спробувати виявити, які шрифти встановлені на машині. Я впевнений, що хтось міг би зробити за допомогою цієї техніки чудову сторінку зібрання статистики шрифтів.


6
Це повертає повний рядок css типу "Helvetica, Arial, sans-serif". Він не повертає фактично використаний шрифт.
Том Кінкейд

8

Спрощеною формою є:

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

Якщо вам потрібно щось повніше, перевірте це .


8

Є просте рішення - просто використовуйте element.style.font:

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

Ця функція буде точно робити те, що ви хочете. Під час виконання він поверне тип шрифту користувача / браузера. Сподіваюсь, це допоможе.


Я намагаюся це зробити в Safari на елементі, який безумовно має шрифт Arial, і я отримую "" як шрифт. Будь-які ідеї, чому?
Алессандро Вермеулен

Найбільш вірогідна причина полягає в тому, що це перевіряє лише встановлений шрифт, і якщо немає набору шрифтів, він, ймовірно, використовує Arial як шрифт.
Йосія

1
@AlessandroVermeulen це тому, що element.style повертає лише значення, задані в атрибутах стилю, і не повертає жодних значень з інших місць (тобто значення елементів стилю, зовнішній css або типовий користувацький агент не повертаються). Цю відповідь слід видалити, оскільки вона вводить в оману / неправильно. Неймовірно, що вона отримала щедрість!
brennanyoung

Вибачте, але я не думаю, що це правильна відповідь. Хоча це виводить значення для цього властивості CSS, воно не повертає фактично виведений шрифт, який використовується браузером.
gojun

7

Іншим рішенням буде встановлення шрифту автоматично, за допомогою @font-faceякого може заперечуватися потреба у виявленні.

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

Звичайно, це не вирішить жодних проблем з авторським правом, проте ви завжди можете використовувати безкоштовний шрифт або навіть зробити свій власний шрифт. Вам потрібно буде обидва файли .eotта .ttfфайли, щоб найкраще працювати.


3

Calibri - це шрифт, що належить корпорації Майкрософт, і його не слід поширювати безкоштовно. Крім того, вимагати від користувача завантаження певного шрифту не дуже зручно.

Я б запропонував придбати ліцензію на шрифт та вбудувати його у свою програму.


3
+1 для вставки шрифту. Це вирішує проблему, не вимагаючи нічого виявляти.
Ендрю Гроте

1
Я б запропонував перевірити Google Fonts на щось подібне, перш ніж купувати щось.
OJFord

За винятком того, що якщо користувач знаходиться на машині Windows, він може переглядати Calibri. Це весь пункт резервних списків.
dudewad

1
І ваша відповідь не пов'язана з питанням, і має бути коментарем.
dudewad

2

Я використовую Fount. Вам просто потрібно перетягнути кнопку Fount до панелі закладок, натиснути на неї та натиснути певний текст на веб-сайті. Потім він покаже шрифт цього тексту.

https://fount.artequalswork.com/



1

Ви можете помістити Adobe Blank у сімейство шрифтів після того, як ви бажаєте бачити шрифт, і тоді будь-які гліфи, які не містять цей шрифт, не будуть надані.

наприклад:

font-family: Arial, 'Adobe Blank';

Наскільки мені відомо, не існує методу JS, який би визначив, які гліфи в елементі передаються, за допомогою якого шрифту в стеці шрифту для цього елемента.

Це ускладнюється тим, що у веб-переглядачах є користувацькі налаштування для шрифтів serif / sans-serif / monospace, а також у них є власні жорсткі кодові запасні шрифти, які вони будуть використовувати, якщо у будь-якому із шрифтів у гріфі не знайдено гліфів стек шрифту. Таким чином, браузер може відображати деякі гліфи у шрифті, який не знаходиться в стеці шрифту або в налаштуваннях шрифту браузера користувача. Chrome Dev Tools покаже вам кожен відредагований шрифт для гліфів у вибраному елементі . Таким чином, на вашій машині ви можете бачити, що це робить, але немає можливості сказати, що відбувається на машині користувача.

Можливо також, що система користувача може зіграти певну роль у цьому, наприклад, наприклад, Window виконує заміну шрифту на рівні гліфів.

так...

Для зацікавлених вами гліфів ви не можете знати, чи будуть вони надані користувачем веб-переглядача / системи, навіть якщо вони не мають вказаного вами шрифту.

Якщо ви хочете перевірити його в JS, ви можете вивести окремі гліфи із сімейством шрифтів, включаючи Adobe Blank, і виміряти їх ширину, щоб побачити, чи не дорівнює нулю, Але вам доведеться ретельно повторити кожен гліф і кожен шрифт, який ви хочете перевірити , але хоча ви можете знати шрифти в стеку шрифтів елементів, немає ніякого способу знати, які шрифти налаштований браузером користувача, щоб принаймні для деяких користувачів список шрифтів, які ви повторюєте, буде неповним. (Це також не є майбутнім доказом, якщо нові шрифти з’являться і почнуть звикати.)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.