Muhi Logo Text
Work With MeAboutTestimonialsBlog

MUI Typography - Complete Styling & Customization Guide

A comprehensive guide to understanding the MUI Typography component, utility, styling, and theme customization.

Last updated on December 29, 2023

react
mui
MUI Typography

MUI Typography is a CSS utility component that is used to display text. It is a wrapper that renders a limited set of HTML elements like p, h1, h2, h3…etc. It follows the Material Design typography principles, including a range of highly customizable styles.

Having a typography system helps create a consistent visual experience across platforms and devices. This tutorial will cover how to use and customize MUI Typography, including variant, color, font weight, text alignment, and other styling customizations.

MUI Typography Variants

The Typography component depends on the variant prop to render the correct HTML element. By default, using the Typography component without a variant prop will render a p element.

<Typography>Default Text</Typography>

If we inspect the element in the browser, we can see that the <p> element has a predefined set of styles applied to it.

font-family: ...;
font-weight: ...;
font-size: ...;
line-height: ...;
letter-spacing: ...;

The available variants are based on the Material Design typographic scale. The variant prop accepts a string value that can be one of the following:

Variant Element Description
h1 h1 Heading 1
h2 h2 Heading 2
h3 h3 Heading 3
h4 h4 Heading 4
h5 h5 Heading 5
h6 h6 Heading 6
body1 p Body 1
body2 p Body 2
subtitle1 p Subtitle 1
subtitle2 p Subtitle 2
caption p Caption
button span Button
overline span Overline

Here is how we can use the variant prop to render each variant:

<Typography variant="h1">Heading 1</Typography>
<Typography variant="h2">Heading 2</Typography>
<Typography variant="h3">Heading 3</Typography>
<Typography variant="h4">Heading 3</Typography>
<Typography variant="h5">Heading 3</Typography>
<Typography variant="h6">Heading 3</Typography>
<Typography variant="body1">Body 1</Typography>
<Typography variant="body2">Body 2</Typography>
<Typography variant="subtitle1">Subtitle 1</Typography>
<Typography variant="subtitle2">Subtitle 2</Typography>
<Typography variant="caption">Caption</Typography>
<Typography variant="button">Button</Typography>
<Typography variant="overline">Overline</Typography>

Customize a variant

We can customize any variant from the theme in the typography object. In the following example, we will change the h1 variant to have a font size of 6rem and a font-weight of 700.

import React from "react";
import { createTheme, ThemeProvider, Typography } from "@mui/material";

const theme = createTheme({
  typography: {
    h1: {
      fontSize: "4rem",
      fontWeight: 700,
    },
  },
});

export default function App() {
  return (
    <ThemeProvider theme={theme}>
      <Typography variant="h1">Heading 1</Typography>
    </ThemeProvider>
  );
}

Using MUI theme for styling and other customizations is always helpful if we want the changes to persist throughout the app.

Add new variant

Variants are not limited to the ones provided by MUI. We can add custom variants by adding a new key to the typography object.

Let’s create a new variant called h7 with some custom styles.

import React from "react";
import { createTheme, ThemeProvider, Typography } from "@mui/material";

const theme = createTheme({
  typography: {
    h7: {
      fontSize: "3rem",
      fontWeight: 500,
      fontFamily: "sans-serif",
      fontStyle: "italic",
    },
  },
});

export default function App() {
  return (
    <ThemeProvider theme={theme}>
      <Typography variant="h7">H7 Title</Typography>
    </ThemeProvider>
  );
}

Now, we have a new variant called h7 that we can use anywhere in our app.

The default rendered element for any new variant we add will be span. If we want to change the element, we can use variantMapping in the typography object. For example, if we’re going to render the h7 variant as a h1 element, we can do the following:

...

const theme = createTheme({
  typography: {
   ...
  },
  components: {
    MuiTypography: {
      defaultProps: {
        variantMapping: {
          // Map the new variant to render a <h1> by default
          h7: 'h1',
        },
      },
    },
  },
});

...

Disable variant

If there are specific variants we don’t want to use, we can disable them by simply applying an undefined value to the variant in the typography object. In the following example, we will disable the caption variant.

import React from "react";
import { createTheme, ThemeProvider, Typography } from "@mui/material";

const theme = createTheme({
  typography: {
    caption: undefined,
  },
});

export default function App() {
  return (
    <ThemeProvider theme={theme}>
      <Typography variant="caption">Caption</Typography>
    </ThemeProvider>
  );
}

As we can see above, the caption variant no longer has styles applied to it. And we can double-check that by inspecting the element in the browser and looking at the element’s styles.

Typography Styling

Since the Typography component is CSS utility component, it supports all system properties. You can use them as props directly on the component with either string values or shorthand access to the theme object.

Let’s explore some of the most common ones.

Color

The color prop is used to change the color of the text. It accepts a string value that can be a color name, hex code, RGB, RGBA, or HSL value.

<Typography color="#cccccc">Light Grey Text</Typography>

The color prop supports the theme colors, which allows us to use colors from the theme palette.

