Как определить, какой из заданных шрифтов был использован на веб-странице?

Предположим, у меня на странице есть следующее правило CSS:

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

Как я мог определить, какой из определенных шрифтов использовался в браузере пользователя?

Для людей, которые задаются вопросом, почему я хочу это сделать, потому что обнаруживаемый мной шрифт содержит глифы, которые нет доступны в других шрифтах. Если у пользователя есть шрифт нет, я хочу, чтобы он отображал ссылку, предлагающую пользователю загрузить этот шрифт (чтобы они могли использовать мое веб-приложение с правильным шрифтом).

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

Небольшое предупреждение: если вы предлагаете ссылку для загрузки Calibri, имейте в виду, что, хотя он входит в состав нескольких продуктов Microsoft, это бесплатный шрифт нет, и вы нарушаете авторские права, предлагая его для загрузки.

Adam Hepton 01.09.2008 12:18

Следует иметь в виду, что некоторые браузеры заменяют определенные отсутствующие шрифты аналогичными шрифтами, что невозможно обнаружить с помощью трюка JavaScript / CSS. Например, браузеры Windows заменят Helvetica на Arial, если он не установлен. Уловка, о которой упоминали MojoFilter и dragonmatank, по-прежнему будет сообщать, что Helvetica установлена, даже если это не так.

tlrobinson 04.08.2008 05:05

В наши дни вы также можете использовать интерфейс FontFaceSet, чтобы проверить, доступен ли шрифт; см. developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/check

ArendE 02.02.2021 20:54
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
142
3
49 795
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

Ответ принят как подходящий

Я видел, как это делалось ненадежным, но довольно надежным способом. По сути, элемент настроен на использование определенного шрифта, и для этого элемента установлена ​​строка. Если шрифт, установленный для элемента, не существует, он принимает шрифт родительского элемента. Итак, что они делают, так это измеряют ширину отображаемой строки. Если он соответствует тому, что они ожидали для желаемого шрифта, а не производному шрифту, он присутствует. Это не сработает для моноширинных шрифтов.

Вот откуда это взялось: Детектор шрифтов Javascript / CSS (ajaxian.com; 12 марта 2007 г.)

Другой подход с использованием measureText из элемента canvas: github.com/Wildhoney/DetectFont

Wildhoney 24.02.2016 12:35

Метод, который работает, - это посмотреть на вычисленный стиль элемента. Это поддерживается в 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 и, наконец, имя системного шрифта без засечек по умолчанию. Обратите внимание, что порядок шрифтов в вашем объявлении CSS имеет большое значение.

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

Это возвращает полную строку CSS, например «Helvetica, Arial, sans-serif». Он не возвращает фактический используемый шрифт.

Tom Kincaid 02.10.2013 22:09

@pat На самом деле Safari не предоставляет используемый шрифт, вместо этого Safari всегда возвращает первый шрифт в стеке, независимо от того, установлен ли он, по крайней мере, по моему опыту.

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

Предполагая, что Helvetica установлена ​​/ используется, вы получите:

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

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

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

jFont Checker на github

Обнаружение шрифта не решает проблему. Вы можете использовать его для перебора объявленных шрифтов и проверки того, что является допустимым, но он дает мало или совсем не дает информации о том, какой шрифт используется для любого данного div. Если вы создаете div из JS, как мы можем узнать, какой шрифт используется?

Jon Lennart Aasenden 31.08.2014 23:55

@JonLennartAasenden Чтобы получить используемый шрифт, я полагаю, вы можете использовать свойство computedStyle (я забыл точное имя, но это что-то вроде этого).

Derek 朕會功夫 01.09.2014 00:38

Я написал класс, который работает во всех браузерах. Он написан на Smart Pascal, который компилируется в JS, поэтому я не могу опубликовать здесь решение, но, короче говоря, мне пришлось извлечь строку семейства шрифтов, затем проверить, что каждый шрифт действителен, взять первый, который был действительным, и это работает везде. Я перенес "детектор шрифтов" на smart pascal и сделал некоторые настройки.

Jon Lennart Aasenden 04.09.2014 22:03

@JonLennartAasenden Не похоже, что ваш класс защищен от дурака. Браузеры будут проверять каждый шрифт по заданному приоритету, если он установлен, но иногда предпочитают использовать шрифт с более низким приоритетом в списке, если установленный шрифт с более высоким приоритетом имеет отсутствующие символы или глифы, которые не соответствуют запрошенным размерам.

