사용자의 브라우저가 표시 할 수있는 모든 글꼴 나열


105

브라우저가 표시 할 수있는 모든 글꼴 (또는 글꼴 계열)의 이름을 가져 오는 방법이 자바 스크립트에 있습니까? (사용자에게 사용 가능한 모든 글꼴 목록이있는 드롭 다운을 제공하고 사용자가 글꼴을 선택할 수 있도록 허용하고 싶습니다.)이 목록을 미리 하드 코딩하거나 서버에서 보내지 않아도됩니다. (직관적으로 브라우저는 어떤 글꼴이 있는지 알고 있어야하며 이는 어떻게 든 자바 스크립트에 노출되어야합니다.)

답변:


37

자바 스크립트 버전은 약간 불안정합니다. 알려진 글꼴과 테스트를 반복하여 글꼴을 얻습니다.

가장 정확한 방법 (독점 플러그인을 사용해야하지만)은 Flash사용하는 것 입니다. 여기에서 치수를 사용하여 개별적으로 테스트 할 필요없이 글꼴 목록을 가져올 수 있습니다.

일부 장치 (iDevices, Flash 플러그인이없는 브라우저 등)에서 작동하지 않는 대신 정확한 목록을 가질 것인지 아니면 JavaScript를 통해서만 더 잘 지원 되는 일부 목록 을 가질 것인지 결정해야합니다 .


30
@Jared Flash를 언급 해주 셨나요? 이것이 유일한 해결책이라고 말한 것이 아니라 글꼴을 감지하는 가장 정확한 방법이라고 언급했습니다.
alex

4
@alex 예. 개발자, 특히 새로운 개발자에게 잘못된 인상을 줄 수 있습니다. Flash 사용의 장단점을 더 잘 설명하기 위해 답변을 편집하는 것이 좋습니다. "권장되지는 않지만 ..."또는 그와 비슷한 것입니다.
Jared

19
@Jared 독자가 공예에 익숙하지 않은 경우 처음부터 정보를 제공하기 위해 모든 답변을 작성해야합니까? 플래시에는 적절한 플러그인이 필요하다고 설명했지만 현재 사용 가능한 모든 글꼴을 얻는 유일한 방법이라고도 언급했습니다 (JavaScript 메서드는 글꼴의 하위 집합 만 감지하므로 대부분의 사용 사례에 충분할 것입니다). 저도 Flash를 사용하는 것에 만족하지 않지만 지금이 작업을 위해 우리가 가진 전부입니다.
alex

7
@Jared 마지막 단락을 보셨습니까? 다시 읽으 실 수 있습니다.
alex

10
@Jared 그 단락은 항상 존재했습니다.
alex

74

네, 있습니다! 나도이 질문을 사용하고 싶기 때문에이 질문을 해주셔서 감사합니다.

질문에 +1하고 답변은 다음과 같습니다. :)

http://www.lalit.org/lab/javascript-css-font-detect

코드 에서 http://www.lalit.org/wordpress/wp-content/uploads/2008/05/fontdetect.js?ver=0.3

/**
 * JavaScript code to detect available availability of a
 * particular font in a browser using JavaScript and CSS.
 *
 * Author : Lalit Patel
 * Website: http://www.lalit.org/lab/javascript-css-font-detect/
 * License: Apache Software License 2.0
 *          http://www.apache.org/licenses/LICENSE-2.0
 * Version: 0.15 (21 Sep 2009)
 *          Changed comparision font to default from sans-default-default,
 *          as in FF3.0 font of child element didn't fallback
 *          to parent element if the font is missing.
 * Version: 0.2 (04 Mar 2012)
 *          Comparing font against all the 3 generic font families ie,
 *          'monospace', 'sans-serif' and 'sans'. If it doesn't match all 3
 *          then that font is 100% not available in the system
 * Version: 0.3 (24 Mar 2012)
 *          Replaced sans with serif in the list of baseFonts
 */

/**
 * Usage: d = new Detector();
 *        d.detect('font name');
 */
