Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Bulletproof Font Icons
Search
zachleat
May 27, 2014
Programming
19
2.9k
Bulletproof Font Icons
Originally presented at CSSConf 2014:
http://2014.cssconf.com/#zach
zachleat
May 27, 2014
Tweet
Share
More Decks by zachleat
See All by zachleat
NEJS CONF 2017 Interstitial Slides
zachleat
0
150
Credibility
zachleat
0
88
A Brief History of that Time You Used Web Fonts
zachleat
7
1.4k
The Performance and Usability of Font Loading (Velocity NYC 2015)
zachleat
3
620
The Performance and Usability of Font Loading (Velocity Santa Clara 2015)
zachleat
27
4.6k
Performance and Responsive Web Design
zachleat
7
2k
Remodeling @font-face
zachleat
17
3.5k
How and Why I Built fontfamily.io
zachleat
2
1.5k
Impostor Syndrome
zachleat
1
440
Other Decks in Programming
See All in Programming
Implementation Patterns
denyspoltorak
0
140
生成AI時代を勝ち抜くエンジニア組織マネジメント
coconala_engineer
0
37k
JETLS.jl ─ A New Language Server for Julia
abap34
2
470
Graviton と Nitro と私
maroon1st
0
160
実はマルチモーダルだった。ブラウザの組み込みAI🧠でWebの未来を感じてみよう #jsfes #gemini
n0bisuke2
3
1.4k
LLMで複雑な検索条件アセットから脱却する!! 生成的検索インタフェースの設計論
po3rin
4
1.1k
公共交通オープンデータ × モバイルUX 複雑な運行情報を 『直感』に変換する技術
tinykitten
PRO
0
180
Claude Codeの「Compacting Conversation」を体感50%減! CLAUDE.md + 8 Skills で挑むコンテキスト管理術
kmurahama
1
700
ELYZA_Findy AI Engineering Summit登壇資料_AIコーディング時代に「ちゃんと」やること_toB LLMプロダクト開発舞台裏_20251216
elyza
2
920
SQL Server 2025 LT
odashinsuke
0
120
これならできる!個人開発のすゝめ
tinykitten
PRO
0
140
愛される翻訳の秘訣
kishikawakatsumi
3
370
Featured
See All Featured
GitHub's CSS Performance
jonrohan
1032
470k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
2.8k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
140
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.5k
4 Signs Your Business is Dying
shpigford
187
22k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
3.9k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
115
100k
Marketing to machines
jonoalderson
1
4.5k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
0
110
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
0
3.4k
The Invisible Side of Design
smashingmag
302
51k
Digital Ethics as a Driver of Design Innovation
axbom
PRO
0
140
Transcript
N Bulletproof C E U R N
LET’S LEARN EVERYTHING ABOUT @FONT-FACE
@zachleat zachleat.com
None
If you wish to make a font icon from scratch,
you must first invent the universe. —Carl Sagan, probably https://www.flickr.com/photos/scott-s_photos/11763686274 “ ”
@Font-face THIS ONE WEIRD TRICK A G EN D A
CAT FANCY UNICODE LOADING.. . .. .
1997 @font-‐face
1995 <font>
None
@font-‐face
CSS3 CSS2.1 CSS2
@font-‐face { ! font-‐family: The Font that Could;
src:url('icanfont.ttf') format('truetype'), url('icanfont.woff') format('woff'); font-‐weight: normal; font-‐style: normal; ! }
@font-‐face { ! font-‐family: The Font that Could;
src:url('icanfont.ttf') format('truetype'), url('icanfont.woff') format('woff'); font-‐weight: normal; font-‐style: normal; ! }
@font-‐face { ! font-‐family: The Font that Could;
src:url('icanfont.ttf') format('truetype'), url('icanfont.woff') format('woff'); font-‐weight: normal; font-‐style: normal; ! }
David Hasselwoff USE WOFF
Woff caniuse.com 5.0! 6.0 7.0! 7.5!
WOFF BY ONE ERROR
Woff + TTF caniuse.com 5.0! 6.0 7.0! 7.5!
NEED IE8? Add EOT
@font-‐face { ! font-‐family: The Font that Could;
src:url('icanfont.eot?#iefix') format('embedded-‐opentype'), url('icanfont.ttf') format('truetype'), url('icanfont.woff') format('woff'); font-‐weight: normal; font-‐style: normal; ! }
Woff + TTF + EOT caniuse.com 5.0! 6.0 7.0! 7.5!
NEED Chrome + Windows? Add SVG http://www.fontspring.com/blog/smoother-web-font-rendering-chrome
34 8.1 WOFF SVG ISSU E XP
Woff + EOT + TTF + SVG https://code.google.com/p/chromium/issues/detail?id=137692 caniuse.com 5.0
7.0! 7.5! 6.0 6.0
@font-‐face { font-‐family: The Font that Could;
src:url('icanfont.eot?#iefix') format('embedded-‐opentype'), url('icanfont.ttf') format('truetype'), url('icanfont.woff') format('woff'), url('icanfont.svg#icanfont') format('svg'); font-‐weight: normal; font-‐style: normal; } W R O N G
@media (-‐webkit-‐min-‐device-‐pixel-‐ratio:0) { ! @font-‐face {
font-‐family: The Font That Could; src: url('icanfont.svg#icomoon') format('svg'); font-‐weight: normal; font-‐style: normal; } ! }
https://github.com/scottjehl/Device-Bugs/issues/43 ISSU E
None
@media (-‐webkit-‐min-‐device-‐pixel-‐ratio:0) and (min-‐resolution: .001dpcm) { !
@font-‐face { font-‐family: The Font That Could; src: url('icanfont.svg#icomoon') format('svg'); font-‐weight: normal; font-‐style: normal; } ! }
Supports -‐webkit-‐min-‐device-‐pixel-‐ratio Supports min-‐resolution Yes No Yes No
Woff + EOT + TTF + SVG https://code.google.com/p/chromium/issues/detail?id=137692 caniuse.com 5.0
7.0! 7.5! 6.0 6.0
WHEW.
A QUICK REVIEW
@font-‐face { font-‐family: The Font that Could;
src:url('icanfont.eot?#iefix') format('embedded-‐opentype'), url('icanfont.ttf') format('truetype'), url('icanfont.woff') format('woff'); font-‐weight: normal; font-‐style: normal; } ! @media (-‐webkit-‐min-‐device-‐pixel-‐ratio:0) and (min-‐resolution: .001dpcm) { ! @font-‐face { font-‐family: The Font That Could; src: url('icanfont.svg#icomoon') format('svg'); font-‐weight: normal; font-‐style: normal; } }
@font-‐face { font-‐family: The Font that Could;
src:url('icanfont.eot?#iefix') format('embedded-‐opentype'), url('icanfont.ttf') format('truetype'), url('icanfont.woff') format('woff'); font-‐weight: normal; font-‐style: normal; } ! @media (-‐webkit-‐min-‐device-‐pixel-‐ratio:0) and (min-‐resolution: .001dpcm) { ! @font-‐face { font-‐family: The Font That Could; src: url('icanfont.svg#icomoon') format('svg'); font-‐weight: normal; font-‐style: normal; } } REMOVE AFTER CHROME DIRECTWRITE
GO TO YOUR HAPPY PLACE
LET’s PUT THE @FONT-FACE BLOCK ON OUR WEB PAGE
None
NO FONT-FAMILY NO DOWNLOAD
34 28 9, 10, 11 20 6.1, 7 2.3, 4.1
7 8
body { font-‐family: My Icon Font, serif;
}
var b = document.body; ! b.style.fontFamily = "My Icon
Font";
@Font-face THIS ONE WEIRD TRICK A G EN D A
CAT FANCY UNICODE LOADING…
BASIC LATIN CODE POINT Arial Chunk Five x41 A A
x42 B B x43 C C x44 D D x45 E E
Higher UNICODE Ranges x2261 ≡ x2605 ˒ x2665 ♥ x2713
✓
Arial Chunk Five 0x1F300 0x1F302 0x1F350 Arial Chunk Five 0x1F300
0x1F302 0x1F350 EMOJI http://doeschromesupportemojiyet.com/ https://code.google.com/p/chromium/issues/detail?id=62435
None
CONSISTENCY
unicode.johnholtripley.co.uk
None
READ AS x2261 ≡ IDENTICAL TO x2605 ˒ BLACK STAR
or STAR x2665 ♥ HEART SUIT ACCESSIBILITY
None
PRIVATE USE AREA
YOUR ICON FONT HERE 0xe001 0xe002 0xe003 0xe004 PRIVATE USE
AREA
@Font-face THIS ONE WEIRD TRICK A G EN D A
CAT FANCY UNICODE LOADING…
https://www.flickr.com/photos/79157069@N03/11616536203/ OUR @FONT-FACE REQUEST LEAVES THE NEST
LOCAL FONT { @FONT-FACE {
None
FOIT Flash of Invisible Text
@FONT-FACE LOAD
https://twitter.com/aanand/status/465182499577286656
LOCAL FONT { @FONT-FACE {
FOUT Flash of UNSTYLED Text
3 S @FONT-FACE LOAD ABCDEFGH ABCDEFGH
3 S @FONT-FACE LOAD
https://twitter.com/raganwald/status/452092613529567233 Screenshot of GitHub
LOCAL FONT { @FONT-FACE {
Timeouts/CURFEWS 34 > 60 s 36 28 9, 10, 11
N/A 20 > 60 s 3 s 3 s 7 60 s 4.1 > 60 s * 6 > 60 s 60 s* 7
if font loads after 60 seconds SAFARI IGNORES IT 7
*Timeout ISSU E 7
WHAT HAPPENS WHEN A USER HITS THE STOP BUTTON?
LOCAL FONT { @FONT-FACE { ISSU E
None
@Font-face THIS ONE WEIRD TRICK A G EN D A
CAT FANCY UNICODE LOADING…
LET’S FIX EVERYTHING
DECORATIVE ICON U SE C A SE
<span class="twitter icon" aria-‐hidden="true"></span> Share on Twitter
<span class="twitter icon" aria-‐hidden="true"></span> Share on Twitter
FILAMENTGROUP/A-Font-Garde https://github.com/filamentgroup/a-font-garde
FontFaceOnload( "My Icon Font", {
glyphs: "\uE600\uE601\uE602\uE605", success: function() { var docEl = document.documentElement; docEl.className += " my-‐icon-‐font"; } }); // requires http://filamentgroup.github.io/a-font-garde/src/fontfaceonload.js
/* @font-‐face omitted */ ! .my-‐icon-‐font .icon-‐twitter:before {
font-‐family: My Icon Font; content: "\e600"; }
typekit/webfontloader https://github.com/typekit/webfontloader
CSS Font Loading Module Level 3 http://dev.w3.org/csswg/css-font-loading/
document.fonts.load("1em My Icon Font") .then(function() { !
var docEl = document.documentElement; docEl.className += " my-‐icon-‐font"; ! });
BRAMSTEIN/FONTLOADER https://github.com/bramstein/fontloader FOLLOW HE’S WORKING ON A POLYFILL. https://twitter.com/bram_stein/status/465560158723395584
my-‐icon-‐font SOLVES OUR PROBLEMS
WE NOW CONTROL FOIT & FOUT
NO MORE UNICODE SURPRISES TIMEOUT SURPRISES STOP BUTTON SURPRISES
DECORATIVE ICON 3 S @FONT-FACE LOAD FOIT FOUT
@Font-face THIS ONE WEIRD TRICK A G EN D A
LET’S GET FANCY UNICODE LOADING…
LET’S GET CAT FANCY
TEXT to ICON @FONT-FACE LOAD U SE C A SE
<style> .facebook .icon { display: none;
} .my-‐icon-‐font .facebook .icon { display: inline-‐block; } .my-‐icon-‐font .facebook .text { /* Visually hide but keep for screen readers */ clip: rect(0 0 0 0); overflow: hidden; position: absolute; height: 1px; width: 1px; } </style> <span class="facebook"> <span class="icon" aria-‐hidden="true"></span> <span class="text">Facebook</span> </span> https://github.com/h5bp/html5-boilerplate/blob/master/css/main.css#L127
<style> .facebook .icon { display: none;
} .my-‐icon-‐font .facebook .icon { display: inline-‐block; } .my-‐icon-‐font .facebook .text { /* Visually hide but keep for screen readers */ clip: rect(0 0 0 0); overflow: hidden; position: absolute; height: 1px; width: 1px; } </style> <span class="facebook"> <span class="icon" aria-‐hidden="true"></span> <span class="text">Facebook</span> </span> https://github.com/h5bp/html5-boilerplate/blob/master/css/main.css#L127
GLYPH to ICON ≡ U SE C A SE
https://twitter.com/bjankord/status/451367657493647361 Hamburger Helper
Hamburger Emoji
= Veggieburger
– Gluten Free Hamburger https://twitter.com/brouxhaha/status/464787128334180354
Facebook’s Manburger https://twitter.com/jedschmidt/status/455871778267463680
Hungryman Burger
@FONT-FACE LOAD GLYPH to ICON ≡
<style> .hamburger .icon:before { content: "\2261";
/* Adjust font-‐size and line-‐height to match */ } .hamburger .text { /* Visually hide but keep for screen readers */ clip: rect(0 0 0 0); overflow: hidden; position: absolute; height: 1px; width: 1px; } .my-‐icon-‐font .hamburger .icon:before { font-‐family: My Icon Font; content: "\e601"; ! /* Reset font-‐size and line-‐height */ font-‐size: inherit; line-‐height: inherit; } </style> <span class="hamburger"> <span class="icon" aria-‐hidden="true"></span> <span class="text">Menu</span> </span>
<style> .hamburger .icon:before { content: "\2261";
/* Adjust font-‐size and line-‐height to match */ } .hamburger .text { /* Visually hide but keep for screen readers */ clip: rect(0 0 0 0); overflow: hidden; position: absolute; height: 1px; width: 1px; } .my-‐icon-‐font .hamburger .icon:before { font-‐family: My Icon Font; content: "\e601"; ! /* Reset font-‐size and line-‐height */ font-‐size: inherit; line-‐height: inherit; } </style> <span class="hamburger"> <span class="icon" aria-‐hidden="true"></span> <span class="text">Menu</span> </span> <span class="icon" aria-‐hidden="true"></span>
@Font-face THIS ONE WEIRD TRICK A G EN D A
LET’S GET FANCY UNICODE LOADING…
Different GOALS FOR CONTENT ICONFONTS CONTENT ICON
@zachleat Thank you!