Brandon Elliott 11.07.2016 02:05

Упрощенная форма:

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

Если вам нужно что-то более полное, проверьте это.

Есть простое решение - используйте element.style.font:

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

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

Я пробую это в Safari для элемента, который определенно имеет шрифт Arial, и я получаю "" в качестве шрифта. Есть идеи, почему?

Alessandro Vermeulen 04.07.2013 12:52

Наиболее вероятная причина в том, что при этом проверяется только установленный шрифт, и если шрифт не установлен, вероятно, в качестве шрифта используется Arial.

Josiah 11.01.2016 22:40

@AlessandroVermeulen это потому, что element.style возвращает только значения, установленные в атрибутах стиля, и не будет возвращать никаких значений из других источников (т.е. значения из элементов стиля, внешнего CSS или пользовательского агента по умолчанию не будут возвращены). Этот ответ следует удалить, поскольку он вводит в заблуждение / неверен. Невероятно, что он получил награду!

brennanyoung 16.05.2019 11:46

Мне очень жаль, но я не думаю, что это правильный ответ. Хотя при этом выводится значение этого свойства CSS, он не возвращает фактический шрифт оказано, который используется браузером.

wentjun 09.07.2020 14:32

Другое решение - автоматическая установка шрифта через @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.

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

Я бы посоветовал приобрести лицензию на шрифт и встроить его в ваше приложение.

+1 за встраивание шрифтов. Это решает проблему, ничего не обнаруживая.

Andrew Grothe 22.03.2013 19:58

Я бы посоветовал проверить Google шрифты на что-то подобное, прежде чем что-либо покупать.

OJFord 20.01.2014 10:56

Кроме того, если пользователь работает на компьютере с Windows, он может просматривать Calibri. В этом весь смысл резервных списков.

dudewad 01.05.2015 01:30

И ваш ответ не имеет отношения к вопросу, а должен быть комментарием.

dudewad 01.05.2015 01:31

Вы можете использовать этот сайт:

http://website-font-analyzer.com/

Он делает именно то, что вы хотите ...

@MehranTM да, этот проект закрыли несколько лет назад.

user2267379 25.08.2020 18:09

Я использую Fount. Вам просто нужно перетащить кнопку Fount на панель закладок, щелкнуть по ней, а затем щелкнуть определенный текст на веб-сайте. Затем он покажет шрифт этого текста.

https://fount.artequalswork.com/

Вы можете поместить Adobe Blank в font-family после шрифта, который хотите видеть, и тогда любые глифы, не принадлежащие этому шрифту, не будут отображаться.

например.:

font-family: Arial, 'Adobe Blank';

Насколько мне известно, не существует JS-метода, чтобы определить, какие глифы в элементе отрисовываются каким шрифтом в стеке шрифтов для этого элемента.

Это осложняется тем фактом, что в браузерах есть пользовательские настройки для шрифтов с засечками / без засечек / моноширинных шрифтов, а также у них есть собственные жестко закодированные резервные шрифты, которые они будут использовать, если глиф не найден ни в одном из шрифтов в стек шрифтов. Таким образом, браузер может отображать некоторые глифы шрифтом, которого нет в стеке шрифтов или в настройках шрифта браузера пользователя.Инструменты разработчика Chrome покажут вам каждый отрисованный шрифт для глифов в выбранном элементе.. Таким образом, на своей машине вы можете видеть, что она делает, но нет никакого способа узнать, что происходит на машине пользователя.

Также возможно, что система пользователя может сыграть в этом роль, например, Окно выполняет замену шрифта на уровне глифов.

так...

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

Если вы хотите протестировать его в JS, вы можете визуализировать отдельные глифы с помощью семейства шрифтов, включая Adobe Blank, и измерить их ширину, чтобы увидеть, равна ли она нулю, НО, вам придется тщательно перебирать каждый глиф и каждый шрифт, который вы хотели протестировать, но хотя вы можете знать шрифты в стеке шрифтов элементов невозможно узнать, какие шрифты настроен для использования браузером пользователя, поэтому по крайней мере для некоторых из ваших пользователей список шрифтов, которые вы просматриваете, будет неполным. (Это также не является залогом будущего, если новые шрифты появятся и начнут использоваться.)

Другие вопросы по теме