var Detector = function() {
    // a font will be compared against all the three default fonts.
    // and if it doesn't match all 3 then that font is not available.
    var baseFonts = ['monospace', 'sans-serif', 'serif'];

    //we use m or w because these two characters take up the maximum width.
    // And we use a LLi so that the same matching fonts can get separated
    var testString = "mmmmmmmmmmlli";

    //we test using 72px font size, we may use any size. I guess larger the better.
    var testSize = '72px';

    var h = document.getElementsByTagName("body")[0];

    // create a SPAN in the document to get the width of the text we use to test
    var s = document.createElement("span");
    s.style.fontSize = testSize;
    s.innerHTML = testString;
    var defaultWidth = {};
    var defaultHeight = {};
    for (var index in baseFonts) {
        //get the default width for the three base fonts
        s.style.fontFamily = baseFonts[index];
        h.appendChild(s);
        defaultWidth[baseFonts[index]] = s.offsetWidth; //width for the default font
        defaultHeight[baseFonts[index]] = s.offsetHeight; //height for the defualt font
        h.removeChild(s);
    }

    function detect(font) {
        var detected = false;
        for (var index in baseFonts) {
            s.style.fontFamily = font + ',' + baseFonts[index]; // name of the font along with the base font for fallback.
            h.appendChild(s);
            var matched = (s.offsetWidth != defaultWidth[baseFonts[index]] || s.offsetHeight != defaultHeight[baseFonts[index]]);
            h.removeChild(s);
            detected = detected || matched;
        }
        return detected;
    }

    this.detect = detect;
};

요약

어떻게 작동합니까?

이 코드는 각 문자가 서로 다른 글꼴에서 다르게 표시된다는 단순한 원칙에 따라 작동합니다. 따라서 다른 글꼴은 동일한 글꼴 크기의 동일한 문자열에 대해 다른 너비와 높이를 사용합니다.


2
매우 사악합니다. 굉장합니다.
재귀

4
고맙습니다. 예, 설치된 것을 테스트 할 글꼴 목록이 있으면 유용하지만 문제는 처음에 글꼴 이름 목록을 생성하는 방법입니다.
mattsh

43
이것은 글꼴 설치 여부에 대해서만 예 / 아니오를 제공합니다.
rektide

2
처음에는 훌륭하다고 생각했지만 몇 가지 문제를 발견했습니다. 주요 문제는 각 브라우저가 다른 결과를 반환한다는 것입니다. 확실히 신뢰할 수 없습니다.
Błażej Klisz 2013

11
흥미롭고 유용하지만 질문에 답하지 않습니다. 브라우저에서 사용할 수있는 글꼴 이름은 검색하지 않습니다. 주저하는 -1.
BenjaminGolder

12

이것을 사용하는 방법이 있습니다 document.fonts

반환 된 값은 문서의 FontFaceSet 인터페이스입니다. FontFaceSet 인터페이스는 새 글꼴을로드하고 이전에로드 된 글꼴의 상태를 확인하는 데 유용합니다.

  • 반환되는 값은 가중치, 스타일 등으로 상세합니다.
function listFonts() {
  let { fonts } = document;
  const it = fonts.entries();

  let arr = [];
  let done = false;

  while (!done) {
    const font = it.next();
    if (!font.done) {
      arr.push(font.value[0]);
    } else {
      done = font.done;
    }
  }

  return arr;
}
  • 글꼴 패밀리 만 반환
function listFonts() {
  let { fonts } = document;
  const it = fonts.entries();

  let arr = [];
  let done = false;

  while (!done) {
    const font = it.next();
    if (!font.done) {
      arr.push(font.value[0].family);
    } else {
      done = font.done;
    }
  }

  // converted to set then arr to filter repetitive values
  return [...new Set(arr)];
}

HTML의 글꼴을 연결하지 않고 테스트 한 다음 Roboto 글꼴을 연결하고 다시 테스트 한 다음 결과에 추가되었습니다.


