CSS font-family 권장 사항
(chrismorgan.info)- 웹에서 특정 폰트 이름을 믿고 디자인하면 플랫폼·네트워크·보안 설정에 따라 깨질 수 있어, 일반 계열 fallback을 전제로
font-family를 짜야 함 - 고정폭 표현이 필요한 코드·아트워크·레이아웃에는
monospace를 반드시 포함해야 하며,serif와sans-serif도 원하는 계열을 보장하려면 함께 지정하는 편이 안전함 - 로컬에 있을 법한 폰트를 길게 나열하는 스택은 대개 실익이 작고, 브라우저의 일반 계열 기본값이 더 나은 선택을 할 가능성도 있음
- 웹 폰트는 없는 경우보다 느리고 로딩 실패·
font-display절충을 만들기 때문에, 콘텐츠에는 사용자의 기본 폰트를 그대로 쓰는 선택도 현실적임 system-ui와ui-*는 짧은 UI 텍스트 성격이 강해 긴 콘텐츠와 언어 지원에 맞지 않을 수 있으며, 콘텐츠용 기본 폰트 대체 수단으로 쓰기엔 위험함
폰트 이름을 신뢰하지 않기
- 모든 주요 플랫폼에서 공통으로 제공되는 웹 안전 폰트는 없으므로, 특정 폰트 이름이 항상 동작한다고 가정하면 안 됨
- 웹 폰트도 확실한 해법은 아님
- 인라인되지 않은 하위 리소스는 여러 네트워크 이유로 로드에 실패할 수 있음
- 폰트 로딩은 보안 우려가 있는 영역이라 일부 환경에서 차단될 수 있음
- uBlock Origin에는 원격 폰트를 비활성화하는 전용 버튼이 있음
- 일부 브라우저의 데이터 절약 모드는 폰트 로딩을 막을 수 있으며, 막지 않는 경우도 막아야 한다는 입장임
- 사용자가 웹사이트의 자체 폰트 선택을 허용하지 않으면 일반 계열만 동작함
- JavaScript에서
document.fonts.load("1em my-web-font")를 쓰면 반환되는 Promise가 reject될 수 있음- 2020–2025년 6년 동안 이 문제로 깨진 사례를 약 4개 봤고, 그중 2개는 2025년에 발생함
대체 계열은 반드시 명시하기
- 고정폭 텍스트가 필요하면
font-family에 반드시monospace를 넣어야 함monospace누락은 많은 사용자에게 드러나지 않지만, 일부 환경에서는 레이아웃이나 작품의 의도를 망칠 수 있음- 예시로 Adel Faure의 ASCII might fly?는 작성 시점에
monospace가 빠져 있어 고정폭이 아닌 형태로 보일 수 있음
serif나sans-serif도 원하는 폰트 계열의 fallback이 필요하면 포함하는 편이 좋음- 예:
font-family: Arial, sans-serif; - 예:
font-family: Times New Roman, serif; - 넣지 않으면 기본 폰트를 쓰게 되며, 기본 폰트는 serif일 수도 있지만 전혀 다른 것일 수도 있음
- 예:
설치됐을 법한 폰트 나열 줄이기
Arial,Helvetica,Helvetica Neue,Liberation Sans,Noto Sans처럼 시스템에 있을 법한 폰트를 길게 나열하는 방식은 대체로 도움이 되지 않음- 특히 Arial은
sans-serif보다 더 나은 선택이 될 일이 없다고 봄 sans-serif는 명시한 폰트들보다 나쁘지 않은 폰트로 해석될 수 있고, 더 나은 폰트가 선택될 가능성도 있음- 실제로 본 고정폭 선언 예시는 과도하게 긴 목록임
font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif- 이 선언은
font-family: monospace, monospace보다 엄격히 나쁘며,monospace는 이 목록보다 나쁘지 않은 폰트로 해석될 수 있음
- 이름 있는 비웹 폰트를 완전히 금지할 필요는 없지만, 최대 하나 정도가 적절함
- Georgia)와 Times New Roman은 모두 Microsoft의 Core fonts for the Web에 속한 serif지만 성격이 다름
- Georgia는 Times New Roman보다 훨씬 넓으므로, 스타일상 그 특성이 필요하면
font-family: Georgia, serif는 허용 가능한 선택임
- modernfontstacks.com과 저장소는 플랫폼별 폰트 선택 아이디어를 담고 있음
- 다만 명명된 폰트를 지나치게 처방하며, 상당수는 제거하는 편이 낫다는 평가임
- Courier New 처리는 크게 잘못됐고, 이미지가 macOS Courier로 만들어진 것처럼 보임
일반 계열만 쓰는 선택
- 로컬 설치 폰트 나열을 줄였다면, 웹 폰트도 꼭 필요한지 다시 볼 수 있음
- 웹 폰트는 웹 폰트가 없는 경우보다 느리고, 로딩 문제를 만들 수 있음
- 이 때문에
font-display가 있음 - 하지만 block·swap 기간, 다시 그리기, 리플로우 사이의 절충을 다루는 대신 사용자가 가진 폰트를 그대로 쓰는 선택도 가능함
- 이 때문에
monospace도 일반 계열만 쓰는 선택이 가능함- 과거
monospace기본값은 좋지 않았고, 특히 Microsoft의 Courier New#Courier_New)는 잘못 디지털화되어 400이 아니라 사실상 200–250 weight처럼 보였음 - 이후 Apple이 Menlo)를 도입했고, 브라우저 기본
monospace가 갱신되지 않던 시기에 사람들이 폰트 스택에 Menlo를 넣기 시작함 - 현재 브라우저 기본값은 모두 나아졌고, 모든 경우에 훌륭하지는 않아도 더 이상 나쁘지는 않음
- 과거
Menlo, Monaco, Consolas, Bitstream Vera Sans Mono, Courier, Courier New같은 목록을 버리고monospace만 남겨보는 선택이 가능함Courier New를 의도적으로 폰트 스택에 넣는 것은 강하게 부정적으로 평가됨
monospace, monospace와 브라우저 동작
font-family: monospace;를 명시적 또는 암묵적으로 쓰면font-size가 100%가 아니라 아마 81.25% 로 기본 설정될 수 있음- 사용자는 일반 계열 폰트, 기본 글자 크기, 기본 고정폭 글자 크기를 바꿀 수 있음
- 목록에 두 번째 family가 있으면 이 동작이 발생하지 않음
font-family: my-web-font, monospace;는 괜찮음font-family: monospace, monospace;도 괜찮음- 직접
font-size를 지정하는 방법도 가능함
- Lightning CSS는
monospace, monospace를 망가뜨리는 문제가 있음- 관련 이슈: parcel-bundler/lightningcss#1221
- 임시로
monospace, m을 쓰고 있음
- 이 문제는
monospace에만 영향을 줌 - 브라우저가
monospace크기 동작을 버리고, 아마 13px인 값을 아마 16px로 올리도록 설득하고 싶다는 입장임- 제안 장소는 CSSWG가 될 수 있음
콘텐츠에 system-ui와 ui-* 쓰지 않기
- UI 폰트는 짧은 UI 텍스트용이지 긴 콘텐츠용이 아님
- UI 폰트는 콘텐츠 언어를 잘 지원하지 않을 수 있음
- macOS는 이 부분이 괜찮지만 Windows는 그렇지 않다고 봄
- 결과적으로 CJK 사용자가 좋지 않은 고정폭 폰트를 보게 되는 사례가 생길 수 있음
- 일부 사용자는 의도적으로 우스꽝스러운 시스템 UI 폰트를 골라두기도 하며, Android 일부 커뮤니티에서 꽤 흔하다고 함
system-ui를 쓰면 콘텐츠도 그렇게 보일 수 있다는 우려가 있음
- w3c/csswg-drafts issue #3658은
system-ui의 여러 문제를 논의했고,system-ui가 광범위하게 남용됐다는 결론을 담고 있음 - mdn/content issue #41244는 MDN에 과도한 사용을 경고하는 note를 추가함
system-ui와ui-*는 더 나은 기본 폰트를 얻기 위한 proxy처럼 쓰여왔지만, 이런 용도는 좋지 않음system-ui는 실수였다는 입장임-apple-system만 남기고BlinkMacSystemFont가 그것으로 바뀌게 했어야 한다는 견해임- 표준화 당시 다른 플랫폼에는 유용한 동등 개념이 없었고, 지금은 일부 플랫폼에 생겼다고 봄
- 기존 일반 계열의 낡은 기본값을 브라우저가 갱신하지 않은 문제를 우회하려는 용도로 대부분 남용됐다고 봄
ui-serif,ui-sans-serif,ui-monospace, 특히ui-rounded는 제거돼야 할 명백한 실수라는 입장임- 비 Apple 환경에서는 어떤 폰트로도 매핑될 것으로 기대되지 않음
- 개념 자체가 Apple 플랫폼에만 있으므로 표준에 포함되지 말았어야 함
- Apple이 제공했다면
-apple-system처럼-apple접두 형태였어야 한다고 봄
- 웹 앱에는
system-ui의 정당한 사용 사례가 있지만, 실제로는 거의 전적으로 남용됐다는 인상이며 제거 개입도 나쁘지 않을 수 있음
댓글과 토론
Lobste.rs 의견들
-
https://lindenii.org 에서는 font-family를 아예 지정하지 않는 방식을 택해서, 사용자가 브라우저에서 고른 기본 글꼴을 존중하고 있음
개인적으로는 산세리프를 선호하지만, 사용자가 세리프를 기본값으로 쓰고 있다면 굳이 덮어쓸 이유가 없어 보임
다만 https://runxiyu.org/soc/ta/ 처럼 대부분의 글꼴에 없는 문자를 써야 하는 경우에는 웹 글꼴을 넣을 수밖에 없었고, 그 결과 나머지 텍스트까지 사용자의 기본값이 아니라 산세리프로 강제되는 문제가 생김
이상한 문자마다<unusual-character>같은 걸로 감싸지 않는 한 더 나은 방법이 있는지 모르겠고, “사용자가 선호하는 코드용 글꼴” 같은 걸 지정할 방법도 있으면 좋겠음
monospace, monospace요령은 고마웠고, 크기 차이가 꽤 헷갈렸음- 두 번째 문제는 특이한 문자 옆에 이미지 대체 표시를 두는 게 괜찮은 폴백일 수도 있음
유니코드 문자 목록 사이트들이 그런 식으로 처리함 - 내 블로그 https://hauleth.dev 에서도 비슷하게 하고 있지만
monospace를 씀
사이트 디자인을 칭찬받은 적도 있는데, 사실 Zola 테마 하나를 가져다 CSS와 커스텀 요소를 줄인 정도라서, 특히 개인 페이지에 대해서는 글의 취지에 꽤 공감함 font-family를 아예 지정하지 않는 쪽은, 브라우저의 기본 기본 글꼴이 세리프에서 산세리프로 바뀌는 편이 사용자에게 더 나을 수도 있다고 봄
대다수 사용자는 직접 글꼴을 고르지 않으니 “사용자가 고른 글꼴”과 “브라우저 기본 글꼴”을 구분할 방법이 없음
세리프를 좋아하긴 하지만 요즘은 대부분 산세리프를 더 선호할 가능성이 큼
내 환경에서는 페이지가 글꼴을 지정하지 못하게 막아놨고, 제대로 된 CJK 글꼴도 설치하지 않았음
한자 대신 “4E2D” 같은 상자가 떠도 어차피 그 표의문자만큼이나 나한테는 의미가 없다고 봤기 때문임
그런 폴백 글꼴 처리 자체는 잘했지만, 안타깝게도 기본 글꼴의 이름을 직접 지정하는 방법은 없음
대신 JavaScript로 빈 문서에서getComputedStyle(document.documentElement).fontFamily를 보면 내 고급 글꼴 설정에 따라"serif"또는"sans-serif"가 나옴
“코드용 선호 글꼴”이 정확히 뭘 뜻하는지는 모르겠고,monospace말고 다른 걸 생각하는 듯함
- 두 번째 문제는 특이한 문자 옆에 이미지 대체 표시를 두는 게 괜찮은 폴백일 수도 있음
-
이 글은 아직 초안이라 꽤 미완성이고, 두세 가지 다른 형태의 조각들이 섞여 있어서 다소 난잡함
아마 최종적으로는 한 페이지 이상이 되고, 지금과는 상당히 다른 형태가 될 듯하며, 일부는 손글씨·손그림·수작업 레이아웃이 될 수도 있음
요즘은 대신 가벼운 마크업 언어 구현에 집중하고 있고, 이제 거의 쓸 수 있는 상태라 마지막 90%가 한 번도 채 남지 않은 느낌임
그다음 다시 글을 쓰고 공개할 예정임 -
font-family: monospace;를 쓰면font-size가 100%가 아니라 81.25% 로 기본 설정될 수 있고, 목록에 두 번째 글꼴이 있으면 그런 일이 생기지 않는다는 부분이 정말 흥미로움
font-family: my-web-font, monospace;나font-family: monospace, monospace;는 괜찮다는 건데, MDN에는 현재 문서화되어 있지 않은 것 같음
왜 이런 일이 생겼고 왜 문서화되지 않았는지 설명할 수 있는 사람이 있는지 궁금함- 기억하기로는 Firefox는 실제로 이 글꼴 크기 조정을 하지 않고 Chrome은 함
그래서 브라우저 간 불일치의 원인이 되기도 함 - 아마도 고정폭 텍스트가 본문 텍스트와 시각적으로 같은 크기로 보이게 하려는 의도였을 수도 있음
- 기억하기로는 Firefox는 실제로 이 글꼴 크기 조정을 하지 않고 Chrome은 함
-
초안이라고는 하지만, 글 안에서 한 섹션을 두 번째로 그대로 복사해 붙인 듯한 이상한 반복이 있음
특히 내가 좋아하는 고정폭 글꼴이 별로라는 뉘앙스라 더 거슬렸음- 아직 구조를 다시 잡는 중이라 그런 부분들이 남아 있음
자세히 읽어보면 확정 권고로 둘 내용과, 더 미묘한 입장을 취해야 할 내용을 정리하는 중이라 약한 모순도 있음
좋아하는 고정폭 글꼴이 뭔지 궁금함
- 아직 구조를 다시 잡는 중이라 그런 부분들이 남아 있음
-
serif와sans-serif만 쓰지 못하게 만드는 한 가지 이유는, 기본 세리프 글꼴이 종종 별로라고 느끼는 Times라는 점임
그래서 본문 글꼴을 세리프에서 산세리프로 옮기는 중임 -
“시스템에 설치되어 있을 법한 글꼴을 나열하지 말라”와 “고정폭도 가능하면 일반 계열만 쓰라”는 조언과 관련해, 내 웹사이트에는 다음처럼 설정해 둠
--sans-serif: Adwaita Sans, Adwaita Sans Bundled, Inter, sans-serif;와--monospace: Iosevka, Iosevka Web, Cascadia Code, monospace;를 쓰는 식임
의도는 GNOME에 Adwaita Sans가 설치되어 있으면 시스템 글꼴을 쓰고 웹 글꼴을 내려받지 않게 하며, 없으면Adwaita Sans Bundled웹 글꼴을 쓰고 로딩 중에는 지표가 비슷한 Inter와sans-serif로 폴백하게 하는 것임
고정폭도 마찬가지로 시스템의 Iosevka가 있으면 쓰고, 없으면Iosevka Web웹 글꼴을 쓰며, 로딩 중에는 Cascadia Code와monospace로 폴백하게 했음
Windows의monospace가 Consolas라서 별로이고, 새 Windows에는 Cascadia Code가 설치되어 있다는 점도 고려했음
Cascadia Code가 Iosevka와 지표가 많이 다르다는 건 나쁘다는 걸 알지만, 이런 접근이 어떤지 궁금함- 웹 프로그래밍 지식이 거의 없어서, “시스템에 설치되어 있지 않을 때만 글꼴을 내려받기”를 지정하는 더 좋은 방법을 놓치고 있을 수도 있음
-
깔끔한 글이고,
monospace, monospace요령은 전혀 몰랐음
사소한 서식 문제로, 내 브라우저에서는.unimportant문단의 텍스트가 노란 배경 앞에 오지만 고정된.status바 텍스트 뒤로 들어가서,.unimportant구간을 스크롤해 지나갈 때 이상하게 보임
대각선 DRAFT 워터마크에서도 비슷한 일이 생기는 것 같음