92

Can we change the font family of Material UI components with less code? I have tried many ways but still, I can't able to do it. I have to change the font family individually which is really a lot of work. Are there any other ways to do that?

Olivier Tassinari
  • 8,238
  • 4
  • 23
  • 23
noName94
  • 3,783
  • 1
  • 16
  • 32

9 Answers9

136

You can change the font in material-ui@next library doing the following. Suppose in your <App /> which is defined like the following

// 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'));

In the theme prop for MuiThemeProvider you provide the following where

const THEME = createMuiTheme({
   typography: {
    "fontFamily": `"Roboto", "Helvetica", "Arial", sans-serif`,
    "fontSize": 14,
    "fontWeightLight": 300,
    "fontWeightRegular": 400,
    "fontWeightMedium": 500
   }
});

Then somewhere in your css or your main index.html file include this @import url('https://fonts.googleapis.com/css?family=Roboto:300,400,500,700');

For a list of all params you can give to createMuiTheme Default Theme Params Regarding the docs itself for changing the MuiTheme they are as follows. Themes Material UI Next

Regarding the <Reboot /> part you can have a look at the documentation here Material UI Reboot Details

macphilips
  • 527
  • 4
  • 14
Adeel Imran
  • 13,166
  • 8
  • 62
  • 77
  • It Works.. But if we include any div component we need to change font styles,right? – noName94 Jan 18 '18 at 11:28
  • That depends, The general font which being applied to entire Material UI components can be set like the way I have mentioned above. But if you want custom fonts for every different `div` tag then you need to specify it separately. – Adeel Imran Jan 18 '18 at 11:32
  • Ok. As mentioned above I can be able to change the font family. But there is another problem. I want to change the background colour and colour of the Typography fonts on selecting the texts of the typography. Can we able to do that using Muithemeprovider? – noName94 Jan 18 '18 at 11:45
  • You can change the color of the font, but not the background-color. Have a look at https://material-ui-next.com/customization/theme-default/ If you want to change the background-color you will have to over-ride that component. – Adeel Imran Jan 18 '18 at 12:09
  • it works for me,but i got this warning : Material-UI: you are using the deprecated typography variants that will be removed in the next major release – Reza Dec 23 '18 at 06:56
  • 1
    @Reza Material-UI is deprecating the old typography API, so it gives a warning message. In order to use the latest typography. Add this in the `typography` object. ```typography: { useNextVariants: true } ``` – Adeel Imran Dec 24 '18 at 05:42
  • (!) This answer should be updated for new v5+. – kuzey beytar Jun 02 '22 at 08:36
53

**** UPDATES *****

Adding to the accepted answer by Adeel.

For the latest Material-UI(v4+) components, the imports, as well as MuiThemeProvider, have been changed.

So now in your App.js, do the following:

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;

Now for example, I've added the Nunito font. So I had to add the same to the App.css (which is being imported in App.js) in the following way:

@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;
}
Ankush Raghuvanshi
  • 1,392
  • 11
  • 17
28

In MUI v5, also make sure ThemeProvider and createTheme is imported from @mui/material/styles and not from @mui/styles. I was stuck for hours thinking why it's not working.

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>
  );
}
Viraj Singh
  • 1,951
  • 1
  • 17
  • 27
10

In MUI v5, you can update the fontFamily or any other CSS properties of all Typography variants easily:

const theme = createTheme({
  typography: {
    allVariants: {
      fontFamily: 'serif',
    },
  },
})

To change the fontFamily dynamically in your app, you can use useMemo to create a new theme object based on the latest fontFamily value:

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>
);

Live Demo

Codesandbox Demo

NearHuscarl
  • 66,950
  • 18
  • 261
  • 230
6

Hoping this can help someone...you need to be really careful with commas and brackets when declaring your styles within createMuiTheme

It's really easy to mess this up. For instance, palette is one big object...so is typography, make sure everything is in the right place. I had random problems caused by doing this wrong.

  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",
    }
  },
olegtaranenko
  • 3,722
  • 3
  • 26
  • 33
Kyle Pennell
  • 5,747
  • 4
  • 52
  • 75
4

This is now the preferred method:

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

As noted here: https://material-ui.com/customization/typography/

TechnoTim
  • 3,065
  • 1
  • 23
  • 28
  • 2
    This isn't working for me when I'm trying to import a local .ttf file. I'm using webpack and importing it in the file of the component where I'm making my theme with createMuiTheme and including in my ThemeProvider. – realisation Jul 11 '19 at 16:56
3

This seem to work for me

GlobalStyleOverrides.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>
  );
}
atazmin
  • 4,757
  • 1
  • 32
  • 23
0

When using an intermediate theme it is important to put the font there, for example:

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;
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 20 '23 at 09:14
0

After MUI 5, the methods have been slightly changed.

For your usecase, good practice is create a global theme object and adjust it to your needs. Note that you can fine tune different Typography variants as well!

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

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

And then wrap themeProvider arounf your app component:

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>
);

Important!

While using external fonts, make sure if you import it as well. For eg: in "index.html" add these lines -

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