Google Fonts without specified subset in stylesheet - css

Today I ran into a Google Font that's not loaded the usual way, and I'm hoping that someone can clarify this for me.
Why do some Google Fonts not have specified subsets in the stylesheets?
Here's an example of Roboto:
/* cyrillic-ext */
#font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu72xKOzY.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
#font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu5mxKOzY.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
#font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7mxKOzY.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
#font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4WxKOzY.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
#font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7WxKOzY.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
#font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7GxKOzY.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
#font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxK.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
And here's an example of Train One:
Full stylesheet can be found here: https://fonts.googleapis.com/css?family=Train+One
/* [2] */
#font-face {
font-family: 'Train One';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/trainone/v13/gyB-hwkiNtc6KnxUVjWHP87JR5-7NdB589yspgpx0N7r5-25NB8.2.woff2) format('woff2');
unicode-range: U+ffd7, U+ffda-ffdc, U+ffe0-ffe2, U+ffe4, U+ffe6, U+ffe8-ffee, U+1f100-1f10c, U+1f110-1f16c, U+1f170-1f1ac, U+1f200-1f202, U+1f210-1f234;
}
/* [3] */
#font-face {
font-family: 'Train One';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/trainone/v13/gyB-hwkiNtc6KnxUVjWHP87JR5-7NdB589yspgpx0N7r5-25NB8.3.woff2) format('woff2');
unicode-range: U+fa10, U+fa12-fa6d, U+fb00-fb04, U+fe10-fe19, U+fe30-fe42, U+fe44-fe52, U+fe54-fe66, U+fe68-fe6b, U+ff02, U+ff04, U+ff07, U+ff51, U+ff5b, U+ff5d, U+ff5f-ff60, U+ff66, U+ff69, U+ff87, U+ffa1-ffbe, U+ffc2-ffc7, U+ffca-ffcf, U+ffd2-ffd6;
}
/* [5] */
#font-face {
font-family: 'Train One';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/trainone/v13/gyB-hwkiNtc6KnxUVjWHP87JR5-7NdB589yspgpx0N7r5-25NB8.5.woff2) format('woff2');
unicode-range: U+9e8b-9e8c, U+9e8e-9e8f, U+9e91-9e92, U+9e95-9e96, U+9e98, U+9e9b, U+9e9d-9e9e, U+9ea4-9ea5, U+9ea8-9eaa, U+9eac-9eb0, U+9eb3-9eb5, U+9eb8, U+9ebc-9ebf, U+9ec3, U+9ec6, U+9ec8, U+9ecb-9ecd, U+9ecf-9ed1, U+9ed4-9ed5, U+9ed8, U+9edb-9ee0, U+9ee4-9ee5, U+9ee7-9ee8, U+9eec-9ef2, U+9ef4-9ef9, U+9efb-9eff, U+9f02-9f03, U+9f07-9f09, U+9f0e-9f12, U+9f14-9f17, U+9f19-9f1b, U+9f1f-9f22, U+9f26, U+9f2a-9f2c, U+9f2f, U+9f31-9f32, U+9f34, U+9f37, U+9f39-9f3a, U+9f3c-9f3f, U+9f41, U+9f43-9f47, U+9f4a, U+9f4e-9f50, U+9f52-9f58, U+9f5a, U+9f5d-9f61, U+9f63, U+9f66-9f6a, U+9f6c-9f73, U+9f75-9f77, U+9f7a, U+9f7d, U+9f7f, U+9f8f-9f92, U+9f94-9f97, U+9f99, U+9f9c-9fa3, U+9fa5, U+9fb4, U+9fbc-9fc2, U+9fc4, U+9fc6, U+9fcc, U+f900-f92c;
}
/* [6] */
#font-face {
font-family: 'Train One';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/trainone/v13/gyB-hwkiNtc6KnxUVjWHP87JR5-7NdB589yspgpx0N7r5-25NB8.6.woff2) format('woff2');
unicode-range: U+9c3e, U+9c41, U+9c43-9c4a, U+9c4e-9c50, U+9c52-9c54, U+9c56, U+9c58, U+9c5a-9c61, U+9c63, U+9c65, U+9c67-9c6b, U+9c6d-9c6e, U+9c70, U+9c72, U+9c75-9c78, U+9c7a-9c7c, U+9ce6-9ce7, U+9ceb-9cec, U+9cf0, U+9cf2, U+9cf6-9cf7, U+9cf9, U+9d02-9d03, U+9d06-9d09, U+9d0b, U+9d0e, U+9d11-9d12, U+9d15, U+9d17-9d18, U+9d1b-9d1f, U+9d23, U+9d26, U+9d2a-9d2c, U+9d2f-9d30, U+9d32-9d34, U+9d3a, U+9d3c-9d3f, U+9d41-9d48, U+9d4a, U+9d50-9d54, U+9d59, U+9d5d-9d65, U+9d69-9d6c, U+9d6f-9d70, U+9d72-9d73, U+9d76-9d77, U+9d7a-9d7c, U+9d7e, U+9d83-9d84, U+9d86-9d87, U+9d89-9d8a, U+9d8d-9d8e, U+9d92-9d93, U+9d95-9d9a, U+9da1, U+9da4, U+9da9-9dac, U+9dae, U+9db1-9db2, U+9db5, U+9db8-9dbd, U+9dbf-9dc4, U+9dc6-9dc7, U+9dc9-9dca, U+9dcf, U+9dd3-9dd7, U+9dd9-9dda, U+9dde-9de0, U+9de3, U+9de5-9de7, U+9de9, U+9deb, U+9ded-9df0, U+9df3-9df4, U+9df8, U+9dfd-9dfe, U+9e02, U+9e07, U+9e0a, U+9e0d-9e0e, U+9e10-9e12, U+9e15-9e16, U+9e19-9e1f, U+9e75, U+9e79-9e7d, U+9e80-9e85, U+9e87-9e88;
}
/* [7] */
#font-face {
font-family: 'Train One';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/trainone/v13/gyB-hwkiNtc6KnxUVjWHP87JR5-7NdB589yspgpx0N7r5-25NB8.7.woff2) format('woff2');
unicode-range: U+9ae5-9ae7, U+9ae9, U+9aeb-9aec, U+9aee-9aef, U+9af1-9af5, U+9af7, U+9af9-9afb, U+9afd, U+9aff-9b06, U+9b08-9b09, U+9b0b-9b0e, U+9b10, U+9b12, U+9b16, U+9b18-9b1d, U+9b1f-9b20, U+9b22-9b23, U+9b25-9b2f, U+9b32-9b35, U+9b37, U+9b39-9b3b, U+9b3d, U+9b43-9b44, U+9b48, U+9b4b-9b4f, U+9b51, U+9b55-9b58, U+9b5b, U+9b5e, U+9b61, U+9b63, U+9b65-9b66, U+9b68, U+9b6a-9b6f, U+9b72-9b79, U+9b7f-9b80, U+9b83-9b87, U+9b89-9b8b, U+9b8d, U+9b8f-9b94, U+9b96-9b97, U+9b9a, U+9b9d-9ba0, U+9ba6-9ba7, U+9ba9-9baa, U+9bac, U+9bb0-9bb2, U+9bb4, U+9bb7-9bb9, U+9bbb-9bbc, U+9bbe-9bc1, U+9bc6-9bc8, U+9bca, U+9bce-9bd2, U+9bd4, U+9bd7-9bd8, U+9bdd, U+9bdf, U+9be1-9be5, U+9be7, U+9bea-9beb, U+9bee-9bf3, U+9bf5, U+9bf7-9bfa, U+9bfd, U+9bff-9c00, U+9c02, U+9c04, U+9c06, U+9c08-9c0d, U+9c0f-9c16, U+9c18-9c1e, U+9c21-9c2a, U+9c2d-9c32, U+9c35-9c37, U+9c39-9c3a, U+9c3d;
}
/* [8] */
#font-face {
font-family: 'Train One';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/trainone/v13/gyB-hwkiNtc6KnxUVjWHP87JR5-7NdB589yspgpx0N7r5-25NB8.8.woff2) format('woff2');
unicode-range: U+98eb, U+98ed-98ee, U+98f0-98f1, U+98f3, U+98f6, U+9902, U+9907-9909, U+9911-9912, U+9914-9918, U+991a-9922, U+9924, U+9926-9927, U+992b-992c, U+992e, U+9931-9935, U+9939-993e, U+9940-9942, U+9945-9949, U+994b-994e, U+9950-9952, U+9954-9955, U+9958-9959, U+995b-995c, U+995e-9960, U+9963, U+9997-9998, U+999b, U+999d-999f, U+99a3, U+99a5-99a6, U+99a8, U+99ad-99ae, U+99b0-99b2, U+99b5, U+99b9-99ba, U+99bc-99bd, U+99bf, U+99c1, U+99c3, U+99c8-99c9, U+99d1, U+99d3-99d5, U+99d8-99df, U+99e1-99e2, U+99e7, U+99ea-99ee, U+99f0-99f2, U+99f4-99f5, U+99f8-99f9, U+99fb-99fe, U+9a01-9a05, U+9a08, U+9a0a-9a0c, U+9a0f-9a11, U+9a16, U+9a1a, U+9a1e, U+9a20, U+9a22-9a24, U+9a27, U+9a2b, U+9a2d-9a2e, U+9a31, U+9a33, U+9a35-9a38, U+9a3e, U+9a40-9a45, U+9a47, U+9a4a-9a4e, U+9a51-9a52, U+9a54-9a58, U+9a5b, U+9a5d, U+9a5f, U+9a62, U+9a64-9a65, U+9a69-9a6c, U+9aaa, U+9aac-9ab0, U+9ab2, U+9ab4-9ab7, U+9ab9, U+9abb-9ac1, U+9ac3, U+9ac6, U+9ac8, U+9ace-9ad3, U+9ad5-9ad7, U+9adb-9adc, U+9ade-9ae0, U+9ae2-9ae4;
}
/* [9] */
#font-face {
font-family: 'Train One';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/trainone/v13/gyB-hwkiNtc6KnxUVjWHP87JR5-7NdB589yspgpx0N7r5-25NB8.9.woff2) format('woff2');
unicode-range: U+971d, U+9721-9724, U+9728, U+972a, U+9730-9731, U+9733, U+9736, U+9738-9739, U+973b, U+973d-973e, U+9741-9744, U+9746-974a, U+974d-974f, U+9751, U+9755, U+9757-9758, U+975a-975c, U+9760-9761, U+9763-9764, U+9766-9768, U+976a-976b, U+976e, U+9771, U+9773, U+9776-977d, U+977f-9781, U+9785-9786, U+9789, U+978b, U+978f-9790, U+9795-9797, U+9799-979a, U+979c, U+979e-97a0, U+97a2-97a3, U+97a6, U+97a8, U+97ab-97ac, U+97ae, U+97b1-97b6, U+97b8-97ba, U+97bc, U+97be-97bf, U+97c1, U+97c3-97ce, U+97d0-97d1, U+97d4, U+97d7-97d9, U+97db-97de, U+97e0-97e1, U+97e4, U+97e6, U+97ed-97ef, U+97f1-97f2, U+97f4-97f8, U+97fa, U+9804, U+9807, U+980a, U+980c-980f, U+9814, U+9816-9817, U+9819-981a, U+981c, U+981e, U+9820-9821, U+9823-9826, U+982b, U+982e-9830, U+9832-9835, U+9837, U+9839, U+983d-983e, U+9844, U+9846-9847, U+984a-984b, U+984f, U+9851-9853, U+9856-9857, U+9859-985b, U+9862-9863, U+9865-9866, U+986a-986c, U+986f-9871, U+9873-9875, U+98aa-98ab, U+98ad-98ae, U+98b0-98b1, U+98b4, U+98b6-98b8, U+98ba-98bc, U+98bf, U+98c2-98c8, U+98cb-98cc, U+98ce, U+98dc, U+98de, U+98e0-98e1, U+98e3, U+98e5-98e7, U+98e9-98ea;
}
/* The list goes on to [117] ... */
Roboto has unicode-ranges with the subset's name commented above each #font-face statement, while Train One seems to have ever expanding unicode-ranges with numbers commented above each #font-face statement. The list goes on till 117, btw.
The reason why I'm curious, is because it seems to load three font files, just to display Latin characters.
Is this just a very inefficiently built stylesheet, or is there a specific reason why the stylesheet is built this way?
BTW. if it isn't clear, this is a question specifically regarding the Google Fonts API and the way it generates stylesheets. I understand what unicode-ranges are used for. I just don't understand what the Google Fonts API is trying to achieve with such a large amount of #font-face statements and unicode-ranges.

