更改所有 Material UI 组件的字体系列

94

我们能否用更少的代码更改Material UI组件的字体族?我已经尝试了许多方法,但仍然无法做到。我必须单独更改字体族,这真的是很多工作量。有其他方法可以做到吗?


在 Material UI 的版本 0 中,我们有没有针对相同问题的解决方案? - Nitin Kumar
https://material-ui.com/customization/typography - Borzh
9个回答

140
你可以通过以下方式在 material-ui@next 库中更改字体。假设你的 <App /> 如下所示定义:
// Material UI
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';

const App = () => (
  <MuiThemeProvider theme={THEME}>
    <Provider store={store}>
      <Router history={appHistory} routes={Routes} />
    </Provider>
  </MuiThemeProvider>
 );

 ReactDOM.render(<App />, document.getElementById('app'));
MuiThemeProvidertheme 属性中,您提供了以下内容。
const THEME = createMuiTheme({
   typography: {
    "fontFamily": `"Roboto", "Helvetica", "Arial", sans-serif`,
    "fontSize": 14,
    "fontWeightLight": 300,
    "fontWeightRegular": 400,
    "fontWeightMedium": 500
   }
});

然后在你的css或主要的index.html文件中包含这个:@import url('https://fonts.googleapis.com/css?family=Roboto:300,400,500,700');

关于你可以为createMuiTheme提供的所有参数列表,请参阅默认主题参数。有关更改 MuiTheme 的文档本身,它们如下所示。Material UI Next 主题

关于<Reboot />部分,你可以在这里查看文档 Material UI Reboot 详情


可以运行...但是如果我们包含任何div组件,我们需要改变字体样式,对吧? - noName94
那要看情况。应用于整个Material UI组件的通用字体可以像我上面提到的那样设置。但是,如果您想为每个不同的div标签使用自定义字体,则需要单独指定它。 - Adeel Imran
它对我来说可行,但我收到了这个警告:Material-UI:您正在使用即将在下一个主要版本中删除的已弃用的排版变体。 - Reza
1
@Reza Material-UI正在停用旧的字体API,因此会显示警告消息。为了使用最新的字体,请在typography对象中添加以下内容。typography: { useNextVariants: true } - Adeel Imran
(!)此答案应更新为新的v5+。 - kuzey beytar
显示剩余2条评论

53

**** 更新 *****

在Adeel的回答基础上做出补充。

对于最新的Material-UI(v4+)组件,导入语句和MuiThemeProvider已经发生了变化。

现在,在你的App.js文件中,按照以下方式操作:

import { createMuiTheme } from '@material-ui/core/styles';
import { ThemeProvider } from '@material-ui/styles';
import './Styles/App.css';

const theme = createMuiTheme({
  typography: {
    fontFamily: [
      'Nunito',
      'Roboto',
      '"Helvetica Neue"',
      'Arial',
      'sans-serif'
    ].join(','),
  }
});

class App extends Component {
  render() {
    return (
      <ThemeProvider theme={theme}>
        <div className="App">
          <MainApp />
        </div>
      </ThemeProvider>
    );
  }
}

export default App;

比如说,现在我添加了Nunito字体。因此,我需要在App.css中以以下方式添加相同的字体(该文件被导入到App.js中):

