如何为基于create-react-app的项目添加字体?

Max*_*ler 115 css fonts reactjs webpack create-react-app

我正在使用create-react-app而不喜欢eject.

目前尚不清楚从@ font-face导入并在本地加载的字体应该去哪里.

也就是说,我正在装货

@font-face {
  font-family: 'Myriad Pro Regular';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Regular'), url('MYRIADPRO-REGULAR.woff') format('woff');
}
Run Code Online (Sandbox Code Playgroud)

有什么建议?

- 编辑

包括丹在他的回答中提到的要点

?  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');
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*mov 219

有两种选择:

使用进口

这是建议的选项.它确保您的字体通过构建管道,在编译期间获得哈希,以便浏览器缓存正常工作,并且如果文件丢失,您将收到编译错误.

"添加图像,字体和文件"中所述,您需要从JS导入CSS文件.例如,默认情况下src/index.js导入src/index.css:

import './index.css';
Run Code Online (Sandbox Code Playgroud)

像这样的CSS文件通过构建管道,可以引用字体和图像.例如,如果您输入字体src/fonts/MyFont.woff,则index.css可能包含以下内容:

@font-face {
  font-family: 'MyFont';
  src: local('MyFont'), url(./fonts/MyFont.woff) format('woff');
}
Run Code Online (Sandbox Code Playgroud)

注意我们是如何使用以相对路径开头的./.这是一种特殊符号,可帮助构建管道(由Webpack提供支持)发现此文件.

通常这应该足够了.

使用public文件夹

如果由于某种原因你不想使用构建管道,而是以"经典方式"进行,你可以使用该public文件夹并将字体放在那里.

这种方法的缺点是,在编译生产时文件不会出现哈希,所以每次更改它们时都必须更新它们的名称,否则浏览器将缓存旧版本.

如果你想这样做,将字体放在public文件夹中,例如,放入public/fonts/MyFont.woff.如果你遵循这种方法,你也应该把CSS文件放到public文件夹中,而不是从JS导入它们,因为混合这些方法会非常混乱.所以,如果你仍然想要这样做,你会有一个像这样的文件public/index.css.您必须从以下位置手动添加<link>到此样式表public/index.html:

<link rel="stylesheet" href="%PUBLIC_URL%/index.css">
Run Code Online (Sandbox Code Playgroud)

在其中,您将使用常规CSS表示法:

@font-face {
  font-family: 'MyFont';
  src: local('MyFont'), url(fonts/MyFont.woff) format('woff');
}
Run Code Online (Sandbox Code Playgroud)