Related

Shouldn't #next/font optimization remove #font-face code blocks for unicode-ranges not required? If not, can it be removed to reduce css file size?

I'm following Next's guide to optimize fonts
I added the font export:
src/style/fonts.ts
import { Montserrat } from '#next/font/google';
export const montserrat = Montserrat({
weight: ['500', '600', '700'],
display: 'swap',
preload: true,
subsets: ['latin'],
});
What I get in the network request response for the css includes this:
#font-face {
font-family: __Montserrat_4a3ba4;
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(/_next/static/media/df4ba022c23c08de.woff2) format("woff2");
unicode-range: U+0460-052f,U+1c80-1c88,U+20b4,U+2de0-2dff,U+a640-a69f,U+fe2e-fe2f
}
#font-face {
font-family: __Montserrat_4a3ba4;
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(/_next/static/media/b1464bad92c88a2d.woff2) format("woff2");
unicode-range: U+0301,U+0400-045f,U+0490-0491,U+04b0-04b1,U+2116
}
#font-face {
font-family: __Montserrat_4a3ba4;
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(/_next/static/media/8ed0c04f7e5d7b36.woff2) format("woff2");
unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01a0-01a1,U+01af-01b0,U+1ea0-1ef9,U+20ab
}
#font-face {
font-family: __Montserrat_4a3ba4;
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(/_next/static/media/c528baaebca50056.woff2) format("woff2");
unicode-range: U+0100-024f,U+0259,U+1e??,U+2020,U+20a0-20ab,U+20ad-20cf,U+2113,U+2c60-2c7f,U+a720-a7ff
}
#font-face {
font-family: __Montserrat_4a3ba4;
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(/_next/static/media/1060bab20f18b5c2.p.woff2) format("woff2");
unicode-range: U+00??,U+0131,U+0152-0153,U+02bb-02bc,U+02c6,U+02da,U+02dc,U+2000-206f,U+2074,U+20ac,U+2122,U+2191,U+2193,U+2212,U+2215,U+feff,U+fffd
}
These have unicode ranges that correspond to subsets not included in fonts.tsx. They also point to src urls non-existant (non-latin ones). Perhaps it's some issue with SASS, I'm not sure. My question is, shouldn't all but latin be removed as specified in subsets in fonts.ts?
I tried all methods described in Next's documentation yielding the same results. This might not necessarily be an issue, but since CSS files sizes affect SEO I imagined that those code blocks shouldn't be there as part of Next's optimization. Specially since they are pointing to files that don't exist.
Dependencies in case they are relevant:
"dependencies": {
"#apollo/client": "^3.5.5",
"#elastic/elasticsearch": "^8.4.0",
"#newrelic/next": "^0.3.1",
"#next/font": "^13.0.2",
"#sentry/nextjs": "^7.16.0",
"#snowplow/browser-tracker": "^3.2.1",
"#types/react-scroll": "^1.8.3",
"#types/styled-components": "^5.1.15",
"apollo-link-timeout": "^4.0.0",
"apollo-upload-client": "^16.0.0",
"date-fns": "^2.29.3",
"dayjs": "^1.11.3",
"email-validator": "^2.0.4",
"expo-jwt": "^1.4.1",
"express": "^4.18.1",
"firebase": "^9.6.1",
"graphql": "^16.0.1",
"grommet": "^2.19.1",
"i18next": "^21.5.5",
"ioredis": "^5.2.3",
"js-base64": "^3.7.2",
"lodash.flatten": "^4.4.0",
"lodash.uniqby": "^4.7.0",
"lru-cache": "^7.14.0",
"newrelic": "^9.3.0",
"next": "^13.0.0",
"polished": "^4.1.3",
"react": "^18.2.0",
"react-cookie": "^4.1.1",
"react-dom": "^18.2.0",
"react-hook-form": "^7.24.1",
"react-hot-toast": "^2.4.0",
"react-i18next": "^11.14.3",
"react-icons": "^4.3.1",
"react-intersection-observer": "^8.33.1",
"react-loading-skeleton": "^3.0.1",
"react-scroll": "^1.8.4",
"react-slick": "^0.29.0",
"react-transition-group": "^4.4.2",
"sass": "^1.43.4",
"shortid": "^2.2.16",
"styled-components": "^5.3.3",
"uuid": "^8.3.2",
"winston": "^3.8.2",
"winston-elasticsearch": "^0.17.1"
}