이 코드 조각은 완벽하게 작동했습니다. 감사합니다! ```listFonts () {let fonts = document [ 'fonts']; const it = fonts.entries (); let arr = []; 하자 = 거짓; while (! done) {const font = it.next (); if (! font.done) {arr.push (font.value [0] .family); } else {완료 = font.done; }} // 반복 값을 필터링하기 위해 set로 변환 한 다음 arr로 변환 return [... new Set (arr)]; }```
rufreakde

Firefox에서 실행하면 FontAwesome과 같은 웹 글꼴 만 표시됩니다
Tim Davis

5
<SCRIPT>
    function getFonts()
    {
        var nFontLen = dlgHelper.fonts.count;
        var rgFonts = new Array();
        for ( var i = 1; i < nFontLen + 1; i++ )
            rgFonts[i] = dlgHelper.fonts(i); 

        rgFonts.sort();
        for ( var j = 0; j < nFontLen; j++ )
            document.write( rgFonts[j] + "<BR>" );
    }
</SCRIPT>

<BODY onload="getFonts()">
<OBJECT id=dlgHelper CLASSID="clsid:3050f819-98b5-11cf-bb82-00aa00bdce0b" width="0px" height="0px">
</OBJECT>

2
@Robert Sköld, 네, IE 전용으로 보입니다. 여러 목적에 여전히 유용하지만, 진지하게 사용할 경우 다른 브라우저를 사용하는 사람들이 이해할 수 있도록 몇 가지 기능 감지 기능이 있어야합니다. 예를 들어, 참조 cs.tut.fi/~jkorpela/listfonts1.html
유카 K. 펠라

Windows Phone 용 IE11에서는 작동하지 않습니다. Windows Phone 용으로 추가해야 할 다른 것이 있습니까 ???
jats 2008-08-26

4

FontFaceSet.check () 솔루션

  • 사용 가능한 모든 글꼴을 감지하는 것은 일반적인 브라우저 핑거 프린팅 기술이므로 목록을 직접 반환하는 JS API가 추가 될 가능성은 거의 없습니다.
  • FontFaceSet.check () 지원은 사용하기에 충분하지만 이전 브라우저의 경우이 답변 과 같은 대체가 필요 합니다.
  • 다음 글꼴 목록을 확인하는 데는 150ms 이상이 걸리므로 필요한 경우에만 실행하고 결과를 캐시하면됩니다.

Windows 10 글꼴 목록

'Arial',
'Arial Black',
'Bahnschrift',
'Calibri',
'Cambria',
'Cambria Math',
'Candara',
'Comic Sans MS',
'Consolas',
'Constantia',
'Corbel',
'Courier New',
'Ebrima',
'Franklin Gothic Medium',
'Gabriola',
'Gadugi',
'Georgia',
'HoloLens MDL2 Assets',
'Impact',
'Ink Free',
'Javanese Text',
'Leelawadee UI',
'Lucida Console',
'Lucida Sans Unicode',
'Malgun Gothic',
'Marlett',
'Microsoft Himalaya',
'Microsoft JhengHei',
'Microsoft New Tai Lue',
'Microsoft PhagsPa',
'Microsoft Sans Serif',
'Microsoft Tai Le',
'Microsoft YaHei',
'Microsoft Yi Baiti',
'MingLiU-ExtB',
'Mongolian Baiti',
'MS Gothic',
'MV Boli',
'Myanmar Text',
'Nirmala UI',
'Palatino Linotype',
'Segoe MDL2 Assets',
'Segoe Print',
'Segoe Script',
'Segoe UI',
'Segoe UI Historic',
'Segoe UI Emoji',
'Segoe UI Symbol',
'SimSun',
'Sitka',
'Sylfaen',
'Symbol',
'Tahoma',
'Times New Roman',
'Trebuchet MS',
'Verdana',
'Webdings',
'Wingdings',
'Yu Gothic',

macOS / iOS 글꼴 목록

