How to preload custom fonts with webpack/rails 6 - css

I would like to preload a custom font. I'm using rails 6 with webpack.
In config/_fonts.scss :
#font-face {
font-family: 'customfont';
src: font-url('customfont.eot?81236734');
src: font-url('customfont.eot?81236734#iefix') format('embedded-opentype'),
font-url('customfont.woff2?81236734') format('woff2'),
font-weight: normal;
font-style: normal;
font-display: swap;
}
I import this font in my application scss :
#import "config/index";
But I would like to preload this font. What's the best pratice to do that ?

If I am not mistaken you have to add a link tag in head of the view as per this article : https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content
Then for the href use the asset_pack_url helper in order to point to the right file.
Also be careful the asset_path_url needs to point to the folder where your compiled asset resides without mentionning "public/packs"
Then you probably have to use something like <%= asseet_pack_url 'media/fonts/my-font.woff' %> or something like that
(Also I am considering you are using Webpack to deliver images/css and fonts. If you are using the asdset pipeline just use the usual helpers)

Recently had same question. Here is what I did for Rails 6 with webpack.
Per my understanding webpack produces manifest.json which you can find in public directory of your app (it is configured in webpacker.yml).
When you open manifest.json you should also see references for fonts.
In my manifest it appeared similar to the following:
"media/images/some-font.woff2": "/packs/media/images/4d419d560889218c146f.woff2"
Now when you know that the pack path is available, it is easy to construct preloading in head section (example in haml):
= preload_link_tag(asset_pack_path('media/images/some-font.woff2'))

Related

Custom local fonts not working with webpack 5

I have some local fonts I want to use in my project. I've read a few tutorials and questions on this, and I'm following the reccomendations I've seen, but my fonts are not showing up properly in the browser. I am using webpack 5. In my webpack config:
module.exports = {
// ...
module: {
rules: [
// ...
{
test: /\.(woff|woff2|ttf)$/,
use: {
loader: "url-loader",
},
},
]
}
}
I have a bunch of .tff font files in my src/assets/fonts/ directory. I have a .scss file for global styles. In there, I define the font names and I want to use, and where webpack should find them:
#font-face {
font-family: "InterRegular";
src: url("../assets/fonts/Inter-Regular.ttf") format("truetype");
font-display: swap;
}
#font-face {
font-family: "InterMedium";
src: url("../assets/fonts/Inter-Medium.ttf") format("truetype");
font-display: swap;
}
#font-face {
font-family: "InterSemiBold";
src: url("../assets/fonts/Inter-SemiBold.ttf") format("truetype");
font-display: swap;
}
// etc
I'm fairly sure webpack is finding these, because if I get the path to the file wrong, webpack errors. I then try to apply the font:
html,
body {
font-family: "InterSemiBold", sans-serif;
}
There are no errors, but the font does not get applied to the page. When I look in my network tab, I can see that a font file is indeed being loaded:
But this is clearly not the InterSemiBold font. Regardless of what font I'm using, this strangely-named .tff file always shows this same, seriffed font.
Looking at the computed value of an element, I can see that the browser is reading the "InterSemiBold", sans-serif value of the font family, but still defaulting to Arial:
I have also tried loading in fonts using the file-loader with webpack, but that makes no difference, and many recommend using url-loader instead.
What am I doing wrong here? Why is my font not being loaded in and applied?
Your dev tools screenshot indicates your actual page/app style sheet expects the font-family name to be 'Inter'.
So you don't need different family names for each font-weight
and change your #font-face rules to something like this:
#font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
src: url('../assets/fonts/Inter-Regular.ttf') format('truetype')
}
#font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 500;
src: url('../assets/fonts/Inter-Medium.ttf') format('truetype')
}
#font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 600;
src: url('../assets/fonts/Inter-SemiBold.ttf') format('truetype')
}
#font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 700;
src: url('../assets/fonts/Inter-Bold.ttf') format('truetype')
}
Your #font-face rules should include a font-style value.
For italic styles you would change it to font-style: normal.
The font-url must use the exact file name of a font style (just a note, as some automatic font loaders rename the filenames internally or load updated files directly from Google - resulting in filenames like this "inter-v11-latin-800.ttf").
Since a browser can't automatically tell which intermediate weight would be e.g 'semi-bold' or 'light', you add specific numeric font-weight values which can be used to map all font-weights to different selectors like this:
body{
font-family:Inter;
font-size:16px;
}
.medium{
font-weight:500;
}
.semibold{
font-weight:600;
}
strong, h1, h2,
.button{
font-weight:700;
}
You might also double check your main css – it might also contain a separate #font-face declaration.
If everything is working fine, you should see the .tff files in dev tools just as defined in #font-face urls (e.g. "Inter-Regular.ttf")
Still not working?
Try to open the font via absolute URL in your browser.
Font file connection test example
Provided your compiled folder structure looks something like this:
the final URL is "myapp.com"
the main css is located under URL "myapp.com/css/main.css"
font files are located (at least according to your css/compiling code) in directory URL "myapp.com/assets/fonts/"
the actual font files should be available (downloadable) under URL
"myapp.com/assets/fonts/Inter-Regular.ttf"
If this doesn't work – you need to fix the URLs in your #font-face rule.
This especially important, if assets are copied/assembled during a compiling process to a new directory – so previously paths/URLs might not be "automagically" fixed.
Another cause might be inlined css – so the css becomes part of the compiled HTML <head> or <body> – relative paths/URLs might not work anymore => absolute paths could fix this (... albeit, any decent auto inlining script should be smart enough to translate relative to absolute URLs).
Compiled css
The final css might also include some overriding rules.
So check the finally compiled css in devtools and search for any #font-face rules – as a last resort: add a !important keyword to a font src to enforce the desired URL.
Font files might be corrupt?
Since the "inter" is available as free google webfont you could get a "fresh" copy via google webfonts helper
I was having the same problem as you with Webpack 5 and a custom local font, none of the above suggestions worked, but I just solved it, here's how: When I went to Google Fonts the only option was to download a TTF and that's what I had been trying to use. So, I visited the google-webfonts-helper website which gives you the code to put in your CSS file to make sure I was doing it correctly, and it instead had me download a WOFF and WOFF2 of the font. When I used these files the fonts rendered properly in my Chrome browser right away. I then found a few other forums from the past where people had issues with Chrome rendering TTF's and solved them by switching to WOFF formats. I don't know exactly why this works but it did.