How to import fontsource font with subset in Vite

I have made a simple Vue3 + Vite project and used the Inter font from fontsource with latin and latin-ext subset like this:
npm i #fontsource/inter
SCSS import:
#import '#fontsource/inter/latin.css';
#import '#fontsource/inter/latin-ext.css';
body, html {
font-family: 'Inter';
}
While this works flawlessly when served via vite, the font breaks after building with vite build. Only the characters from latin-ext subset display correctly. There are no errors in the browser, I can also see the required font files in the build directory as well as in the build log:
dist/assets/inter-latin-100-normal.61cac109.woff2 16.16 KiB
dist/assets/inter-latin-700-normal.ced2d8e0.woff2 17.37 KiB
dist/assets/inter-latin-400-normal.0364d368.woff2 16.32 KiB
dist/assets/inter-latin-300-normal.6b2cee46.woff2 16.92 KiB
dist/assets/inter-latin-200-normal.74885a0c.woff2 16.94 KiB
dist/assets/inter-latin-600-normal.048d136d.woff2 17.25 KiB
dist/assets/inter-latin-900-normal.f2db7f82.woff2 16.77 KiB
dist/assets/inter-latin-800-normal.a51ac27d.woff2 17.35 KiB
dist/assets/inter-latin-ext-100-normal.d3be20b3.woff2 19.92 KiB
dist/assets/inter-latin-ext-300-normal.34623012.woff2 21.34 KiB
dist/assets/inter-latin-500-normal.d5333670.woff2 17.14 KiB
dist/assets/inter-latin-ext-500-normal.4fba9ae6.woff2 21.81 KiB
dist/assets/inter-latin-ext-700-normal.1cc47d25.woff2 22.09 KiB
dist/assets/inter-latin-ext-400-normal.64a98f58.woff2 19.95 KiB
dist/assets/inter-latin-ext-200-normal.4336e69d.woff2 21.45 KiB
dist/assets/inter-latin-ext-600-normal.cc23fe6f.woff2 21.92 KiB
dist/assets/inter-latin-ext-900-normal.3cff82a5.woff2 21.26 KiB
dist/assets/inter-latin-ext-800-normal.b6167428.woff2 22.11 KiB
dist/assets/inter-latin-100-normal.8b9e4e8a.woff 20.74 KiB
dist/assets/inter-latin-700-normal.51df444d.woff 22.15 KiB
dist/assets/inter-latin-300-normal.48602fcd.woff 21.64 KiB
dist/assets/inter-latin-600-normal.22b2f9fb.woff 22.11 KiB
dist/assets/inter-latin-400-normal.3ea830d4.woff 20.92 KiB
dist/assets/inter-latin-900-normal.c38e95e0.woff 21.46 KiB
dist/assets/inter-latin-200-normal.3df10d85.woff 21.71 KiB
dist/assets/inter-latin-ext-100-normal.e2338738.woff 43.34 KiB
dist/assets/inter-latin-ext-300-normal.4118491a.woff 45.38 KiB
dist/assets/inter-latin-500-normal.2514f3df.woff 21.99 KiB
dist/assets/inter-latin-800-normal.d08d7178.woff 22.18 KiB
dist/assets/inter-latin-ext-500-normal.c1ea9351.woff 46.31 KiB
dist/assets/inter-latin-ext-700-normal.ab946822.woff 46.80 KiB
dist/assets/inter-latin-ext-400-normal.33bbf334.woff 43.10 KiB
dist/assets/inter-latin-ext-200-normal.ff6f9abd.woff 45.52 KiB
dist/assets/inter-latin-ext-600-normal.debf2949.woff 46.66 KiB
dist/assets/inter-latin-ext-900-normal.dbda8df9.woff 45.33 KiB
dist/assets/inter-latin-ext-800-normal.16afe65f.woff 46.82 KiB
When swapping the order of the imports, it's the opposite - all text is in Inter except the latin-ext characters. It starts working fine when I import the whole font:
#import '#fontsource/inter';
But that makes the whole fontsource thing kinda useless, since it bloats my bundle with useless font files.
I have narrowed down the issue to missing font-face registration in the built CSS file. Only fonts from the last import are present, despite all files being included in the bundle:
#font-face {
font-family: Inter;
font-style: normal;
font-display: swap;
font-weight: 100;
src: url(./inter-latin-ext-100-normal.d3be20b3.woff2) format("woff2"), url(./inter-latin-ext-100-normal.e2338738.woff) format("woff");
}
#font-face {
font-family: Inter;
font-style: normal;
font-display: swap;
font-weight: 200;
src: url(./inter-latin-ext-200-normal.4336e69d.woff2) format("woff2"), url(./inter-latin-ext-200-normal.ff6f9abd.woff) format("woff");
}
#font-face {
font-family: Inter;
font-style: normal;
font-display: swap;
font-weight: 300;
src: url(./inter-latin-ext-300-normal.34623012.woff2) format("woff2"), url(./inter-latin-ext-300-normal.4118491a.woff) format("woff");
}
#font-face {
font-family: Inter;
font-style: normal;
font-display: swap;
font-weight: 400;
src: url(./inter-latin-ext-400-normal.64a98f58.woff2) format("woff2"), url(./inter-latin-ext-400-normal.33bbf334.woff) format("woff");
}
#font-face {
font-family: Inter;
font-style: normal;
font-display: swap;
font-weight: 500;
src: url(./inter-latin-ext-500-normal.4fba9ae6.woff2) format("woff2"), url(./inter-latin-ext-500-normal.c1ea9351.woff) format("woff");
}
#font-face {
font-family: Inter;
font-style: normal;
font-display: swap;
font-weight: 600;
src: url(./inter-latin-ext-600-normal.cc23fe6f.woff2) format("woff2"), url(./inter-latin-ext-600-normal.debf2949.woff) format("woff");
}
#font-face {
font-family: Inter;
font-style: normal;
font-display: swap;
font-weight: 700;
src: url(./inter-latin-ext-700-normal.1cc47d25.woff2) format("woff2"), url(./inter-latin-ext-700-normal.ab946822.woff) format("woff");
}
#font-face {
font-family: Inter;
font-style: normal;
font-display: swap;
font-weight: 800;
src: url(./inter-latin-ext-800-normal.b6167428.woff2) format("woff2"), url(./inter-latin-ext-800-normal.16afe65f.woff) format("woff");
}
#font-face {
font-family: Inter;
font-style: normal;
font-display: swap;
font-weight: 900;
src: url(./inter-latin-ext-900-normal.3cff82a5.woff2) format("woff2"), url(./inter-latin-ext-900-normal.dbda8df9.woff) format("woff");
}
Is this some bug in Vite, or do I need to do something more in order to achieve the same behavior as in debug builds?

