웹폰트 사용하기 (웹폰트 101)

Posted by in Research

1. 웹폰트란?

웹 폰트는, 방문자의 로컬 컴퓨터에 서비스 제공자가 원하는 서체가 없을 경우, 온라인의 특정 서버에 위치한 서체 파일을 내려받아 화면에 표현할 수 있도록 해주는 웹 전용 서체입니다. 이 새로운 CSS3 규약을 사용하면 원하는 서체 스타일시트의 @font-face에 등록하고, font-family 속성을 통해 문서 안에서 자유롭게 사용할 수 있습니다.

2. 웹폰트를 사용하기 위해 알아야하는 속성

2-1. @font-face 기본 규칙

위의 코드는 웹폰트를 사용하는 기본적인 방법이며, NanumGothic체를 웹폰트로 사용하기 위한 예제입니다.

2-2. @font-face 속성 설명

  • font-family : CSS 문서에서 사용할 서체 이름입니다.
  • src: src를 통해 로컬 컴퓨터에 설치 된 서체의 경로를 적는 local()과, 온라인상의 서체 주소를 적는 url()이 사용됩니다. 콤마(,)로 나누어 명시하며 여러번 중첩하여 사용할 수 있으며, 마지막에 오는 속성은 세미콜론(;)으로 마무리합니다.
  • local: 방문자의 컴퓨터에서 해당 폰트의 서체가 있는지 찾습니다. 첫번째 local(NanumGothic)에서 서체를 찾지 못하면 다음 local(NanumGothic-Regular)에서 서체를 찾습니다.
  • url: 만일 방문자의 컴퓨터에 로컬 폰트가 없다면 해당 폰트 파일(NanumGothic-Regular.ttf)을 내려받습니다. format부분은 참조 할 서체의 파일 포맷을 명시한 부분입니다. 웹 브라우저는 이 포맷을 통해 자기가 지원할 수 있는 파일만 다운로드 받는데 만약 파일 포맷을 명시하지 않고 url만 적을 경우, 사용중인 웹 브라우저가 화면에 표현도 못할 서체 파일까지 다운로드 받을 수 있습니다.
    • 포맷을 넣지 않았을 때:
    • 포맷을 넣었을 때:
  • font-style, font-weight: 폰트가 가지게 될 스타일과 굵기를 정합니다. 서체 이름을 하나로 하고 여러개의 스타일을 표현하고자 할 때 사용합니다.