Why dont font formats imported from Github function correctly?

Using canvas to generate text for some Trading Cards (Its a community project)
And I needed the Andy Font. However there are no stable web serving locations.
So I went with github. I placed all my font formats inside this repository folder:
https://github.com/FunctFlow/TerrariaTradingCards/tree/master/andy%20font%20family
Then I used this font-font inside of my project:
#font-face {
font-family: "Andy";
src: url("https://github.com/FunctFlow/TerrariaTradingCards/raw/master/andy%20font%20family/Andy-Bold.eot");
src: url("https://github.com/FunctFlow/TerrariaTradingCards/raw/master/andy%20font%20family/Andy-Bold.eot?#iefix")
format("embedded-opentype"),
url("https://github.com/FunctFlow/TerrariaTradingCards/raw/master/andy%20font%20family/Andy-Bold.woff2")
format("woff2"),
url("https://github.com/FunctFlow/TerrariaTradingCards/raw/master/andy%20font%20family/Andy-Bold.woff")
format("woff"),
url("https://github.com/FunctFlow/TerrariaTradingCards/raw/master/andy%20font%20family/Andy-Bold.ttf")
format("truetype");
font-weight: bold;
font-style: normal;
}
However, my project does NOT render the andy font, as you can see in this codepen: https://codepen.io/SkylerSpark/pen/bGVBpmj
I love how solutions always appear minutes after Ive given up and come here.
Basically, Github serves the wrong filetype headers, and the website cant recognize the font-formats.
So you cannot use Github for font formats, similarly to how you cant use it to host Javascript or CSS or whatever else you need to reference through http.
The best solution I can think of is to use a tool like jsDelivr to reference the fonts. As seen here: JsDelivr Github
And using a link like this:
https://cdn.jsdelivr.net/gh/FunctFlow/TerrariaTradingCards#master/andy%20font%20family/Andy-Bold.ttf
My fonts now render successfully

How do you include custom fonts in Semantic UI (instead of Google Fonts)

In /src/site/globals/site.variables, I can see how you can define google fonts, which get imported from when you compile. What I am interested in is defining my own custom fonts where I will supply my own font files.
I can’t find docs on how to do it. While I know how to do it in CSS, I am wondering if it is already built-in in this framework but I have simply missed it.
Thanks!
I don't believe there is a built-in way to do it. Here's how I did it.
I used the standard #font-face css rule. I then placed it in the site.overrides file. I am using a less variable (#font-path) to simplify my file paths.
#font-path: '../../fonts';
#font-face {
font-family: 'my-font';
src: url('#{font-path}/my-font.woff') format('woff'),
url('#{proxima-prefix}my-font.woff2') format('woff2');
font-weight: normal;
font-style: normal;
}
You'll have to make sure that the font files are served up appropriately by your server.
The above can be turned into a less mixin based on your usage as well.
A good resource on #font-face and formats: https://css-tricks.com/snippets/css/using-font-face/
A great answer on how to use different font weights/styles: https://stackoverflow.com/a/10046346/7681976