FontAwesome 5 javax.el.ELException: Failed to parse the expression [#{resource['atlas-layout:fonts/fa-brands-400.eot]}]

I am new to CSS & Font awesome world, I got an issue while updating my Font Awesome from 4.4.0 to 5.0.10 in primfaces atlas theme,
here is the exception
Caused by: org.apache.el.parser.ParseException: Encountered " <ILLEGAL_CHARACTER> "\' "" at line 1, column 12.
Was expecting one of:
"{" ...
<INTEGER_LITERAL> ...
<FLOATING_POINT_LITERAL> ...
<STRING_LITERAL> ...
"true" ...
"false" ...
"null" ...
"(" ...
"[" ...
"!" ...
"not" ...
"empty" ...
"-" ...
<IDENTIFIER> ...
<IDENTIFIER> ...
"(" ...
at org.apache.el.parser.ELParser.generateParseException(ELParser.java:3090)
And my
fa fa icons working fine, but not the new ones like FAB,FAR
I have added files which I downloaded from fontAwesome and replaced with old one,
And Edited the font-awesome.css
#font-face {
font-family: 'Font Awesome 5 Brands';
font-style: normal;
font-weight: normal;
src: url("#{resource['atlas-layout:fonts/fa-brands-400.eot]}");
src: url("#{resource['atlas-layout:fonts/fa-brands-400.eot]}?#iefix") format("embedded-opentype"), url("#{resource['atlas-layout:fonts/fa-brands-400.woff2]}") format("woff2"), url("#{resource['atlas-layout:fonts/fa-brands-400.woff]}") format("woff"), url("#{resource['atlas-layout:fonts/fa-brands-400.ttf]}") format("truetype"), url("#{resource['atlas-layout:fonts/fa-brands-400.svg]}#fontawesome") format("svg"); }
.fab {
font-family: 'Font Awesome 5 Brands'; }
#font-face {
font-family: 'Font Awesome 5 Free';
font-style: normal;
font-weight: 400;
src: url("#{resource['atlas-layout:fonts/fa-regular-400.eot]}");
src: url("#{resource['atlas-layout:fonts/fa-regular-400.eot]}?#iefix") format("embedded-opentype"), url("#{resource['atlas-layout:fonts/fa-regular-400.woff2]}") format("woff2"), url("#{resource['atlas-layout:fonts/fa-regular-400.woff]}") format("woff"), url("#{resource['atlas-layout:fonts/fa-regular-400.ttf]}") format("truetype"), url("#{resource['atlas-layout:fonts/fa-regular-400.svg]}#fontawesome") format("svg"); }
.far {
font-family: 'Font Awesome 5 Free';
font-weight: 400; }
#font-face {
font-family: 'Font Awesome 5 Free';
font-style: normal;
font-weight: 900;
src: url("#{resource['atlas-layout:fonts/fa-solid-900.eot]}");
src: url("#{resource['atlas-layout:fonts/fa-solid-900.eot]}?#iefix") format("embedded-opentype"), url("#{resource['atlas-layout:fonts/fa-solid-900.woff2]}") format("woff2"), url("#{resource['atlas-layout:fonts/fa-solid-900.woff]}") format("woff"), url("#{resource['atlas-layout:fonts/fa-solid-900.ttf]}") format("truetype"), url("#{resource['atlas-layout:fonts/fa-solid-900.svg]}#fontawesome") format("svg"); }
.fa,
.fas {
font-family: 'Font Awesome 5 Free';
font-weight: 900; }
please help on this
The error seems to be completely correct. In EACH of the
#{resource['atlas-layout:fonts/fa-brands-400.eot]}
You have a single 'open' quote after the [ but not a 'closing' one before the ]. Easy to find when you compare with the original PrimeFaces ones.