<Typography color="primary">Primary Text</Typography>
<Typography color="secondary">Secondary Text</Typography>

Using the theme colors is very helpful because we can create and change the color palette only once and use it in multiple places. For example, if we have a specific text color that we want to use throughout the app, we can add it to the theme under the palette object.

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

const theme = createTheme({
  palette: {
    textBlue: "#1e88e5",
  },
});

function App() {
  return (
    <ThemeProvider theme={theme}>
      <Typography color="textBlue">Text Blue</Typography>
    </ThemeProvider>
  );
}

Now, anywhere we need to use the textBlue color, we can apply it to the color prop.

Font Size

The fontSize prop is used to change the size of the text. It accepts a string value that can be a pixel value, percentage, em, rem, or any other valid CSS unit.

<Typography fontSize="2rem">2rem</Typography>

We can use the theme to create custom font sizes using the typography object.

import React from "react";
import { createTheme, ThemeProvider, Typography } from "@mui/material";

const theme = createTheme({
  typography: {
    fontSizeSmall: "1rem",
    fontSizeMedium: "2rem",
    fontSizeLarge: "3rem",
  },
});

export default function App() {
  return (
    <ThemeProvider theme={theme}>
      <Typography fontSize="fontSizeSmall">Small</Typography>
      <Typography fontSize="fontSizeMedium">Medium</Typography>
      <Typography fontSize="fontSizeLarge">Large</Typography>
    </ThemeProvider>
  );
}

Additionally, we can choose to change the size of the text to an existing variant size.

<Typography fontSize="h4.fontSize">
  Some text that is the same size as the h4 variant
</Typography>

Font Weight

The fontWeight prop is used to change the weight of the text. It accepts a string value that can be a number or keyword. For example, the value can be 100 to 900 or normal, bold, bolder or lighter.

<Typography fontWeight="700">Bold</Typography>
<Typography fontWeight="bold">Bold</Typography>

We can use the theme to create custom font weights using the typography object.

import React from "react";
import { Typography, createTheme, ThemeProvider } from "@mui/material";

const theme = createTheme({
  typography: {
    fontWeightRegular: 400,
    fontWeightMedium: 700,
    fontWeightBold: 900,
  },
});

export default function MuiTypographyFontWeightCustom() {
  return (
    <ThemeProvider theme={theme}>
      <Typography fontWeight="fontWeightRegular">Regular</Typography>
      <Typography fontWeight="fontWeightMedium">Medium</Typography>
      <Typography fontWeight="fontWeightBold">Bold</Typography>
    </ThemeProvider>
  );
}

Additionally, we can choose to change the font weight of the text to an existing variant weight.

<Typography fontWeight="h1.fontWeight">
  Some text that is the same weight as the h1 variant
</Typography>

Font Family

The fontFamily prop is used to change the text’s font family. It accepts a string value that can be a font family name, generic family name, or a comma-separated list of font family names.

<Typography fontFamily="monospace">Monospace Font</Typography>

We can use the theme to create custom font families using the typography object.

import React from "react";
import { Typography, createTheme, ThemeProvider } from "@mui/material";

const theme = createTheme({
  typography: {
    fontFamilyPrimary: "monospace",
    fontFamilySecondary: "Arial",
  },
});

export default function MuiTypographyFontFamilyCustom() {
  return (
    <ThemeProvider theme={theme}>
      <Typography fontFamily="fontFamilyPrimary">Primary Font</Typography>
      <Typography fontFamily="fontFamilySecondary">Secondary Font</Typography>
    </ThemeProvider>
  );
}

Additionally, we can change the text’s font family to an existing variant font family.

<Typography fontFamily="h1.fontFamily">
  Some text that is the same family as the h1 variant
</Typography>

Text Align

The textAlign prop is used to change the alignment of the text. It accepts a string value and can be one of the following: left, center, right, initial, inherit, or unset.

<Typography textAlign="left">Left</Typography>
<Typography textAlign="center">Center</Typography>
<Typography textAlign="right">Right</Typography>

Letter Spacing

The letterSpacing prop is used to change the spacing between letters. It accepts a string value that can be a pixel value, percentage, em, rem, or any other valid CSS unit.

<Typography letterSpacing="2px">Letter Spacing</Typography>

We can use the theme to create custom letter spacing using the typography object.

import React from "react";
import { createTheme, ThemeProvider, Typography } from "@mui/material";

const theme = createTheme({
  typography: {
    letterSpacingSmall: "1px",
    letterSpacingMedium: "2px",
    letterSpacingLarge: "3px",
  },
});

export default function MuiTypographyLetterSpacingCustom() {
  return (
    <ThemeProvider theme={theme}>
      <Typography letterSpacing={theme.typography.letterSpacingSmall}>
        Small
      </Typography>
      <Typography letterSpacing={theme.typography.letterSpacingMedium}>
        Medium
      </Typography>
      <Typography letterSpacing={theme.typography.letterSpacingLarge}>
        Large
      </Typography>
    </ThemeProvider>
  );
}

