ChatGPT解决这个技术问题 Extra ChatGPT

Converting and rendering web fonts to base64 - keep original look

I want to defer font loading on my site inspired by deferred font loading logic for Smashing Magazine.

Main part of this is converting fonts to base64 and preparing your CSS file. My steps so far:

Pick fonts on Google Web Fonts and download them. Use Font Squirrel Webfont Generator to convert downloaded TTF files to CSS file with base64 embedded WOFF fonts (Expert options -> CSS -> Base64 Encode). Load CSS file async (not important here).

CSS snippet for Open Sans Bold:

@font-face {
  font-family: 'Open Sans';
  src: url(data:application/x-font-woff;charset=utf-8;base64,<base64_encoded>) format('woff');
  font-weight: 700;
  font-style: normal;
}

https://i.stack.imgur.com/SEmsd.gif

Especially notice accents being way off and absolutely horrible letter a. Other font families and variants look very noticeably different as well (size and shape distortions, etc.).

So the question is: How do you properly encode TTF files from Google Web Fonts (or other source) to base64 format and use it in a way that the result is identical to the original file?


d
djangodude

In the Font Squirrel Expert options, make sure to set the 'TrueType Hinting' option to 'Keep Existing'. Either of the other options will cause the TrueType instructions (hints) to be modified, which will in turn affect the rendering of the font.

Alternatively, if you're happy with the rendering of the font directly from GWF, you can just take that file and do the base64 encoding yourself. In OS X or Linux, use the built-in base64 command in Terminal/shell:

$ base64 myfont.ttf > fontbase64.txt

For Windows, you'll need to download a program to encode in base64 (there are several free/Open Source tools available). Copy the contents of that file, then use in your CSS as:

@font-face {
    font-family: 'myfont';
    src: url(data:font/truetype;charset=utf-8;base64,<<copied base64 string>>) format('truetype');
    font-weight: normal;
    font-style: normal;
}

(Note that you may need to make some adjustments to the various @font-face info to match your particular font data; this is just an example template)


I try to do exactly the same thing. I followed your instructions, but it still does not work. The font renders worse than the WOFF served by Google. I also tried different other options. Is there another way?
Answer updated with explanation of how to do base64 yourself and use in CSS.
I think there is a syntax error in the example. It should be a comma rather than a semi-colon after base64 thus: base64,<> Otherwise really helpful. Thanks.
You're right, RFC 2397 says it should be a comma after the 'base64' indicator. I've updated my answer to reflect that.
I noticed it is important to keep the src: line - including the base64 string - one single line. The base64 command might insert line breaks by default. That can be disabled using the -w parameter: base64 -w 0 font.ttf > font_base64.txt. (for the base64 utility from GNU coreutils)
I
Ilyich

Use this code snippet to base64 encode your font directly in the browser (OS independent, no need to install anything)

function base64convert (files) { console.clear() const reader = new FileReader() reader.onload = (e) => { console.log(e.target.result) } reader.readAsDataURL(files[0]) }

Then copy the output and paste it into your CSS:

@font-face {
    font-family: 'myfont';
    src: url("<<copied base64 string>>");
}

Wow. This is really impressive. And it works. :-)
works but feels awful having that in my html file

关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now