위 처럼 사용하면 서체는 NanumGothic 하나지만 font-weight를 달리 줌으로써 폰트를 바꿀 수 있게 됩니다.
나눔고딕의 font-weight는 300, 400, 700, 900으로 정의되어 있습니다.
font-weight 200, 600속성이 없는데 코드에 font-weight: 200과 font-weight:600을 주면 어떻게 될까요?
만약 정확히 주어진 가중치를 사용할 수 없다면 실제로 렌더링 되는 가중치를 결정하기 위해 다음과 같은 경험적 접근이 적용 됩니다.(https://developer.mozilla.org/en/docs/Web/CSS/font-weight)

  • 만약 500 초과의 가중치가 주어지면, 가능한 굵은 가중치 중 가장 가까운 것이 사용된다.(만약 없다면 얇은 가중치 중 가까운 것)

  • 만약 400 미만의 가중치가 주어진다면, 가능한 얇은 가중치 중 가장 가까운 것이 사용된다.(만약 없다면 굵은 가중치 중 가까운 것)

  • 만약 가중치가 400이 주어지면, 500이 사용되고 500이 불가능하면 500 미만의 폰트 가중치를 위한 경험적 접근이 사용됩니다.

  • 만약 가중치가 500이 주어지면, 400이 사용되고 400이 불가능하면 400 미만의 폰트 가중치를 위한 경험적 접근이 사용됩니다.

위의 설명에 따르면 font-weight: 200은 얇은 가중치 중 가장 가까운 300 으로 적용이 되며, font-weight: 600은 굵은 가중치 중 가장 가까운 700으로 적용됩니다.

Browser support
Firefox3 는,

  • 해당 폰트가 OpenType폰트일떄, font-weight 프로퍼티를 모두 지원합니다.
  • 폰트가 True type font일 때, Firefox3는 100-500을 normal로 렌더링하고, 600~900을 bold로 렌더링합니다.
  • bold type이 지원되지 않을때는 normal 폰트의 획폭(stroke width)을 증가시키는 방식으로 그려 bold처럼 보이게합니다.

IE6,7와 Opera 9.6 은,

  • weight:600이 지원되는 폰트라 하더라도 적용되지 않는 버그가 있습니다.
  • 이 버그를 제외하고는 Firefox3와 같은 방식으로 렌더링합니다.

Safari 3.2 는,

  • 지원가능한 typeface에 상관없이 100-500을 normal로, 600-900을 bold로 렌더링합니다.
  • 결과적으로 Safari3.2는 font-weight 프로퍼티를 부분적으로만 지원합니다.

2-3. 문제가 있는 local 속성

웹 폰트를 참조하기 전에 방문자의 컴퓨터에 설치 된 서체를 찾아 표현하는 local() 속성에 문제가 있습니다.

  • 로컬 서체를 로딩조차 못하는 웹 브라우저들이 존재한다.(IE6~8)
  • 운영체제별로 참조하는 로컬 서체의 이름이 다르다.

이 문제는 서체의 포맷 즉 OTF, TTF의 파일 포맷과 연관이 있고, 이 포맷에서 사용하는 Post Script Name, TTF Name과 같은 다양한 이름, 거기에 다국어 이름에 대한 웹 브라우저별 지원 여부까지 얽혀있습니다.

이렇다 보니 local() 속성을 사용하지 않고 url() 속성으로만 웹폰트를 표현하는 경우가 많습니다. 혹은 local() 속성에 ※와 같은 사용자 시스템에 존재하지 않을만한 글꼴을 임의로 지정해서 사용합니다.
굳이 2 byte 짜리 특수문자를 사용한 이유는 MAC OS에서 2 byte 짜리 문자열로 된 시스템 글꼴 이름은 아예 처리하지 않기 때문입니다. 넣지 않는다고 규칙에 위배되거나 오작동을 일으키지는 않습니다.

2-4. 브라우저별 대응 방법

위의 사진을 보면 각 브라우저마다 지원하는 파일종류가 다르다는 것을 알 수 있습니다. 위에서 언급했던 파일 포맷이 여기에 관련이 있습니다. 위의 코드를 기본적으로 하고 각 브라우저별 대응 코드를 추가하겠습니다.

2-4-1. IE 6~8 대응

IE 6~8은 EOT 파일만 지원하므로 EOT 파일을 내려받도록 해야합니다. IE 6~8은 format(’embedded-opentype’)와 같은 포맷명을 해석하지 못하기 때문에 자기가 포함 된 src의 다른 서체까지 모두 내려받으려고 시도하지만, EOT 포맷 외에는 해석을 못하므로 서체를 불러오지 못하거나 404 Not found가 발생하곤 합니다. 그래서 파일명 뒤에 물음표(?)를 추가해서 이후의 구문은 쿼리문으로 인식하여 해석하지 못하게끔 속임수를 사용합니다.

  • format(’embedded-opentype’)과 같이 해석도 못할 포맷명을 굳이 물음표 뒤에 적을 필요가 있겠냐만은, 다른 웹 브라우저들이 EOT 파일의 포맷을 해석하고 다운로드 하지 않도록 하기 위함입니다. 하지만 대부분의 모던 브라우저들은 IE의 포맷명이 정의되어 있지 않은 상황에서도 EOT 파일은 다운로드 하지 않기 때문에, 그저 @font-face 규칙을 따르는 의미 정도로 여겨집니다.
  • IE 6~8에서 local속성을 인식하지 못한다는 특징 이용하여 아래와 같이 사용할 수도 있습니다.

2-4-2. IE 9 이상 및 IE 9 호환성 보기 모드 대응

IE 9 이상부터는 EOT와 함께 WOFF 포맷도 해석할 수 있게 됐습니다. 하지만 IE의 호환성 보기 모드(Compatible Mode)에서는 이전에 사용한 물음표 속임수를 사용할 수 없게 됐습니다. 물음표가 추가된 EOT 파일은 아예 인식이 되지 않도록 문서 모드가 수정됐기 때문입니다. 이럴 경우, 인식도 안될 EOT 구문이 다른 포맷들과 함께 src 속성에 묶여있으면 다른 포맷을 다운받기 위한 시도를 하기 때문에, 아예 src를 따로 구분하여 별도 정의해 줍니다.

2-4-3. 모던 브라우저 대응

W3C의 표준을 비교적 빠르게 잘 반영하는 웹 브라우저 들은 WOFF를 지원합니다.

2-4-4. 일부 구 버전 모바일용 웹 브라우저 대응

WOFF나 TTF 포맷을 지원하지 않던 몇몇 구 버전 모바일 웹 브라우저(예를들어 Safari 4.3 이하, Android 4.3 이하, Opera Mobile 10 이하 등)들을 위해 CSS2에서 폰트로 활용할 수 있도록 명시 된 SVG(Scalable Vector Graphics) 포맷을 이용하기도 합니다. 본래 백터 이미지를 표현하는 포맷이지만, 이미지의 크기가 품질에 관여하지 않기 때문에 서체를 표현하는 용도로도 사용하는 것이죠.

SVG 포맷의 서체는 하나의 파일 안에 여러 서체를 넣고 ID(ex. #NanumGothicRegular)를 부여하여 개별적으로 호출 할 수 있고, SVG Viewer가 탑재된 모든 기기에서 표현 할 수 있는 장점이 있지만, 서체에 대한 폰트 힌팅 정보가 없기 때문에 작은 글씨를 표현할 때 가독성이 떨어지는 단점도 있습니다.

힌팅이란?
윤관선 글자 정보에 약간의 힌트(hint)를 주어 폰트를 비트맵으로 변환할 때 그 힌트를 이용하여 글자의 변형이나 왜곡 없이 더 나은 출력 결과를 얻게 만든다는 의미에서 붙여진 용어 입니다. 즉, 모니터상에서 글씨가 보다 뚜렷하게 보이게끔 글자 스스로 약간 글모양을 변형시키는 기술 입니다.

첫번째 줄 ‘활’은 힌팅이 적용되지 않은 폰트인데 확대했을 때 깨져 보이는 부분이 있지만 두번째 줄 ‘활’은 힌팅이 적용되어있고 확대 했을 때 깨짐이 덜합니다.

2-4-5. 미래 브라우저 대응

WOFF1.0 버전에 비해 평균 30%정도 압축 형식을 제공(경우에 따라 최대 50%)하는 WOFF2를 추가합니다.

2-4-6 정리

현재 뮤직 서비스에서 사용하고 있는 코드 입니다.(구버전 모바일 브라우저 대응을 위한 .svg는 삭제되었습니다)

위의 코드를 가지고 브라우저별로 접속했을 때 어떤 폰트가 다운로드 되는지 알아보겠습니다.

  1. IE 6~8 로 접근하면 NanumSquareR.eot? 가 다운로드 됩니다.
  2. IE 호환성 보기 로 접근하면 NanumSquareR.eot 가 다운로드 됩니다.
  3. IE 9이상 으로 접근하면 NanumSquareR.eot? 가 다운로드 됩니다.
    • 만약 url(../webfont/NanumSquare/NanumSquareR.eot?#iefix) format('embedded-opentype')  부분을 local("☺")  로 바꾸면 NanumSquareR.woff가 다운로드 됩니다.
  4. Chrome, Safari 등 다른 표준 브라우저 로 접근할 때는 NanumSquareR.woff가 다운로드 됩니다.

아래의 코드는 모든 브라우저를 대응하고 IE에서 eot 파일이 아닌 woff 파일을 로드받을 수 있게 하는 코드입니다.

3. 웹폰트를 적용하는 방법

3-1. 서버에 직접 업로드 하는 경우

3-2. 구글 웹폰트를 사용하는 경우

4. 로컬 서버 vs 구글 웹폰트 로드 차이

예상했던 대로 로컬서버에서 파일을 로드하는게 더 빠릅니다.
로컬서버에서 불러올 때:

구글에서 불러올 때:

하지만 티스토리와 같이 폰트를 서버에서 올릴 수 없을 경우 구글 웹폰트를 로드해서 사용할 수 있습니다.

5. 구글 웹폰트를 빠르게 로드하는 팁

  • HEAD 파일에서 CSS보다 더 빠르게 로드 해야 합니다.
  • 참조링크를 사용합니다.
    • 가져다 사용하는 경우는 css내에서 @import방법, 참조링크를 사용하는 방법, 자바스크립트를 이용하는방법 3가지가 있는데 참조링크를 이용하면 HTML의 최상위에 코드를 넣을 수 있으며, CSS 파일보다 더 빠르게 로드될 수 있습니다. @import 코드는 CSS 파일안에 넣어야 하는데 이는 스타일 되지 않은 텍스트가 번쩍거리는 현상을 일으킬 수 있습니다.(flash of unstyled text:FOUT)
  • 적은 폰트를 로드 해야 합니다.
  • 표제를 위한 볼드타입과 기사를 위한 가독성이 좋은 폰트(최대 2개의 폰트)를 선정하는 것이 좋습니다.
    • 폰트는 많을 수록 로딩 시간이 더 길어집니다.
  • 폰트 로드 코드를 결합해서 사용합니다
    • 코드 한 줄에 여러 구글 폰트를 로드할 수 있습니다. 로드하려는 각 폰트마다 한 줄 코드를 넣을 필요가 없습니다. Open Sans와 Oswald 폰트를 사용하고 싶으면 아래 처럼 한 줄에 적으면 좋습니다.
폰트의 기본 옵션을 로드하는 것이 좋습니다.

  • 한 가지 옵션만 선택했을 때:

  • 많은 옵션을 선택했을 때:

  • 구글에서 제공하는 Google Webfont Loader를 사용합니다.

6. 웹폰트를 사용하지 않는 이유

6.1 IE브라우저에서 깜빡거리는 현상(FOUC – Flash Of Unstyled Content)발생

웹폰트파일이 완전히 로드되기 전까지 기본서체(굴림)가 노출되었다가, 웹폰트가 로드 완료되면 웹폰트(나눔스퀘어체)로 바뀝니다. 화면이 움찔되는듯 보일 수 있으며, 글자가 클수록 도드라져 보입니다.

FOUC 현상 발생 샘플페이지 https://codepen.io/witblog/full/WRLzBx/

6.1.1 해결방법 – fontfaceobserver.js 사용

위의 현상은 웹폰트를 적용하지 않는 대표적인 이유 중 한 가지인데요. 이는 스크립트를 통해 어느정도 개선이 가능합니다. 잘 알려진 fontfaceobserver.js를 적용했을 때 결과입니다.(“MP3 30곡” 텍스트를 제외한 나머지만 적용되어 있습니다.) 지원브라우저: Chrome, FireFox, Opera, Safari, IE8+, Android WebKit

스크립트 적용 url: http://codepen.io/witblog/full/JEwZWG/
이미지로 적용했을 때와 많은 차이가 없습니다.

해결방안은 웹폰트가 로드되기 전에는 텍스트를 미노출 시켰다가(기본서체가 미노출되도록) 웹폰트가 완전히 로드된 후 노출시키는 방식입니다.
적용 방식은 다음과 같습니다.

웹폰트가 로드되기 전, 웹폰트가 로드된 후 적용할 스타일을 추가합니다.

폰트가 로드되었는지 체크해주는 스크립트를 추가합니다.

6.1.2 해결방법 – Google Webfont Loader 사용

  • 구글 웹폰트를 로드 할 때는 구글에서 제공하는 Google Webfont Loader를 사용하여 FOUC 현상을 막을 수 있습니다.
웹폰트 로더를 사용할 때 :

웹폰트 로더를 사용하지 않을 때(FOUT 현상):

웹폰트 로더 적용 방법

  • loading: 모든 폰트에 대해 요청중이다.
  • active: 모든 폰트가 랜더링 되었다.
  • inactive: 폰트가 브라우저에서 지원이 되지 않거나 로드가 되지 않았다.
  • fontloading: 특정 한 폰트가 로딩중이다.
  • fontactive: 특정 한 폰트가 랜더링 되었다.
  • fontinactive: 특정 한 폰트가 로드되지 않았다.

fontloading, fontactive, fontinactive는 폰트가 여러개 일 때 순차적으로 붙고 loading, active, inactive는 전체 폰트에 대해서 한 번만 붙습니다.
예를 들어, droid sans와 droid sans-serif 폰트를 로드하게 되면 아래와 같이 클래스가 적용됩니다.

이를 통해서 구글 웹폰트 로더를 사용하면 구글 웹폰트로 로드되는 시간동안 변화를 체크하여 웹폰트를 사용한 곳만 숨김처리 하거나, 전체를 숨김처리 한 후 보여줄 수 있는 코드를 작성할 수 있습니다.

6.2 웹폰트의 용량이 커서 성능에 문제가 있다.

실제로 이미지폰트를 많이 사용하지 않는 경우에는 웹폰트를 사용하는 것보다 이미지 폰트를 사용하는 것이 좋습니다.

  • 이미지폰트 적용 페이지: 이미지 용량 136KB
  • 웹폰트 적용 페이지: 웹폰트 용량 273KB

웹폰트를 적용했을 때 137KB정도 용량이 더 크지만, 웹폰트, 이미지폰트 모두 사이트에 한 번 접속하면 캐시에 저장되고 이후에 접속할 때 마다 캐시에서 불러와 사용합니다. 그러므로 이미지폰트를 여러 페이지에 사용할 경우 이미지폰트보다 웹폰트를 사용하는 것이 효율적입니다.

예를 들어 아래 동선과 같이 여러 페이지를 이동한다고 가정했을 때를 비교해보겠습니다.
뮤직홈 → 이용권 구매 → 알뜰 이용권 자세히 보기

웹폰트 적용환경 사용자A는 뮤직홈에 처음 접속했을 때 웹폰트가 다운받아지고 캐시에 저장됩니다. 이 후 이용권 구매, 알뜰 이용권 자세히 보기 페이지에서는 캐시에 저장된 웹폰트를 불러 사용합니다.

이미지 적용환경 사용자B는 뮤직홈, 이용권 구매, 알뜰 이용권 자세히 보기 에서 이미지파일 136KB를 받기 때문에 총 408KB를 다운받게 됩니다.

이미지폰트도 캐시를 이용하지만 각 페이지에서 사용한 이미지가 모두 다른 파일이기 때문입니다.(모두 같은 이미지파일에 저장하게되면 이미지용량이 너무 커지게 됩니다.)

웹폰트를 좀 더 빠르게 로드하는 방법

6.2.1 data-uri로 웹폰트 사용하기

이미지처럼 웹 폰트도 data-uri로 사용할 수 있는데 Font Squirrel에서 제공하는 Webfont Generator를 사용하면 쉽게 data-uri로 만들어 낼 수 있습니다.

사용할 폰트 파일(TTF, OTF)를 업로드하고 Expert 옵션을 선택하여 세부사항을 선택합니다. 위의 사진에서는 WOFF만 지정했지만 TTF폰트만 있다면 다른 타입의 폰트 파일도 만들 수 있습니다. 하단의 CSS부분에서는 Base64 Encode를 지정합니다. 맨 아래 합법적인 폰트라고 체크만 해주면 다운로드받을 수 있습니다.

대표적인 성능 측정사이트 3군데에서 비교해보았습니다.

핑덤(http://tools.pingdom.com/)

  • data-uri 사용

  • data-uri 미사용

data-uri를 사용했을 때 파일크기가 약 37KB가 증가했지만 속도는 0.04초 빨랐습니다. 또한 여기서는 REQUEST가 data-uri까지 포함하여 8개로 나오지만 웹페이지에서 REQUREST 파일 수는 7로 REQUEST가 하나 줄었습니다.

GT 매트릭스(https://gtmetrix.com/)

  • data-uri 사용

  • data-uri 미사용

data-uri를 사용했을 때 파일크기가 약 37KB가 증가했지만 속도는 0.1초 빨랐습니다. REQUREST 역시 7개로 한 개 줄었습니다.

웹페이지테스트(http://www.webpagetest.org/)

  • data-uri 사용

  • data-uri 미사용

data-uri를 사용했을 때 파일크기가 약 37KB가 증가했지만 속도는 0.1초 빨랐습니다. REQUEST 역시 7개로 한 개 줄었습니다.

data-uri를 사용했을 때의 특징

  • data-uri로 접근한 이유 중 하나는 HTTP 리퀘스트 수를 줄이기 위함입니다. 웹페이지에서는 리소스를 가져오는 요청이 많이 발생하므로 CSS Sprites처럼 HTTP 요청개수를 줄여서 속도를 높이려는 것입니다. 물론 CSS Sprite처럼 다수의 요청을 하나로 만들 수 있는 것은 아니고 CSS를 받은 다음에 font를 가져오는 요청 대신 CSS를 받을 때 한꺼번에 받도록 한 것입니다.
  • 웹폰트의 용량이 큰 경우에는 가져오는데 FOUC 현상이 발생할 수 있습니다. data-uri는 한꺼번에 같이 받으므로 이러한 현상을 줄일 수 있습니다.
  • font 파일은 브라우저가 캐싱하지만, data-uri는 별도로 캐싱하지 않습니다. 그래서 data-uri를 사용할 파일(CSS)에 캐싱 정책을 주어야 합니다.
  • data-uri를 가진 파일을 캐싱하더라도 사용하려면 브라우저가 data-uri를 처리해야 하는데 이는 페이지를 열 때마다 매번 처리합니다. 그러므로 data-uri를 너무 많이 쓰는 것은 좋지 않고 사용하더라도 바이너리를 받아서 사용하는 것과 비교해서 사용해야 합니다.
  • 웹폰트를 사용하면 파이어폭스가 크로스 도메인을 허용하지 않아서 폰트가 제대로 다운로드 되지 않는 문제가 발생할 수 있습니다. CDN이나 폰트 파일을 내려주는 곳에서 CORS를 설정해야 폰트 파일이 제대로 로드되는데 data-uri를 사용하면 이런 설정 없이도 파이어폭스에서 웹 폰트를 사용할 수 있습니다.

참고: https://blog.outsider.ne.kr/1138

6.2.2 preload, prefetch 사용

preload, prefetch 를 통하여 IE11+, Chrome, Firefox, Opera, Android Webkit 에서는 웹폰트로드를 좀 더 빠르게 할 수 있습니다.
지원 브라우저
prefetch:

preload:

preload를 적용하지 않았을 때는 CSS파일 다운이 완료된 후 웹폰트를 다운받기 시작합니다.

preload를 적용했을 때는 css파일과 동시에 다운로드 받기 시작합니다.

참고: https://www.bramstein.com/writing/preload-hints-for-web-fonts.html

7. 참고문서