CSS 如何向基于 create-react-app 的项目添加字体?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/41676054/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add fonts to create-react-app based projects?
提问by Maxim Veksler
I'm using create-react-appand prefer not to eject
.
我正在使用create-react-app而不想使用eject
.
It's not clear where fonts imported via @font-face and loaded locally should go.
目前尚不清楚通过@font-face 导入并在本地加载的字体应该放在哪里。
Namely, I'm loading
也就是说,我正在加载
@font-face {
font-family: 'Myriad Pro Regular';
font-style: normal;
font-weight: normal;
src: local('Myriad Pro Regular'), url('MYRIADPRO-REGULAR.woff') format('woff');
}
Any suggestions?
有什么建议?
-- EDIT
- 编辑
Including the gist to which Dan referring in his answer
包括丹在他的回答中提到的要点
? Client git:(feature/trivia-game-ui-2) ? ls -l public/static/fonts
total 1168
-rwxr-xr-x@ 1 maximveksler staff 62676 Mar 17 2014 MYRIADPRO-BOLD.woff
-rwxr-xr-x@ 1 maximveksler staff 61500 Mar 17 2014 MYRIADPRO-BOLDCOND.woff
-rwxr-xr-x@ 1 maximveksler staff 66024 Mar 17 2014 MYRIADPRO-BOLDCONDIT.woff
-rwxr-xr-x@ 1 maximveksler staff 66108 Mar 17 2014 MYRIADPRO-BOLDIT.woff
-rwxr-xr-x@ 1 maximveksler staff 60044 Mar 17 2014 MYRIADPRO-COND.woff
-rwxr-xr-x@ 1 maximveksler staff 64656 Mar 17 2014 MYRIADPRO-CONDIT.woff
-rwxr-xr-x@ 1 maximveksler staff 61848 Mar 17 2014 MYRIADPRO-REGULAR.woff
-rwxr-xr-x@ 1 maximveksler staff 62448 Mar 17 2014 MYRIADPRO-SEMIBOLD.woff
-rwxr-xr-x@ 1 maximveksler staff 66232 Mar 17 2014 MYRIADPRO-SEMIBOLDIT.woff
? Client git:(feature/trivia-game-ui-2) ? cat src/containers/GameModule.css
.GameModule {
padding: 15px;
}
@font-face {
font-family: 'Myriad Pro Regular';
font-style: normal;
font-weight: normal;
src: local('Myriad Pro Regular'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-REGULAR.woff') format('woff');
}
@font-face {
font-family: 'Myriad Pro Condensed';
font-style: normal;
font-weight: normal;
src: local('Myriad Pro Condensed'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-COND.woff') format('woff');
}
@font-face {
font-family: 'Myriad Pro Semibold Italic';
font-style: normal;
font-weight: normal;
src: local('Myriad Pro Semibold Italic'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-SEMIBOLDIT.woff') format('woff');
}
@font-face {
font-family: 'Myriad Pro Semibold';
font-style: normal;
font-weight: normal;
src: local('Myriad Pro Semibold'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-SEMIBOLD.woff') format('woff');
}
@font-face {
font-family: 'Myriad Pro Condensed Italic';
font-style: normal;
font-weight: normal;
src: local('Myriad Pro Condensed Italic'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-CONDIT.woff') format('woff');
}
@font-face {
font-family: 'Myriad Pro Bold Italic';
font-style: normal;
font-weight: normal;
src: local('Myriad Pro Bold Italic'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-BOLDIT.woff') format('woff');
}
@font-face {
font-family: 'Myriad Pro Bold Condensed Italic';
font-style: normal;
font-weight: normal;
src: local('Myriad Pro Bold Condensed Italic'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-BOLDCONDIT.woff') format('woff');
}
@font-face {
font-family: 'Myriad Pro Bold Condensed';
font-style: normal;
font-weight: normal;
src: local('Myriad Pro Bold Condensed'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-BOLDCOND.woff') format('woff');
}
@font-face {
font-family: 'Myriad Pro Bold';
font-style: normal;
font-weight: normal;
src: local('Myriad Pro Bold'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-BOLD.woff') format('woff');
}
回答by Dan Abramov
There are two options:
有两种选择:
Using Imports
使用导入
This is the suggested option. It ensures your fonts go through the build pipeline, get hashes during compilation so that browser caching works correctly, and that you get compilation errors if the files are missing.
这是建议的选项。它确保您的字体通过构建管道,在编译期间获得哈希值,以便浏览器缓存正常工作,并且如果文件丢失,您将收到编译错误。
As described in “Adding Images, Fonts, and Files”, you need to have a CSS file imported from JS. For example, by default src/index.js
imports src/index.css
:
如“添加图像、字体和文件”中所述,您需要有一个从 JS 导入的 CSS 文件。例如,默认情况下src/index.js
导入src/index.css
:
import './index.css';
A CSS file like this goes through the build pipeline, and can reference fonts and images. For example, if you put a font in src/fonts/MyFont.woff
, your index.css
might include this:
像这样的 CSS 文件通过构建管道,可以引用字体和图像。例如,如果您将字体放入src/fonts/MyFont.woff
,则index.css
可能包含以下内容:
@font-face {
font-family: 'MyFont';
src: local('MyFont'), url(./fonts/MyFont.woff) format('woff');
}
Notice how we're using a relative path starting with ./
. This is a special notation that helps the build pipeline (powered by Webpack) discover this file.
请注意我们如何使用以 开头的相对路径./
。这是一个特殊的符号,可以帮助构建管道(由 Webpack 提供支持)发现这个文件。
Normally this should be enough.
通常这应该足够了。
Using public
Folder
使用public
文件夹
If for some reason you prefer notto use the build pipeline, and instead do it the “classic way”, you can use the public
folderand put your fonts there.
如果由于某种原因您不想使用构建管道,而是使用“经典方式”,您可以使用该public
文件夹并将字体放在那里。
The downside of this approach is that the files don't get hashes when you compile for production so you'll have to update their names every time you change them, or browsers will cache the old versions.
这种方法的缺点是文件在编译生产时不会得到哈希值,因此每次更改它们时都必须更新它们的名称,否则浏览器将缓存旧版本。
If you want to do it this way, put the fonts somewhere into the public
folder, for example, into public/fonts/MyFont.woff
. If you follow this approach, you should put CSS files into public
folder as well and notimport them from JS because mixing these approaches is going to be very confusing. So, if you still want to do it, you'd have a file like public/index.css
. You would have to manually add <link>
to this stylesheet from public/index.html
:
如果要这样做,请将字体放入public
文件夹中的某个位置,例如放入public/fonts/MyFont.woff
. 如果你遵循这种方法,你应该把 CSS 文件也放到public
文件夹中,而不是从 JS 中导入它们,因为混合这些方法会非常混乱。所以,如果你仍然想这样做,你会有一个像public/index.css
. 您必须从以下位置手动添加<link>
到此样式表public/index.html
:
<link rel="stylesheet" href="%PUBLIC_URL%/index.css">
And inside of it, you would use the regular CSS notation:
在其中,您将使用常规的 CSS 符号:
@font-face {
font-family: 'MyFont';
src: local('MyFont'), url(fonts/MyFont.woff) format('woff');
}
Notice how I'm using fonts/MyFont.woff
as the path. This is because index.css
is in the public
folder so it will be served from the public path (usually it's the server root, but if you deploy to GitHub Pages and set your homepage
field to http://myuser.github.io/myproject
, it will be served from /myproject
). However fonts
are also in the public
folder, so they will be served from fonts
relatively (either http://mywebsite.com/fonts
or http://myuser.github.io/myproject/fonts
). Therefore we use the relative path.
注意我是如何fonts/MyFont.woff
用作路径的。这是因为index.css
位于public
文件夹中,因此将从公共路径提供服务(通常它是服务器根目录,但如果您部署到 GitHub Pages 并将您的homepage
字段设置为http://myuser.github.io/myproject
,它将从 提供/myproject
)。但是fonts
也在public
文件夹中,因此它们将从fonts
相对(http://mywebsite.com/fonts
或http://myuser.github.io/myproject/fonts
)提供。因此我们使用相对路径。
Note that since we're avoiding the build pipeline in this example, it doesn't verify that the file actually exists. This is why I don't recommend this approach. Another problem is that our index.css
file doesn't get minified and doesn't get a hash. So it's going to be slower for the end users, and you risk the browsers caching old versions of the file.
请注意,由于我们在此示例中避免了构建管道,因此它不会验证文件是否确实存在。这就是我不推荐这种方法的原因。另一个问题是我们的index.css
文件没有被缩小,也没有得到散列。因此,对于最终用户来说,它会变慢,并且您冒着浏览器缓存旧版本文件的风险。
?Which Way to Use?
?使用哪种方式?
Go with the first method (“Using Imports”). I only described the second one since that's what you attempted to do (judging by your comment), but it has many problems and should only be the last resort when you're working around some issue.
使用第一种方法(“使用导入”)。我只描述了第二个,因为那是你试图做的(根据你的评论判断),但它有很多问题,当你解决一些问题时,它应该只是最后的手段。
回答by sudo bangbang
Here are some ways of doing this:
这里有一些方法可以做到这一点:
1. Importing font
1. 导入字体
For example, for using Roboto, install the package using
例如,要使用 Roboto,请使用以下命令安装软件包
yarn add typeface-roboto
or
或者
npm install typeface-roboto --save
In index.js:
在 index.js 中:
import "typeface-roboto";
There are npm packages for a lot of open source fonts and most of Google fonts. You can see all fonts here. All the packages are from that project.
有很多开源字体和大部分谷歌字体的 npm 包。您可以在此处查看所有字体。所有的包都来自那个项目。
2. For fonts hosted by Third party
2.对于第三方托管的字体
For example Google fonts, you can go to fonts.google.comwhere you can find links that you can put in your public/index.html
例如 Google 字体,您可以访问fonts.google.com,在那里您可以找到可以放在您的public/index.html
It'll be like
它会像
<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet">
or
或者
<style>
@import url('https://fonts.googleapis.com/css?family=Montserrat');
</style>
3. Downloading the font and adding it in your source code.
3. 下载字体并将其添加到您的源代码中。
Download the font. For example, for google fonts, you can go to fonts.google.com. Click on the download button to download the font.
下载字体。例如,对于 google 字体,您可以访问fonts.google.com。点击下载按钮下载字体。
Move the font to fonts
directory in your src
directory
将字体移动到fonts
目录中的src
目录
src
|
`----fonts
| |
| `-Lato/Lato-Black.ttf
| -Lato/Lato-BlackItalic.ttf
| -Lato/Lato-Bold.ttf
| -Lato/Lato-BoldItalic.ttf
| -Lato/Lato-Italic.ttf
| -Lato/Lato-Light.ttf
| -Lato/Lato-LightItalic.ttf
| -Lato/Lato-Regular.ttf
| -Lato/Lato-Thin.ttf
| -Lato/Lato-ThinItalic.ttf
|
`----App.css
Now, in App.css
, add this
现在,在App.css
,添加这个
@font-face {
font-family: 'Lato';
src: local('Lato'), url(./fonts/Lato-Regular.otf) format('opentype');
}
@font-face {
font-family: 'Lato';
font-weight: 900;
src: local('Lato'), url(./fonts/Lato-Bold.otf) format('opentype');
}
@font-face {
font-family: 'Lato';
font-weight: 900;
src: local('Lato'), url(./fonts/Lato-Black.otf) format('opentype');
}
For ttf
format, you have to mention format('truetype')
. For woff
, format('woff')
对于ttf
格式,您必须提及format('truetype')
. 对于woff
,format('woff')
Now you can use the font in classes.
现在您可以在类中使用该字体。
.modal-title {
font-family: Lato, Arial, serif;
font-weight: black;
}
4. Using web-font-loader package
4. 使用 web-font-loader 包
Install package using
使用安装包
yarn add webfontloader
or
或者
npm install webfontloader --save
In src/index.js
, you can import this and specify the fonts needed
在 中src/index.js
,您可以导入它并指定所需的字体
import WebFont from 'webfontloader';
WebFont.load({
google: {
families: ['Titillium Web:300,400,700', 'sans-serif']
}
});
回答by Hitesh Sahu
- Go to Google Fonts https://fonts.google.com/
- Select your font as depicted in image below:
- 转到 Google 字体https://fonts.google.com/
- 选择您的字体,如下图所示:
- Copy and then paste that url in new tab you will get the css code to add that font. In this case if you go to
- 复制然后将该 url 粘贴到新选项卡中,您将获得添加该字体的 css 代码。在这种情况下,如果你去
It will open like this:
它会像这样打开:
4, Copy and paste that code in your style.css and simply start using that font like this:
4,将该代码复制并粘贴到 style.css 中,然后像这样开始使用该字体:
<Typography
variant="h1"
gutterBottom
style={{ fontFamily: "Spicy Rice", color: "pink" }}
>
React Rock
</Typography>
Result:
结果:
回答by Delfino
回答by Yasin UYSAL
I was making mistakes like this.
我犯了这样的错误。
@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i&subset=cyrillic,cyrillic-ext,latin-ext";
@import "https://use.fontawesome.com/releases/v5.3.1/css/all.css";
It works properly this way
它以这种方式正常工作
@import url(https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i&subset=cyrillic,cyrillic-ext,latin-ext);
@import url(https://use.fontawesome.com/releases/v5.3.1/css/all.css);
回答by puiu
I spent the entire morning solving a similar problem after having landed on this stack question. I used Dan's first solution in the answer above as the jump off point.
在解决这个堆栈问题后,我花了一整个上午来解决类似的问题。我在上面的答案中使用了 Dan 的第一个解决方案作为起点。
Problem
问题
I have a dev (this is on my local machine), staging, and production environment. My staging and production environments live on the same server.
我有一个开发(在我的本地机器上)、暂存和生产环境。我的临时环境和生产环境位于同一台服务器上。
The app is deployed to staging via acmeserver/~staging/note-taking-app
and the production version lives at acmeserver/note-taking-app
(blame IT).
该应用程序部署到暂存通过acmeserver/~staging/note-taking-app
,生产版本位于acmeserver/note-taking-app
(归咎于 IT)。
All the media files such as fonts were loading perfectly fine on dev (i.e., react-scripts start
).
所有媒体文件(如字体)都在 dev(即react-scripts start
)上加载得很好。
However, when I created and uploaded staging and production builds, while the .css
and .js
files were loading properly, fonts were not. The compiled .css
file looked to have a correct path but the browser http request was getting some very wrong pathing (shown below).
但是,当我创建和上传临时和生产版本时,虽然.css
和.js
文件正确加载,但字体却没有。编译后的.css
文件看起来有一个正确的路径,但浏览器的 http 请求得到了一些非常错误的路径(如下所示)。
The compiled main.fc70b10f.chunk.css
file:
编译后的main.fc70b10f.chunk.css
文件:
@font-face {
font-family: SairaStencilOne-Regular;
src: url(note-taking-app/static/media/SairaStencilOne-Regular.ca2c4b9f.ttf) ("truetype");
}
The browser http request is shown below. Note how it is adding in /static/css/
when the font file just lives in /static/media/
as well as duplicating the destination folder. I ruled out the server config being the culprit.
浏览器http请求如下所示。请注意它是如何/static/css/
在字体文件刚刚存在/static/media/
以及复制目标文件夹时添加的。我排除了服务器配置是罪魁祸首。
The Referer
is partly at fault too.
该Referer
过错是部分过。
GET /~staging/note-taking-app/static/css/note-taking-app/static/media/SairaStencilOne-Regular.ca2c4b9f.ttf HTTP/1.1
Host: acmeserver
Origin: http://acmeserver
Referer: http://acmeserver/~staging/note-taking-app/static/css/main.fc70b10f.chunk.css
The package.json
file had the homepage
property set to ./note-taking-app
. This was causing the problem.
该package.json
文件的homepage
属性设置为./note-taking-app
. 这导致了问题。
{
"name": "note-taking-app",
"version": "0.1.0",
"private": true,
"homepage": "./note-taking-app",
"scripts": {
"start": "env-cmd -e development react-scripts start",
"build": "react-scripts build",
"build:staging": "env-cmd -e staging npm run build",
"build:production": "env-cmd -e production npm run build",
"test": "react-scripts test",
"eject": "react-scripts eject"
}
//...
}
Solution
解决方案
That was long winded — but the solution is to:
这是冗长的 - 但解决方案是:
- change the
PUBLIC_URL
env variable depending on the environment - remove the
homepage
property from thepackage.json
file
PUBLIC_URL
根据环境更改env 变量homepage
从package.json
文件中删除属性
Below is my .env-cmdrc
file. I use .env-cmdrc
over regular .env
because it keeps everything together in one file.
下面是我的.env-cmdrc
文件。我.env-cmdrc
经常使用,.env
因为它将所有内容放在一个文件中。
{
"development": {
"PUBLIC_URL": "",
"REACT_APP_API": "http://acmeserver/~staging/note-taking-app/api"
},
"staging": {
"PUBLIC_URL": "/~staging/note-taking-app",
"REACT_APP_API": "http://acmeserver/~staging/note-taking-app/api"
},
"production": {
"PUBLIC_URL": "/note-taking-app",
"REACT_APP_API": "http://acmeserver/note-taking-app/api"
}
}
Routing via react-router-dom
works fine too — simply use the PUBLIC_URL
env variable as the basename
property.
通过路由也可以react-router-dom
正常工作 - 只需使用PUBLIC_URL
env 变量作为basename
属性。
import React from "react";
import { BrowserRouter } from "react-router-dom";
const createRouter = RootComponent => (
<BrowserRouter basename={process.env.PUBLIC_URL}>
<RootComponent />
</BrowserRouter>
);
export { createRouter };
The server config is set to route all requests to the ./index.html
file.
服务器配置设置为将所有请求路由到./index.html
文件。
Finally, here is what the compiled main.fc70b10f.chunk.css
file looks like after the discussed changes were implemented.
最后,这是main.fc70b10f.chunk.css
在实施所讨论的更改后编译文件的样子。
@font-face {
font-family: SairaStencilOne-Regular;
src: url(/~staging/note-taking-app/static/media/SairaStencilOne-Regular.ca2c4b9f.ttf)
format("truetype");
}
Reading material
阅读材料
https://create-react-app.dev/docs/deployment#serving-apps-with-client-side-routing
https://create-react-app.dev/docs/advanced-configuration
- this explains the
PUBLIC_URL
environment variableCreate React App assumes your application is hosted at the serving web server's root or a subpath as specified in package.json (homepage). Normally, Create React App ignores the hostname. You may use this variable to force assets to be referenced verbatim to the url you provide (hostname included). This may be particularly useful when using a CDN to host your application.
- this explains the
https://create-react-app.dev/docs/deployment#serving-apps-with-client-side-routing
https://create-react-app.dev/docs/advanced-configuration
- 这解释了
PUBLIC_URL
环境变量Create React App 假设您的应用程序托管在服务 Web 服务器的根目录或 package.json(主页)中指定的子路径中。通常,Create React App 会忽略主机名。您可以使用此变量强制将资产逐字引用到您提供的 url(包括主机名)。这在使用 CDN 托管您的应用程序时特别有用。
- 这解释了