Font rendering in Chrome (woff2) - after load font family doesn't want to change

To prevent font rendering lags related to font loading time I wrote some simple script which load CSS containing #font-face and custom fonts with some delay. Thanks to that solution, by default system fonts are used (no lag) and later they are overwrite by new CSS with new fonts. However, solution works everywhere except Chrome. In chrome network tab I can see that fonts were loaded but somehow they were not re-rendered.
How it looks in IE, and Firefox (desired fonts):
And Chrome (system fonts):
HTML:
<link data-href="/assets/v2/default/css/font-loader.css" rel="stylesheet" type="text/css" data-mobile="true"/>
Default CSS:
body{
font-family: sans-serif;
}
.price{
text-align: right;
font-size: 22px;
font-family: sans-serif;
letter-spacing: 0.01em;
}
Loaded CSS:
#font-face {
font-family: 'PT Sans';
font-style: normal;
font-weight: 400;
src: local('PT Sans'),
local('PTSans-Regular'),
url('https://fonts.gstatic.com/s/ptsans/v8/JX7MlXqjSJNjQvI4heMMGvY6323mHUZFJMgTvxaG2iE.woff2') format('woff2'),
url('http://fonts.gstatic.com/s/ptsans/v8/LKf8nhXsWg5ybwEGXk8UBQ.woff') format('woff'),
url('../fonts/PT_Sans-Regular.woff2') format('woff2'),
url('../fonts/PT_Sans-Regular.woff') format('woff'),
url('../fonts/PT_Sans-Web-Regular.ttf') format('truetype');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
#font-face {
font-family: 'PT Sans Narrow';
font-style: normal;
font-weight: 400;
src: local('PT Sans Narrow'),
local('PTSans-Narrow'),
url('https://fonts.gstatic.com/s/ptsansnarrow/v7/UyYrYy3ltEffJV9QueSi4SppsHecKHw584ktcwPXSnc.woff2') format('woff2'),
url('https://fonts.gstatic.com/s/ptsansnarrow/v7/UyYrYy3ltEffJV9QueSi4RdbPw3QSf9R-kE0EsQUn2A.woff') format('woff'),
url('../fonts/PT_Sans-Narrow-Web-Regular.woff2') format('woff2'),
url('../fonts/PT_Sans-Narrow-Web-Regular.woff') format('woff'),
url('../fonts/PT_Sans-Narrow-Web-Regular.ttf') format('truetype');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
body{
font-family: 'PT Sans', sans-serif;
}
.price{
font-weight: normal;
font-family: 'PT Sans Narrow', sans-serif;
letter-spacing: normal;
font-size: 30px;
}
JS:
(function (document) {
var loadScripts = function () {
var uaString = navigator.userAgent,
isMobile = function () {
return uaString.indexOf('android') > -1 || uaString.indexOf('Android') > -1 || uaString.indexOf('Mobile') > -1 || uaString.indexOf('mobile') > -1 || uaString.indexOf('iPhone') > -1
};
this.styles = document.querySelectorAll('link[data-href]');
for (var i = 0; i < this.styles.length; i++) {
if (this.styles[i].getAttribute('data-mobile') === 'false' && isMobile()) {
return;
}
this.styles[i].setAttribute('href', this.styles[i].getAttribute('data-href'));
}
};
if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', loadScripts);
} else {
document.attachEvent('onreadystatechange', function (e) {
if (document.readyState === "complete") {
loadScripts();
}
});
}
}(document));
The woff2 file you specified does not have latin characters.
You must have copied the URL of the "cyrillic-ext" subset of the font.
You should use the 'latin' subset. Change the url of woff2 to this:
url('https://fonts.gstatic.com/s/ptsansnarrow/v7/UyYrYy3ltEffJV9QueSi4UU-p1xzoRgkupcXIqgYFBc.woff2') format('woff2'),
The issue only occur with WOFF2 font, when I changed code to:
#font-face {
font-family: 'PT Sans Narrow';
font-style: normal;
font-weight: 400;
src: local('PT Sans Narrow'),
local('PTSans-Narrow'),
/*Remove woff2 from here and load woff instead*/
url(https://fonts.gstatic.com/s/ptsansnarrow/v7/UyYrYy3ltEffJV9QueSi4RdbPw3QSf9R-kE0EsQUn2A.woff) format('woff'),
url(../fonts/PT_Sans-Narrow-Web-Regular.woff2) format('woff2'),
url(../fonts/PT_Sans-Narrow-Web-Regular.woff) format('woff'),
url(../fonts/PT_Sans-Narrow-Web-Regular.ttf) format('truetype');
}
It works fine.