'American Typewriter',
'Andale Mono',
'Arial',
'Arial Black',
'Arial Narrow',
'Arial Rounded MT Bold',
'Arial Unicode MS',
'Avenir',
'Avenir Next',
'Avenir Next Condensed',
'Baskerville',
'Big Caslon',
'Bodoni 72',
'Bodoni 72 Oldstyle',
'Bodoni 72 Smallcaps',
'Bradley Hand',
'Brush Script MT',
'Chalkboard',
'Chalkboard SE',
'Chalkduster',
'Charter',
'Cochin',
'Comic Sans MS',
'Copperplate',
'Courier',
'Courier New',
'Didot',
'DIN Alternate',
'DIN Condensed',
'Futura',
'Geneva',
'Georgia',
'Gill Sans',
'Helvetica',
'Helvetica Neue',
'Herculanum',
'Hoefler Text',
'Impact',
'Lucida Grande',
'Luminari',
'Marker Felt',
'Menlo',
'Microsoft Sans Serif',
'Monaco',
'Noteworthy',
'Optima',
'Palatino',
'Papyrus',
'Phosphate',
'Rockwell',
'Savoye LET',
'SignPainter',
'Skia',
'Snell Roundhand',
'Tahoma',
'Times',
'Times New Roman',
'Trattatello',
'Trebuchet MS',
'Verdana',
'Zapfino',

FontFaceSet.check ()

const fontCheck = new Set([
  // Windows 10
'Arial', 'Arial Black', 'Bahnschrift', 'Calibri', 'Cambria', 'Cambria Math', 'Candara', 'Comic Sans MS', 'Consolas', 'Constantia', 'Corbel', 'Courier New', 'Ebrima', 'Franklin Gothic Medium', 'Gabriola', 'Gadugi', 'Georgia', 'HoloLens MDL2 Assets', 'Impact', 'Ink Free', 'Javanese Text', 'Leelawadee UI', 'Lucida Console', 'Lucida Sans Unicode', 'Malgun Gothic', 'Marlett', 'Microsoft Himalaya', 'Microsoft JhengHei', 'Microsoft New Tai Lue', 'Microsoft PhagsPa', 'Microsoft Sans Serif', 'Microsoft Tai Le', 'Microsoft YaHei', 'Microsoft Yi Baiti', 'MingLiU-ExtB', 'Mongolian Baiti', 'MS Gothic', 'MV Boli', 'Myanmar Text', 'Nirmala UI', 'Palatino Linotype', 'Segoe MDL2 Assets', 'Segoe Print', 'Segoe Script', 'Segoe UI', 'Segoe UI Historic', 'Segoe UI Emoji', 'Segoe UI Symbol', 'SimSun', 'Sitka', 'Sylfaen', 'Symbol', 'Tahoma', 'Times New Roman', 'Trebuchet MS', 'Verdana', 'Webdings', 'Wingdings', 'Yu Gothic',
  // macOS
  'American Typewriter', 'Andale Mono', 'Arial', 'Arial Black', 'Arial Narrow', 'Arial Rounded MT Bold', 'Arial Unicode MS', 'Avenir', 'Avenir Next', 'Avenir Next Condensed', 'Baskerville', 'Big Caslon', 'Bodoni 72', 'Bodoni 72 Oldstyle', 'Bodoni 72 Smallcaps', 'Bradley Hand', 'Brush Script MT', 'Chalkboard', 'Chalkboard SE', 'Chalkduster', 'Charter', 'Cochin', 'Comic Sans MS', 'Copperplate', 'Courier', 'Courier New', 'Didot', 'DIN Alternate', 'DIN Condensed', 'Futura', 'Geneva', 'Georgia', 'Gill Sans', 'Helvetica', 'Helvetica Neue', 'Herculanum', 'Hoefler Text', 'Impact', 'Lucida Grande', 'Luminari', 'Marker Felt', 'Menlo', 'Microsoft Sans Serif', 'Monaco', 'Noteworthy', 'Optima', 'Palatino', 'Papyrus', 'Phosphate', 'Rockwell', 'Savoye LET', 'SignPainter', 'Skia', 'Snell Roundhand', 'Tahoma', 'Times', 'Times New Roman', 'Trattatello', 'Trebuchet MS', 'Verdana', 'Zapfino',
].sort());

