如何在 material-ui 主题中导入和使用自定义字体?

Posted

技术标签:

【中文标题】如何在 material-ui 主题中导入和使用自定义字体?【英文标题】:How to import and use a custom font in a material-ui theme? 【发布时间】:2020-01-28 10:56:38 【问题描述】:

我正在尝试在 Material-UI 主题的 React 应用中导入和使用 Yellowtail 字体(来自 Google Fonts)。

据我所知,所有谷歌字体都在 npm 上,我已经安装了它,带有

npm install typeface-yellowtail --save

命令。

我已经在App.js中导入了,放到主题的font-family部分,把主题传给了MuiThemeProvider,但是还是不行。我错过了什么?

这就是我在 App.js 中的内容(标题包含一个带有一些网格的 AppBar,正文只包含一个用于测试的 h1 文本)

import React,  Component, Fragment  from 'react';
import Header from './Components/Layouts/Header';
import AppBody from './Components/Layouts/AppBody';
import Footer from './Components/Layouts/Footer'; 
import  MuiThemeProvider, createMuiTheme  from '@material-ui/core';
import 'typeface-yellowtail';

const theme = createMuiTheme(  
  typography: 
    fontFamily: 
      '"Yellowtail", cursive',
  ,
);

class App extends Component 
  render() 
    return (
      <MuiThemeProvider theme=theme>
        <Header />
        <AppBody />
        <Footer />       
      </MuiThemeProvider>
    );
  


export default App;

【问题讨论】:

【参考方案1】:

您可以先加载 CSS 文件,而不是通过 npm 安装。

@import url('https://fonts.googleapis.com/css?family=Yellowtail&display=swap');

导入这个 CSS 文件

import './assets/css/yellowtail.css';

现在你不需要使用任何@font-face。这可以与正常的字体系列一起使用。

【讨论】:

感谢您的帮助!我想避免这种方法,因此我想使用 material-ui 提供的样式设置。 yellowtail.css 来自哪里,包含什么? 如果它的溢价购买了没有任何 CDN 的 .otf 文件,你是怎么做的?【参考方案2】:

你错过了三件事:

导入npm包作为的东西 使用CssBaseline 组件 将override 添加到提供给createMuiTheme() 的对象中

查看示例:

import React,  Component, Fragment  from 'react';
import Header from './Components/Layouts/Header';
import AppBody from './Components/Layouts/AppBody';
import Footer from './Components/Layouts/Footer'; 
import  MuiThemeProvider, createMuiTheme, CssBaseline  from '@material-ui/core';
import yellowtail from 'typeface-yellowtail';

const theme = createMuiTheme(  
  typography: 
    fontFamily: 
      '"Yellowtail", cursive',
  ,
  overrides: 
    MuiCssBaseline: 
      '@global': 
        '@font-face': [yellowtail],
      ,
    ,
  ,
);

class App extends Component 
  render() 
    return (
      <MuiThemeProvider theme=theme>
        <CssBaseline />
        <Header />
        <AppBody />
        <Footer />       
      </MuiThemeProvider>
    );
  


export default App;

示例 CodeSandbox (MUI v3):https://codesandbox.io/s/late-pond-gqql4?file=/index.js

示例 CodeSandbox (MUI v4):https://codesandbox.io/s/pensive-monad-eqwlx?file=/index.js

注意事项

在从 Material-UI v3 到 v4 的过渡中,MuiThemeProvider 更改为 ThemeProvider。如果您使用的是 v4,这是唯一需要的更改 - 此示例代码在两个版本上都适用。

您必须在 Material-UI 的 Typography 组件中换行文本才能使用字体。

【讨论】:

您的代码不起作用。 CssBaseLine 在哪里定义?什么样的字体没有扩展名(即typeface-yellowtail)? ThemeProvider 在 v4 中不存在,但 MuiThemeProvider 存在 @ekkis 我相信你误会了ThemeProvider... 在此处查看 v4 文档:material-ui.com/customization/theming 并在此处查看 v3 文档:material-ui.com/customization/theming @ekkis 我不知何故在答案中没有得到CssBaseline 的导入,我已经编辑了它。它是 Material-UI 提供的一个组件:material-ui.com/api/css-baseline/#cssbaseline-api typeface-yellowtail 是一个 NPM 包,不是字体文件。根据问题,OP 已使用 npm install typeface-yellowtail --save 安装它。【参考方案3】:

更新:由于提到了@ekkis,我正在添加有关如何包含 Google 字体的更多详细信息。以下答案假设您使用的是 Material UI v4.10.1

    安装gatsby-plugin-web-font-loader以安装谷歌字体。

    编辑 gatsby-config.js 以包含插件和 Google 字体。

module.exports = 
  plugins:      [
    
      resolve: "gatsby-plugin-web-font-loader",
      options: 
        google: 
          families: ["Domine", "Work Sans", "Happy Monkey", "Merriweather", "Open Sans", "Lato", "Montserrat"]
        
      
    ,
  ]

    要使用该字体,请在src/components 中创建一个名为theme.js 的文件
import 
  createMuiTheme,
  responsiveFontSizes
 from "@material-ui/core/styles"

let theme = createMuiTheme(
  typography: 
    fontFamily: [
                  "Work Sans",
                  "serif"
                ].join(","),
    fontSize:   18,
  
)

// To use responsive font sizes, include the following line
theme     = responsiveFontSizes(theme)

export default theme

    现在您已经导出了theme,您可以在组件中使用它。

    theme 导入到您的组件中。假设&lt;Layout /&gt; 是您的主要组件。

// src/components/layout.js

/**
 * External
 */
import React from "react"
import PropTypes from "prop-types"
import 
  ThemeProvider
 from "@material-ui/styles"
import  Typography  from "@material-ui/core"

/**
 * Internal
 */
import theme from "./theme"

const Layout = ( children ) => 

  return (
    <>
      <ThemeProvider theme=theme>
        <Typography variant="body1">Hello World!</Typography>
      </ThemeProvider>
    </>
  )

    要在其他组件中使用 Google 字体,只需使用
<Typography ...>Some Text</Typography> 

只要这些组件用作其父组件,这些组件就会继续使用 Google 字体。希望这会有所帮助。


旧答案:

将您的文本放在Typography 组件中,以反映您通过npm 安装的Google 字体

import  Typography  from "@material-ui/core"

假设您在&lt;AppBody&gt; 中有一些文本

<AppBody>
    Hello World!
</AppBody>

上面的文字现在应该改为

<AppBody>
    <Typography variant="body1">Hello World!</Typography>
</AppBody>

请参阅 Material UI docs 了解不同的变体。

【讨论】:

感谢您的补充,这对以前没有这样做过的人有所帮助。好多了! 小心!如果客户端的 Internet 连接速度较慢,则加载字体将需要一段时间。此方法需要向 Google 的 CDN 发出单独的 HTTP 请求。在请求完成之前,字体将回退到标准字体。【参考方案4】:

有一种更简单的方法可以做到这一点,不需要.css 文件或安装任何额外的包。

如果您的字体可通过诸如Google Fonts 之类的 CDN 使用,则只需将其导入应用的根 html 文件:

<link
  href="https://fonts.googleapis.com/css2?family=Yellowtail&display=swap"
  rel="stylesheet"
/>

然后在 Material-UI 主题中添加一行:

const theme = createTheme(
  typography:  fontFamily: ["Yellowtail", "cursive"].join(",") 
);

Working codesandbox example with Material-UI v5.

【讨论】:

这比网络上涉及安装包的许多其他答案要容易得多。

以上是关于如何在 material-ui 主题中导入和使用自定义字体?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Vue 单文件组件中导入和使用图片?

如何在不使用主题的情况下自定义 Material-UI 的下划线?

如何在 Aurelia 中导入和使用 RobinHerbots 的 Inputmask

如何在 Laravel 项目中导入和使用 vue-good-table Vue 组件

如何使用python在机器人框架中导入和使用用户定义的类

在模板内的 vuejs 组件中导入和使用类