SASS and #font-face

I have the following CSS - how would I describe it in SASS? I've tried reverse compiling it with css2sass, and just keep getting errors.... is it my CSS (which works ;-) )?
#font-face {
font-family: 'bingo';
src: url("bingo.eot");
src: local('bingo'),
url("bingo.svg#bingo") format('svg'),
url("bingo.otf") format('opentype');
}
In case anyone was wondering - it was probably my css...
#font-face
font-family: "bingo"
src: url('bingo.eot')
src: local('bingo')
src: url('bingo.svg#bingo') format('svg')
src: url('bingo.otf') format('opentype')
will render as
#font-face {
font-family: "bingo";
src: url('bingo.eot');
src: local('bingo');
src: url('bingo.svg#bingo') format('svg');
src: url('bingo.otf') format('opentype'); }
which seems to be close enough... just need to check the SVG rendering
I’ve been struggling with this for a while now. Dycey’s solution is correct in that specifying the src multiple times outputs the same thing in your css file. However, this seems to break in OSX Firefox 23 (probably other versions too, but I don’t have time to test).
The cross-browser #font-face solution from Font Squirrel looks like this:
#font-face {
font-family: 'fontname';
src: url('fontname.eot');
src: url('fontname.eot?#iefix') format('embedded-opentype'),
url('fontname.woff') format('woff'),
url('fontname.ttf') format('truetype'),
url('fontname.svg#fontname') format('svg');
font-weight: normal;
font-style: normal;
}
To produce the src property with the comma-separated values, you need to write all of the values on one line, since line-breaks are not supported in Sass. To produce the above declaration, you would write the following Sass:
#font-face
font-family: 'fontname'
src: url('fontname.eot')
src: url('fontname.eot?#iefix') format('embedded-opentype'), url('fontname.woff') format('woff'), url('fontname.ttf') format('truetype'), url('fontname.svg#fontname') format('svg')
font-weight: normal
font-style: normal
I think it seems silly to write out the path a bunch of times, and I don’t like overly long lines in my code, so I worked around it by writing this mixin:
=font-face($family, $path, $svg, $weight: normal, $style: normal)
#font-face
font-family: $family
src: url('#{$path}.eot')
src: url('#{$path}.eot?#iefix') format('embedded-opentype'), url('#{$path}.woff') format('woff'), url('#{$path}.ttf') format('truetype'), url('#{$path}.svg##{$svg}') format('svg')
font-weight: $weight
font-style: $style
Usage: For example, I can use the previous mixin to setup up the Frutiger Light font like this:
+font-face('frutigerlight', '../fonts/frutilig-webfont', 'frutigerlight')
For those looking for an SCSS mixin instead, including woff2, SASS list.append is useful for conditionally adding source files/formats:
#mixin fface(
$path,
$family,
$type: "",
$weight: 400,
$style: normal,
$local1: null,
$local2: null,
$ttf: null,
$otf: null,
$eot: null,
$svg: null
) {
$src: null; // initialize an empty source path
// only load local files when both sources are present
#if $local1 and $local2 {
$src: append($src, local("#{$local1}"), comma);
$src: append($src, local("#{$local2}"), comma);
}
#if $otf {
$src: append($src, url("#{$path}#{$type}.otf") format("opentype"), comma);
}
// load default formats (woff and woff2)
$src: append($src, url("#{$path}#{$type}.woff2") format("woff2"), comma);
$src: append($src, url("#{$path}#{$type}.woff") format("woff"), comma);
// formats that should only be added at the end
#if $ttf {
$src: append($src, url("#{$path}#{$type}.ttf") format("truetype"), comma);
}
#if $svg {
$src: append($src, url("#{$path}#{$type}.svg##{$svg}") format("svg"), comma);
}
// the actual FONT FACE DECLARATION
#font-face {
font-family: $family;
// for compatibility reasons EOT comes first and is not appended
#if $eot {
src: url("#{$path}#{$type}.eot");
}
// load appended sources path
src: $src;
font-weight: $weight;
font-style: $style;
}
}
// USAGE
$dir: "assets/fonts/";
// declare family name
$familyName: "MyFont";
#include fface(
"#{$dir}#{$familyName}", $familyName, "-regular", 400, "normal",
"#{$familyName} Regular", "#{$familyName}-Regular", "ttf", "otf"
);
#include fface(
"#{$dir}#{$familyName}", $familyName, "-medium", 500, "normal",
"#{$familyName} Medium", "#{$familyName}-Medium", "ttf", "otf"
);
#include fface(
"#{$dir}#{$familyName}", $familyName, "-semibold", 600, "normal",
"#{$familyName} SemiBold", "#{$familyName}-SemiBold", "ttf", "otf"
);
// Material Icons
$familyName: "Material Icons"; // override previous value
$familyFileName: "MaterialIcons";
#include fface(
"#{$dir}#{$familyFileName}", $familyName, "-regular", 400, "normal",
$familyName, "#{$familyFileName}-Regular", "ttf", null, "eot"
);
#include fface(
"#{$dir}#{$familyFileName}", "#{$familyName} Outline", "-outline", 400, "normal",
"#{$familyName} Outline", "#{$familyFileName}-Outline", null, "otf", "eot"
);
.material-icons {
font-family: $familyName;
}
.material-icons-outline {
font-family: "#{$familyName} Outline";
}
The $type parameter is used for locating different files within a $family.
If you get a can't resolve error, remember to double check your fonts directory ($dir).
In my case I use SASS Mixin:
#mixin font-face($family, $file, $path, $svg, $weight: normal, $style: normal)
#font-face
font-family: $family
src: url($path + $file + '.eot')
src: url($path + $file + '.eot?#iefix') format('embedded-opentype'), url($path + $file + '.woff') format('woff'), url($path + $file + '.ttf') format('truetype'), url($path + $file + '.svg##{$svg}') format('svg')
font-weight: $weight
font-style: $style
Usage:
#include font-face('altivo', 'altivo-regular', '', 'altivo-regular')
#include font-face('altivo', 'altivo-medium', '', 'altivo-medium', 500, normal)
#include font-face('altivo', 'altivo-bold', '', 'altivo-bold', 700, normal)
#include font-face('corsa', 'corsa-grotesk-regular', '', 'corsa-grotesk-regular')
#include font-face('corsa', 'corsa-grotesk-medium', '', 'corsa-grotesk-medium', 500, normal)
#include font-face('corsa', 'corsa-grotesk-bold', '', 'corsa-grotesk-bold', 700, normal)
#include font-face('corsa', 'corsa-grotesk-xbold', '', 'corsa-grotesk-xbold', 800, normal)
Result:
#font-face {
font-family: "altivo";
src: url("altivo-regular.eot");
src: url("altivo-regular.eot?#iefix") format("embedded-opentype"), url("altivo-regular.woff") format("woff"), url("altivo-regular.ttf") format("truetype"), url("altivo-regular.svg#altivo-regular") format("svg");
font-weight: normal;
font-style: normal;
}
#font-face {
font-family: "altivo";
src: url("altivo-medium.eot");
src: url("altivo-medium.eot?#iefix") format("embedded-opentype"), url("altivo-medium.woff") format("woff"), url("altivo-medium.ttf") format("truetype"), url("altivo-medium.svg#altivo-medium") format("svg");
font-weight: 500;
font-style: normal;
}
#font-face {
font-family: "altivo";
src: url("altivo-bold.eot");
src: url("altivo-bold.eot?#iefix") format("embedded-opentype"), url("altivo-bold.woff") format("woff"), url("altivo-bold.ttf") format("truetype"), url("altivo-bold.svg#altivo-bold") format("svg");
font-weight: 700;
font-style: normal;
}
#font-face {
font-family: "corsa";
src: url("corsa-grotesk-regular.eot");
src: url("corsa-grotesk-regular.eot?#iefix") format("embedded-opentype"), url("corsa-grotesk-regular.woff") format("woff"), url("corsa-grotesk-regular.ttf") format("truetype"), url("corsa-grotesk-regular.svg#corsa-grotesk-regular") format("svg");
font-weight: normal;
font-style: normal;
}
#font-face {
font-family: "corsa";
src: url("corsa-grotesk-medium.eot");
src: url("corsa-grotesk-medium.eot?#iefix") format("embedded-opentype"), url("corsa-grotesk-medium.woff") format("woff"), url("corsa-grotesk-medium.ttf") format("truetype"), url("corsa-grotesk-medium.svg#corsa-grotesk-medium") format("svg");
font-weight: 500;
font-style: normal;
}
#font-face {
font-family: "corsa";
src: url("corsa-grotesk-bold.eot");
src: url("corsa-grotesk-bold.eot?#iefix") format("embedded-opentype"), url("corsa-grotesk-bold.woff") format("woff"), url("corsa-grotesk-bold.ttf") format("truetype"), url("corsa-grotesk-bold.svg#corsa-grotesk-bold") format("svg");
font-weight: 700;
font-style: normal;
}
#font-face {
font-family: "corsa";
src: url("corsa-grotesk-xbold.eot");
src: url("corsa-grotesk-xbold.eot?#iefix") format("embedded-opentype"), url("corsa-grotesk-xbold.woff") format("woff"), url("corsa-grotesk-xbold.ttf") format("truetype"), url("corsa-grotesk-xbold.svg#corsa-grotesk-xbold") format("svg");
font-weight: 800;
font-style: normal;
}

Resources