(async() => {
  await document.fonts.ready;

  const fontAvailable = new Set();

  for (const font of fontCheck.values()) {
    if (document.fonts.check(`12px "${font}"`)) {
      fontAvailable.add(font);
    }
  }

  console.log('Available Fonts:', [...fontAvailable.values()]);
})();


감사합니다 이것은 내가 너무 많은 CPU를 채우지 않는 방식으로 콘텐츠를 표시하거나 페이지를 구문 분석하는 데 많은 유연성을 얻기 위해 로컬 시스템 글꼴을 따라 최종 웹 디자인을 찾고 있습니다
Constantin

3

이를 검색 할 때 Image와 매우 유사한 Font 객체를 추가하는 Font.js 도 발견 했습니다 . 따라서 실제로 글꼴을 사용할 준비가되었는지 확인할 수 있습니다. 설치된 / 시스템 글꼴에서도 작동합니다. 단점은 IE9 +가 필요하기 때문에 Object.defineProperty(다른 브라우저에 있음)이지만 최신 웹을 사용하는 경우 더 나은 옵션처럼 보입니다. (슬프게도 위의 답변으로 가야하고, upvoted하고 지금은 계속 진행해야합니다. :))


3

위의 Lalit Patel의 Detector에 두 가지 방법을 추가했습니다.

  • addFont (family, stylesheetUrl, ruleString)-> 'family'글꼴이 존재하는지 감지합니다. 그렇지 않은 경우 stylesheetUrl (제공된 경우) 또는 ruleString을 사용하여 글꼴을로드하는 스타일 시트를 추가합니다.
  • addFontsArr (arr)-> 글꼴 배열 추가

이를 통해 다음을 수행 할 수 있습니다.

fonts = [ 'Arial', 'Arial Black', { family: 'Lato', stylesheetUrl: 'https://fonts.googleapis.com/css?family=Lato'}, 'Leelawadee UI']
(new FontDetector()).addFontsArr(fonts);

암호:

/**
 * JavaScript code to detect available availability of a
 * particular font in a browser using JavaScript and CSS.
 *
 * Author : Lalit Patel
 * Website: http://www.lalit.org/lab/javascript-css-font-detect/
 * License: Apache Software License 2.0
 *          http://www.apache.org/licenses/LICENSE-2.0
 * Version: 0.15 (21 Sep 2009)
 *          Changed comparision font to default from sans-default-default,
 *          as in FF3.0 font of child element didn't fallback
 *          to parent element if the font is missing.
 * Version: 0.2 (04 Mar 2012)
 *          Comparing font against all the 3 generic font families ie,
 *          'monospace', 'sans-serif' and 'sans'. If it doesn't match all 3
 *          then that font is 100% not available in the system
 * Version: 0.3 (24 Mar 2012)
 *          Replaced sans with serif in the list of baseFonts
 */

/**
 * Usage: d = new Detector();
 *        d.detect('font name');
 */
