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

23

我正试图在我的React应用中使用Google Fonts的Yellowtail字体,在Material-UI主题中导入和使用它。

据我所知,所有的Google字体都在npm上,我已经使用以下命令进行了安装:

npm install typeface-yellowtail --save

我已经在App.js文件中导入了它,并将其放在主题的字体部分,将主题传递给MuiThemeProvider,但它没有起作用。我错过了什么吗?

这是我在App.js文件中的代码(header包括一个带有一些网格的AppBar,body仅包含一个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;
7个回答

14

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

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

导入这个CSS文件

import './assets/css/yellowtail.css';
现在您不需要使用任何 @font-face。这可以与像 normal 这样的字体系列一起使用。

谢谢你的帮助! 我想避免这种方法,因此我想使用material-ui提供的样式设置来工作。 - boglarkaszell
4
yellowtail.css 是从哪里来的?它包含什么内容? - ekkis
如果是没有CDN的高级购买.otf文件,你该怎么做? - BackSlashHaine

5
你缺少三个东西:
  • 将npm包作为某个名称导入
  • 使用CssBaseline组件
  • 向提供给createMuiTheme()的对象添加override
参考示例:
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
@ekkis 我认为你对 ThemeProvider 有所误解... 在这里查看 v4 文档:https://material-ui.com/customization/theming/并在这里查看 v3 文档:https://material-ui.com/customization/theming/ - psychedelicious
1
@ekkis 我不知道为什么在答案中没有导入CssBaseline,我已经进行了编辑。CssBaseline是由Material-UI提供的一个组件:https://material-ui.com/api/css-baseline/#cssbaseline-apitypeface-yellowtail是一个NPM包,而不是字体文件。根据问题,OP使用npm install typeface-yellowtail --save进行了安装。 - psychedelicious

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(",") }
});

这是一个使用Material-UI v5的工作代码沙箱示例。


2
这比网上其他需要安装软件包的答案要容易得多。 - Joel Rummel

3

我已经在主CSS文件(index.css)中定义了我的字体。

@font-face {
    font-family: 'mikhak';
    src: url(./fonts/mikhak.ttf) format("truetype")
}

然后在 App.tsx 文件中,我添加了 theme

const theme = createTheme({
    typography: {
        fontFamily: 'mikhak, Raleway, Arial',
    }
});
    

ReactDOM.render(
    <ThemeProvider theme={theme}>
        <App />
    </ThemeProvider>,
    document.getElementById('root')
);

请注意,这是针对排版组件的。

2
这对我有用:
  1. 使用npm上的@fontsource将您的字体安装为包,例如:
npm i @fontsource/work-sans
  1. 将以下代码添加到你的_app.js文件中,这样就可以全局访问你的字体包了。
const workSans = require('@fontsource/work-sans');
  1. 在您的主题中修改排版:
...
  typography: {
      fontFamily: 'Work Sans',
    }
...

就是这样!


1
更新:由于@ekkis提到,我将添加有关如何包含Google字体的更多细节。 以下答案假定您正在使用Material UI v4.10.1。
  1. 安装gatsby-plugin-web-font-loader以安装Google字体。

  2. 编辑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
  1. 现在你已经导出了 theme,可以在你的组件中使用它。

  2. theme 导入到你的组件中。比如说 <Layout /> 是你的主要组件。

// 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> 

只要这些组件的父级使用 <head>,这些组件就会继续使用 Google 字体。希望这能帮到你。

旧答案:

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

import { Typography } from "@material-ui/core"

假设您在<AppBody>中有一些文本。
<AppBody>
    Hello World!
</AppBody>

上述文本现在应更改为:
<AppBody>
    <Typography variant="body1">Hello World!</Typography>
</AppBody>

请参考Material UI文档获取不同变体的信息。

1
谢谢您的补充,这对于那些以前没有做过这个的人来说很有帮助。好多了! - ekkis
小心!如果客户的网络连接较慢,加载字体可能需要一些时间。该方法需要向谷歌CDN发出单独的HTTP请求。在请求完成之前,字体将会回退到标准字体。 - Megajin

0

我想补充@georgeos的回答,提出的解决方案经过小修订对我有用:

export const theme = createTheme({
    ...
    components: {
        MuiCssBaseline: {
            styleOverrides: {
                '@global': {
                    '@font-face': [Inter, Nunito],
                 },
            },
        },
    },
    ...
});

我还需要在app.ts文件中添加以下内容(source):

function App(){
    ...
    return (
        <ThemeProvider theme={theme}>
            <CssBaseline enableColorScheme /> <---
        ...
        </ThemeProvider>);
    ...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接