@font-face {
  font-family: 'Nunito';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: local('Nunito Regular'), local('Nunito-Regular'), 
   url(https://fonts.gstatic.com/s/nunito/v11/XRXV3I6Li01BKofINeaBTMnFcQ.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;
}

2
我们如何添加多种字体?例如,Nunito和Montserrat。 - Alex

31

在 MUI v5 中,请确保从 @mui/material/styles 导入 ThemeProvider 和 createTheme,而不是从 @mui/styles。我曾经因为这个问题卡了几个小时。

import { ThemeProvider, createTheme } from '@mui/styles'; ❌

import { ThemeProvider, createTheme } from '@mui/material/styles'; ✅

const theme = createTheme({
  typography: {
    allVariants: {
      fontFamily: 'serif',
      textTransform: 'none',
      fontSize: 16,
    },
  },
});

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

1
为什么MUI团队在这种情况下没有发出警告? - olegtaranenko

10
MUI v5 中,您可以轻松更新所有 Typography 变体的 fontFamily 或任何其他 CSS 属性:
const theme = createTheme({
  typography: {
    allVariants: {
      fontFamily: 'serif',
    },
  },
})

为了动态更改应用中的字体系列fontFamily,可以使用useMemo根据最新的fontFamily值创建一个新的theme对象:
const defaultFontFamily = 'serif';
const [fontFamily, setFontFamily] = React.useState(defaultFontFamily);

const theme = React.useMemo(
  () =>
    createTheme({
      typography: {
        allVariants: { fontFamily },
      },
    }),
  [fontFamily],
);

return (
  <div>
    <Select
      defaultValue={defaultFontFamily}
      onChange={(e) => setFontFamily(e.target.value)}
    >
      <MenuItem value="serif">serif</MenuItem>
      <MenuItem value="sans-serif">sans-serif</MenuItem>
    </Select>
    <ThemeProvider theme={theme}>
      <Content />
    </ThemeProvider>
  </div>
);

演示

Codesandbox 演示


6
希望这能帮到一些人……在createMuiTheme中声明样式时,逗号和括号需要非常小心。很容易出错。例如,调色板是一个大对象……排版也是,确保所有内容都放在正确的位置。我曾因此犯过错误而遇到了随机问题。
  palette: {
    primary: {
      light: '#ff8e8c',
      main: '#ff5a5f',
      dark: '#c62035',
      contrastText: '#fff',
    },
    secondary: {
      light: '#4da9b7',
      main: '#017a87',
      dark: '#004e5a',
      contrastText: '#000',
    },
  },
  typography: {
    allVariants: {
      fontFamily: "'Montserrat', sans-serif",
      textTransform: "none",
    }
    button: {
      textTransform: "none",
    }
  },

4
这是现在首选的方法:
const theme = createMuiTheme({
  typography: {
    fontFamily: [
      '-apple-system',
      'BlinkMacSystemFont',
      '"Segoe UI"',
      'Roboto',
      '"Helvetica Neue"',
      'Arial',
      'sans-serif',
      '"Apple Color Emoji"',
      '"Segoe UI Emoji"',
      '"Segoe UI Symbol"',
    ].join(','),
  },
});


根据此处注明的信息:https://material-ui.com/customization/typography/

2
当我尝试导入本地的.ttf文件时,这对我不起作用。我正在使用webpack,并在组件文件中导入它,其中我正在使用createMuiTheme制作我的主题,并包含在我的ThemeProvider中。 - realisation

3
这对我有用。
全局样式覆盖.js
import { createTheme, responsiveFontSizes } from '@mui/material/styles';

export default function GlobalStyleOverrides() {
  const theme = createTheme({       
    typography: {
      fontFamily: [
        '"Bebas Neue"',
        'Roboto',
        '"Helvetica Neue"',
        'Arial',
        'sans-serif',
      ].join(','),         
      body1: {
        fontFamily: "'Poppins', Arial, sans-serif",
      },
    },
    components: {
      MuiButton: {
        variants: [
          {
            props: { variant: 'contained' },
            style: {
              textTransform: 'none',
              border: `10px dashed red`,
            },
          },              
        ],
      },
    },
  });

  return responsiveFontSizes(theme);
}

App.js

import GlobalStyleOverrides from 'components/_base/global-style-overrides/GlobalStyleOverrides';
...
function App() {
  return (
    <ThemeProvider theme={GlobalStyleOverrides()}>
      <Router>
        ...
      </Router>
    </ThemeProvider>
  );
}

1

当使用中间主题时,将字体放在那里非常重要,例如:

import { createTheme } from "@mui/material/styles";
import { Inter } from "next/font/google";

export const inter = Inter({
  subsets: ["latin"],
});

let theme = createTheme({
  typography: {
    allVariants: {
      fontFamily: inter.style.fontFamily,
    },
  },
  breakpoints: {
    values: {
      xs: 0,
      sm: 656,
      md: 1023,
      lg: 1440,
      xl: 1920,
    },
  },
});

const Mytheme = createTheme(theme, {
  typography: {
    h1: {
      fontWeight: 700,
      [theme.breakpoints.between("xs", "md")]: {
        fontSize: "40px",
        lineHeight: "48px",
      },
      [theme.breakpoints.between("md", "xl")]: {
        fontSize: "56px",
        lineHeight: "64px",
      },
    },
    h2: {
      fontWeight: 700,
      fontSize: "40px",
      lineHeight: "48px",
    },
    h3: {
      fontWeight: 700,
      fontSize: "32px",
      lineHeight: "40px",
    },
  },
});

export default Mytheme;

你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Community

0

MUI 5之后,方法有些许改变。

对于您的用例,良好的做法是创建一个全局主题对象并根据您的需求进行调整。请注意,您也可以微调不同的排版变体!

import {createTheme} from "@mui/material/styles";

const theme = createTheme(
    {
        typography: {
            fontFamily: ['Merriweather', 'serif'].join(','),
            fontSize: 16,
            h2: {
                fontSize: "60px",
                fontWeight: "bold",
            }
        },
    }
)

然后在您的应用组件周围包装ThemeProvider:

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import theme from "./theme";
import {ThemeProvider} from "@mui/material/styles";

const root = ReactDOM.createRoot(
    document.getElementById('root') as HTMLElement
);

root.render(
    <React.StrictMode>
        <ThemeProvider theme={theme}>
            <App/>
        </ThemeProvider>
    </React.StrictMode>
);

重要!

在使用外部字体时,请确保也导入它。 例如:在 "index.html" 中添加以下代码 -

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

<link href="https://fonts.googleapis.com/css2?family=Merriweather:wght@300;700&display=swap" rel="stylesheet">

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