function FontDetector() {
    this.detect = detect;
    this.addFont = addFont;
    this.addFontsArr = addFontsArr;

    // a font will be compared against all the three default fonts.
    // and if it doesn't match all 3 then that font is not available.
    var baseFonts = ['monospace', 'sans-serif', 'serif'];

    //we use m or w because these two characters take up the maximum width.
    // And we use a LLi so that the same matching fonts can get separated
    var testString = "mmmmmmmmmmlli";

    //we test using 72px font size, we may use any size. I guess larger the better.
    var testSize = '72px';

    var h = document.getElementsByTagName("body")[0];

    // create a SPAN in the document to get the width of the text we use to test
    var s = document.createElement("span");
    s.style.fontSize = testSize;
    s.innerHTML = testString;
    var defaultWidth = {};
    var defaultHeight = {};
    for (var index in baseFonts) {
        //get the default width for the three base fonts
        s.style.fontFamily = baseFonts[index];
        h.appendChild(s);
        defaultWidth[baseFonts[index]] = s.offsetWidth; //width for the default font
        defaultHeight[baseFonts[index]] = s.offsetHeight; //height for the defualt font
        h.removeChild(s);
    }

    function detect(font) {
        var detected = false;
        for (var index in baseFonts) {
            s.style.fontFamily = font + ',' + baseFonts[index]; // name of the font along with the base font for fallback.
            h.appendChild(s);
            var matched = (s.offsetWidth != defaultWidth[baseFonts[index]] || s.offsetHeight != defaultHeight[baseFonts[index]]);
            h.removeChild(s);
            detected = detected || matched;
        }
        return detected;
    }

    function addFont(family, stylesheetUrl, ruleString) {
        if (detect(family)) {
            //console.log('using internal font '+family);
            return true;
        }
        if (stylesheetUrl) {
            console.log('added stylesheet '+stylesheetUrl);
            var head = document.head, link = document.createElement('link');
            link.type = 'text/css';
            link.rel = 'stylesheet';
            link.href = stylesheetUrl;
            head.appendChild(link);
            return true;          
        }

        if (ruleString) {
            console.log('adding font rule:'+rule);
            var newStyle = document.createElement('style');
            newStyle.appendChild(document.createTextNode(rule));
            document.head.appendChild(newStyle);
            return true;
        }

        console.log('could not add font '+family);
    }

    function addFontsArr(arr) {
        arr.forEach(a => typeof a==='string' ? addFont(a) : addFont(a.family, a.stylesheetUrl, a.ruleString));
    }
};

2

특정 문자에 대해 알려진 글꼴 이미지가있는 스프라이트 시트를 사용하고 브라우저가 동일한 글꼴로보고하는 것과 동일한 문자가 그려지는 캔버스 요소의 스냅 샷과 비교하여 완전히 다른 방식으로 수행 할 수 있습니다. 비교는 resemble.js 와 같은 것으로 수행 될 수 있습니다 .

속도는 느리지 만 브라우저가 거짓말을 할 때 감지 할 수 있어야합니다.


2

짧은 대답입니다. Flash를 사용하는 것이 이제 더 나쁜 생각이라는 점을 제외하고는 2020 년 브라우저의 글꼴 감지와 관련하여 많이 변경되지 않았습니다 .

현재 사용 가능한 모든 글꼴을 "나열"하는 브라우저 기본 시스템은 없습니다. 그러나 브라우저에서는 FontFaceSet API를 사용하여 글꼴이로드 / 준비되었는지 확인할 수 있습니다 . 최신 브라우저에서 꽤 잘 지원됩니다.

이것은 웹 글꼴이 완전히 다운로드되었는지 표시하기위한 것이지만 시스템 글꼴에서도 작동합니다. 문제는 확인할 글꼴 목록을 제공해야한다는 것 입니다.

따라서 user agent 테스트 (항상 정확하지는 않음) 와 함께 각 장치 유형에 대한 공통 시스템 글꼴 목록을 생성 할 수 있습니다 . 그런 다음로드 한 웹 글꼴과 웹 글꼴에 대해 테스트합니다.

참고 : 사용 가능한 글꼴의 전체 목록을 제공하지는 않지만 MS Office 또는 Adobe 제품에서 일반적으로 설치하는 글꼴을 확인할 수 있습니다.


0

최근에 HTML5 캔버스의 context.font 값을 "정크"와 같은 잘못된 값으로 설정하면 변경 사항이 캔버스에서 무시된다는 사실을 알게되었습니다. 이것이 브라우저에 특정한 것인지는 모르겠지만 Chrome에서 이런 식으로 작동하는 것 같습니다. 나는 또한 다른 브라우저에서 발생한다는 것을 나타내는 다른 게시물 ( HTML 5 canvas font being ignore )을 보았습니다 .

그런 다음 "10px sans serif"( https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/font ) 라고 생각되는 기본값으로 문자열을 작성 하고 글꼴을 설정할 수 있습니다. 테스트중인 사람에게 문자열을 다시 씁니다. 첫 번째 도면과 동일한 경우 글꼴을 사용할 수 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.