Additionally, we can choose to change the spacing between letters to an existing variant spacing.

<Typography letterSpacing={theme => theme.typography.h1.letterSpacing}>
  Some text that has the same letter spacing as the h1 variant
</Typography>

Note, unlike the other style props, the letterSpacing does not support shorthand access to the theme object. We must pass a function to the prop and use the full path to get the value.

Line Height

The lineHeight prop is used to change the height of each line of text. It accepts a string value that can be a pixel value, percentage, em, rem, or any other valid CSS unit.

<Typography lineHeight="2rem">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla vehicula congue
  convallis. Cras mollis imperdiet quam, vitae euismod nisi fringilla sed.
</Typography>

We can use the theme to create custom line heights using the typography object.

import React from "react";
import { Typography, createTheme, ThemeProvider } from "@mui/material";

const theme = createTheme({
  typography: {
    lineHeightSmall: "1rem",
    lineHeightMedium: "2rem",
    lineHeightLarge: "3rem",
  },
});

export default function MuiTypographyLineHeightCustom() {
  return (
    <ThemeProvider theme={theme}>
      <Typography lineHeight={theme.typography.lineHeightSmall}>
        Small
      </Typography>
      <Typography lineHeight={theme.typography.lineHeightMedium}>
        Medium
      </Typography>
      <Typography lineHeight={theme.typography.lineHeightLarge}>
        Large
      </Typography>
    </ThemeProvider>
  );
}

Additionally, we can choose to change the line height of the text to an existing variant line height.

<Typography lineHeight={theme => theme.typography.h1.lineHeight}>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla vehicula congue
  convallis. Cras mollis imperdiet quam, vitae euismod nisi fringilla sed.
</Typography>

Note, unlike the other style props, the lineHeight does not support shorthand access to the theme object. We must pass a function to the prop and use the full path to get the value.

Additional Styling

The Typography component props don’t support all CSS properties, so alternatively, we can use the sx prop to apply any CSS styles. Let’s take an example that combines all the styles we covered earlier with some additions, including the text-shadow property.

<Typography
  sx={{
    color: "#cccccc",
    fontSize: "20px",
    fontWeight: 700,
    fontFamily: "Roboto",
    textAlign: "center",
    letterSpacing: "2px",
    lineHeight: "2rem",
    textTransform: "uppercase",
    textShadow: "1px 1px 2px black, 0 0 1em blue, 0 0 0.2em",
    width: "fit-content",
    backgroundColor: "#ccc",
    padding: "5px",
  }}
>
  Custom Text Styling
</Typography>

We can also apply the styles above as a new variant. Let’s create a new variant called fancy with the latest styles.

import React from "react";
import { Typography, createTheme, ThemeProvider } from "@mui/material";

const theme = createTheme({
  typography: {
    fancy: {
      color: "#cccccc",
      fontSize: "20px",
      fontWeight: 700,
      fontFamily: "Roboto",
      textAlign: "center",
      letterSpacing: "2px",
      lineHeight: "2rem",
      textTransform: "uppercase",
      textShadow: "1px 1px 2px black, 0 0 1em blue, 0 0 0.2em",
      width: "fit-content",
      backgroundColor: "#ccc",
      padding: "5px",
    },
  },
});

export default function MuiTypographySxVariant() {
  return (
    <ThemeProvider theme={theme}>
      <Typography variant="fancy">Custom Text Styling</Typography>
    </ThemeProvider>
  );
}

Finally, MUI Typography can be used as a utility to other components. For example, we can create a Box component and apply a typography style using any defined variants.

<Box
  component="span"
  sx={{
    typography: "h4",
    color: "primary.main",
  }}
>
  Box Typography
</Box>

This will render a span element with the h4 variant styles. So, if we inspect the element in the browser, we can see that the span element has a predefined set of styles.

font-family: "Roboto", "Helvetica", "Arial", sans-serif;
font-weight: 400;
font-size: 2.125rem;
line-height: 1.235;
letter-spacing: 0.00735em;

Summary

Working with MUI Typography is easy and offers a lot of flexibility. Here are some of the key takeaways from this tutorial:

  • We can use the variant prop to render a predefined set of HTML elements.
  • We can customize the predefined variants using the theme in the typography object.
  • We can directly modify the color, font size, font weight, font family, text align, letter spacing, and line height styles from the component props.
  • We can use the sx prop to apply any CSS styles to the text.
  • We can apply the typography styles on other components.

Bye for now 👋

If you enjoyed this post, I regularly share similar content on Twitter. Follow me @muhimasri to stay up to date, or feel free to message me on Twitter if you have any questions or comments. I'm always open to discussing the topics I write about!

Recommended Reading

Learn how to create dynamic, customizable inputs that enhance user experience with React Material UI FormControl.

react
mui

Discussion

Upskill Your Frontend Development Techniques 🌟

Subscribe to stay up-to-date and receive quality front-end development tutorials straight to your inbox!

No spam, sales, or ads. Unsubscribe anytime you wish.

© 2024, Muhi Masri