When asset paths don't match up with the asset pipeline, should I edit paths or try and precompile fonts into a different directory?

I am working on a project with a bootstrap theme and the font paths inside toolkit.css are pointing to ../fonts/.
When rails precompiles my fonts in /app/assets/fonts/ it puts them in /public/assets but the CSS file is pointing to public/fonts.
Here's a code snippet:
#font-face {
font-family: "toolkit-entypo";
src: url("../fonts/toolkit-entypo.eot");
src: url("../fonts/toolkit-entypo.eot?#iefix") format("eot"),
url("../fonts/toolkit-entypo.woff2") format("woff2"),
url("../fonts/toolkit-entypo.woff") format("woff"),
url("../fonts/toolkit-entypo.ttf") format("truetype");
font-weight: normal;
font-style: normal; }
I can think of two options, but I believe they each have faults:
Edit the CSS file and change ../fonts/ to ../assets/
CON: If I ever get a newer version of toolkit.css, I'll have to remake the changes
Try and figure out how to precompile only the fonts in /app/assets/fonts/ into /public/fonts/.
CON: One may not even be able to precompile assets into a directory lower than /public/assets/
I understand that this question is opinion based since I am proposing two potential solutions, but perhaps someone in the world can point me in the right direction.
Thanks for your time.

Can I replace a reference to https://fonts.googleapis.com/css?family=Karla|Ubuntu to read all the contents from our server

I am working on a web layout template which I have downloaded, and I noted on some CSS files there are references to external links to load fonts and themes, such as the following line of code at the beginning of a .css file:-
#import url(https://fonts.googleapis.com/css?family=Karla|Ubuntu)
When I open the link inside my browser I noted it will load the following:-
#font-face {
font-family: 'Karla';
font-style: normal;
font-weight: 400;
src: local('Karla'), local('Karla-Regular'), url(https://themes.googleusercontent.com/static/fonts/karla/v2/azR40LUJrT4HaWK28zHmVA.woff) format('woff');
}
#font-face {
font-family: 'Ubuntu';
font-style: normal;
font-weight: 400;
src: local('Ubuntu'), url(https://themes.googleusercontent.com/static/fonts/ubuntu/v4/_xyN3apAT_yRRDeqB3sPRg.woff) format('woff');
}
My problem is that I am using this template for our intranet, so users might access the intranet even if they do not have access to the internet. So my question is how I can add these fonts and themes inside my asp.net mvc project , so that the contents will be loaded from our server and not from Google site ?
Thanks ?
EDIT
I replaced the following :-
#import url(https://fonts.googleapis.com/css?family=Karla|Ubuntu);
with :-
#font-face {
font-family: 'Karla';
font-style: normal;
font-weight: 400;
src: local('Karla'), local('Karla-Regular'), local('/Content/fonts/azR40LUJrT4HaWK28zHmVA.woff');
}
#font-face {
font-family: 'Ubuntu';
font-style: normal;
font-weight: 400;
src: local('Ubuntu'), local('/Content/fonts/_xyN3apAT_yRRDeqB3sPRg.woff');
}
but i did not get the font effect ?
BR
You may want to see this section from the Google FAQ on the subject
Can I download the fonts on Google Fonts to my own computer?
Yes. To
download the fonts, simply add fonts to your collection and click the
"Download your Collection" link. You can download the fonts to use
them for your mockups, in your documents or to host them on your own
server.
This article goes into further step by step detail about how to do this, it should solve any issue with end users not having access to the internet- as long as you're local references to the fonts are correctly defined in your CSS.
You should download the font from the Google site, then process it with a font file generator like the FontSquirrel generator, which also produces a CSS file you can use.
The point is that different browsers need different font formats, served using a suitably crafted #font-face rule.
When you use the fonts using a URL like https://fonts.googleapis.com/css?family=Karla|Ubuntu, the Google server recognizes the browser and sends just CSS code tailored for that browser. If you just copy that onto your page, it will only work on that browser and sufficiently similar browsers.
You can self-host Google Fonts, read Self-host web fonts quick guide:
https://fonts.google.com/knowledge/using_type/self_hosting_web_fonts
Here you can find a practical example of how this can be done:
https://developers.google.com/fonts/docs/material_icons
Setup Method 1. Using via Google Fonts - provides an example of how the Google Material Icons font can be used via fonts.googleapis.com.
Setup Method 2. Self hosting - provides an example of how the same Google Material Icons font can be self hosted.

Resources