注意我是如何使用fonts/MyFont.woff路径的.这是因为index.css它位于public文件夹中,因此它将从公共路径提供(通常是服务器根目录,但如果部署到GitHub页面并将homepage字段设置为http://myuser.github.io/myproject,则将从中提供/myproject).但是fonts也在public文件夹中,因此它们将从fonts相对(任一http://mywebsite.com/fonts或者http://myuser.github.io/myproject/fonts)提供.因此我们使用相对路径.

请注意,由于我们在此示例中避免使用构建管道,因此它不会验证文件是否确实存在.这就是为什么我不推荐这种方法.另一个问题是我们的index.css文件没有被缩小并且没有得到哈希.因此,对于最终用户来说,它会变得更慢,并且您冒着浏览器缓存旧版本文件的风险.

 使用哪种方式?

使用第一种方法("使用进口").我只描述了第二个,因为那是你试图做的事情(根据你的评论判断),但它有很多问题,应该只是你解决某些问题时的最后手段.

  • 如果有人添加```ttf```字体,你应该给```truetype```而不是```ttf```作为```format``` [*]的参数(https ://scotch.io/@micwanyoike/how-to-add-fonts-to-a-react-project). (41认同)
  • 如果您使用`otf`,请关注@milkersarac,您需要输入`opentype`. (13认同)
  • @milkersarac你是我的英雄 (7认同)
  • 文档中的一个例子会很有用,我也有点困惑 (4认同)
  • 一个系列有多种样式(“粗体”、“粗体+斜体”,..)?这应该有所帮助:/sf/answers/170578131/ (3认同)
  • 我发现我实际上不得不使用网址./fonts/Myfont.woff而不是./Myfont.woff (2认同)
  • @milkersarac你是最棒的! (2认同)
  • 字体正在加载,但是文件具有'&lt;hash&gt; .ttf',并且由于index.css文件仍具有常规路由,因此它们没有加载。有任何想法吗? (2认同)
  • 应该添加@milkersarac 的评论来回答 - 这救了我 (2认同)

sud*_*ang 11

以下是一些方法:

1.导入字体

例如,要使用Roboto,请使用

yarn add typeface-roboto
Run Code Online (Sandbox Code Playgroud)

要么

npm install typeface-roboto --save
Run Code Online (Sandbox Code Playgroud)

在index.js中:

import "typeface-roboto";
Run Code Online (Sandbox Code Playgroud)

npm软件包包含许多开源字体和大多数Google字体。您可以在此处查看所有字体。所有软件包均来自该项目

2.对于第三方托管的字体

例如Google字体,您可以访问fonts.google.com,在其中可以找到可放入您的链接的链接。public/index.html

fonts.google.com的屏幕截图

就像

<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet">
Run Code Online (Sandbox Code Playgroud)

要么

<style>
    @import url('https://fonts.googleapis.com/css?family=Montserrat');
</style>
Run Code Online (Sandbox Code Playgroud)

3.使用web-font-loader软件包

使用安装软件包

yarn add webfontloader
Run Code Online (Sandbox Code Playgroud)

要么

npm install webfontloader --save
Run Code Online (Sandbox Code Playgroud)

在中src/index.js,您可以导入它并指定所需的字体

import WebFont from 'webfontloader';

WebFont.load({
   google: {
     families: ['Titillium Web:300,400,700', 'sans-serif']
   }
});
Run Code Online (Sandbox Code Playgroud)

  • `对于 ttf 格式,你必须提到 format('truetype')。对于 woff,format('woff')` 为我做到了!谢谢你! (3认同)

Hit*_*ahu 7

  1. 转到 Google 字体https://fonts.google.com/
  2. 选择您的字体,如下图所示:

在此处输入图片说明

  1. 复制然后将该 url 粘贴到新选项卡中,您将获得添加该字体的 css 代码。在这种情况下,如果你去

https://fonts.googleapis.com/css?family=Spicy+Rice

它会像这样打开:

在此处输入图片说明

4、将该代码复制并粘贴到 style.css 中,然后像这样开始使用该字体:

      <Typography
          variant="h1"
          gutterBottom
          style={{ fontFamily: "Spicy Rice", color: "pink" }}
        >
          React Rock
        </Typography>
Run Code Online (Sandbox Code Playgroud)

结果:

在此处输入图片说明

  • 在许多情况下(例如:企业网络),对外部 CDN 的访问会被防火墙阻止,这种方法虽然正确,但可能不起作用。我们的组织中有多个 VLAN,除了 IT 和少数其他人之外,所有 VLAN 都会阻止外部 CDN 访问,这也意味着 Google 的内容 CDN 也被阻止。去过也做过。 (3认同)

pio*_*son 7

当对普通/斜体使用不同的字体文件时,font-style您指定的方式@font-face可能需要根据入口点而有所不同。在这里查看我的答案

  1. 如果您选择将css文件直接链接到您的文件public/index.html,那么您可以font-face正常使用一个font-family名称和不同的名称font-style
@font-face {
  font-family: "FontName"; <---
  font-style: normal; <---
  font-weight: normal;
  src: url("path-to-assets/fonts/FontName.ttf") format("truetype");
}
@font-face {
  font-family: "FontName"; <---
  font-style: italic; <---
  font-weight: normal;
  src: url("path-to-assets/fonts/FontName-Italic.ttf") format("truetype");
}

/* Usage */
.text {
  font-family: FontName;
  font-style: normal;
}
.text-italic {
  font-family: FontName;
  font-style: italic;
}
Run Code Online (Sandbox Code Playgroud)
  1. 如果您选择css通过 Js 链接文件进行捆绑,那么您需要font-family为所有italic字体使用不同的名称并使用font-style普通字体。
@font-face {
  font-family: "FontName"; <---
  font-style: normal; <---
  font-weight: normal; /* normal | 300 | 400 | 600 | bold | etc */
  src: url("path-to-assets/fonts/FontName.ttf") format("truetype");
}
@font-face {
  font-family: "FontNameItalic";
  font-style: normal; <----
  font-weight: normal; /* normal | 300 | 400 | 600 | bold | etc */
  src: url("path-to-assets/fonts/FontName-Italic.ttf") format("truetype");
}

/* Usage */
.text {
  font-family: FontName;
}
.text-italic {
  font-family: FontNameItalic;
}
Run Code Online (Sandbox Code Playgroud)


Cod*_*ker 5

链接到您的 React js 的本地字体可能会失败。因此,我更喜欢使用 google 的在线 css 文件来链接字体。参考下面的代码,

<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
Run Code Online (Sandbox Code Playgroud)

或者

<style>
    @import url('https://fonts.googleapis.com/css?family=Roboto');
</style>
Run Code Online (Sandbox Code Playgroud)


Use*_*ebo 5

您可以使用Web API FontFace构造函数(也称为 Typescript),而无需 CSS:

export async function loadFont(fontFamily: string, url: string): Promise<void> {
    const font = new FontFace(fontFamily, `local(${fontFamily}), url(${url})`);
    // wait for font to be loaded
    await font.load();
    // add font to document
    document.fonts.add(font);
    // enable font with CSS class
    document.body.classList.add("fonts-loaded");
}
Run Code Online (Sandbox Code Playgroud)
import ComicSans from "./assets/fonts/ComicSans.ttf";

loadFont("Comic Sans ", ComicSans).catch((e) => {
    console.log(e);
});
Run Code Online (Sandbox Code Playgroud)

使用您的模块声明一个文件font.ts(仅限 TS):

declare module "*.ttf";
declare module "*.woff";
declare module "*.woff2";
Run Code Online (Sandbox Code Playgroud)

如果 TS 找不到仍为正式 WIP 的 FontFace 类型,请将此声明添加到您的项目中。它可以在您的浏览器中运行,IE 除外。