How to Extend Material-UI Typography With Strikethrough, Font Size, Spacing, and Color

The Typography component is critical for a consistent UI. This article explores how to customize the Typography component through extending the theme.typography object, creating a Typography Styled Component, and overriding the MuiTypography base class.

Specifically, I will add strikethrough (textDecoration: "line-through"), font style, letter spacing, and font size to the Typography component and using the customization options above.

The Typography component has incredible optionality. Throughout this article I will link to Material-UI documentation that goes above and beyond what is discussed here.

Code Sandbox with full React code is in the Resources section.

Customizing The Typography Component

I used three different methods to customize the Typography component. Each is best suited to a particular situation, and all are useful to be aware of. I’ll list each and then give code examples.

  • Creating a custom theme and extending theme.typography
  • Creating a Styled Component
  • Creating a custom theme and overriding the MuiTypography root class

Extending Theme.Typography

Theme in Material-UI is an object that can be extended and customized in a variety of ways. I created a “new theme” in my Theme.jsx file and passed it to TypographyExtended.jsx via a ThemeProvider.

I added a new object inside the existing theme.typography object -> theme.typography.typography. While this name may seem a bit confusing, it actually follows convention. The theme.typography object contains styling for many different elements by default, for example theme.typography.h1 and theme.typography.button. Take a look at this important documentation to see the all the properties.

Now that I have created a new object within theme.typography, I can simply destructure the properties in makeStyles to quickly create a new class for my Typography component. The destructuring adds textDecoration: "line-through" and letterSpacing: "2px" to the local typography class used in my TypographyExtended component.

//Theme.jsx
export const theme1 = createMuiTheme({
  typography: {
    typography: {
      textDecoration: "line-through",
      letterSpacing: "2px"
    },
    button: {
      fontStyle: "italic"
    }
  }
});

//TypographyExtended.jsx (this gets wrapped in ThemeProvider)
const useStyles = makeStyles((theme) => ({
  typography: {
    ...theme.typography.typography
  }
}));

const TypographyExtended = () => {
  const classes = useStyles();
  return (
    <Typography className={classes.typography} component="div">
      
      Letter Spacing 4px

    </Typography>
  );
};

Anywhere that this theme is used, the extended typography object is available. This is a useful way to globally (or at least ‘regionally’) extend the typography object.

Read here to learn more about theme object breakpoints, overrides, and shadows.

Creating A Styled Component

A styled component receives an original Material-UI component and extends it with additional styling. Then the styled component is used like any other component in the JSX.

const StyledTypography = useMemo(() => {
  return withStyles({
    root: {
      textDecoration: "line-through",
      letterSpacing: "2px"
    }
  })(Typography);
}, []);

//JSX return statement
<StyledTypography component="div">
  Letter Spacing 2px
</StyledTypography>

In the code above we extended/overrode the root class with additional styling.

A styled component can be exported and then used anywhere in an application. It is another excellent option for write-once, use-often code.

Overriding Material-UI’s Theme Classes

Perhaps the most interesting option for globally adding strikethrough, font size, spacing, and other styling is to use Material-UI’s theme override functionality.

//Theme.jsx
export const theme2 = createMuiTheme({
  overrides: {
    MuiTypography: {
      root: {
        textDecoration: "line-through",
        backgroundColor: "grey"
      }
    }
  }
});

//TypographyOverride.jsx
<ThemeProvider theme={theme2}>
  <Typography component="div">Letter Spacing Def.</Typography>
</ThemeProvider>

The code above targets the MuiTypoygraphy-root class. If I wanted to target Typography components with variant="button" applied, I would add a button object inside MuiTypography, like so:

overrides: {
    MuiTypography: {
      button: {        
        backgroundColor: "grey"
      }
    }
  }

This will target MuiTypography-button class and add background color only when button variant is used.

The best thing about this method of global styling is that all Typography components pick up the new styling with no additional code. No class needed to be added, no components exported, etc., simply wrap the Typography component in a ThemeProvider.

There is a significant drawback that I found. As soon as I used the TypographyOverride component, all Typography components picked up the grey background color…even Typography components that were not given theme2 via their ThemeProvider. I tried many different methods of structuring my code and could not get around it. It seems to me that overrides should be specific to a theme. Either I am doing something incorrectly, or MUI team purposefully created overrides this way.

Typography Strikethrough, Spacing, Font Size, and Font Style

Here’s the JSS needed to add these stylings (with example values):

  • Strikethrough (also known as “line through”): textDecoration: "line-through"
  • Spacing: letterSpacing: "2px"
  • Font Size: fontSize: "20px"
  • Font Style: fontStyle: "italic"

I will focus on the TypographyExtended component to demonstrate these stylings.

I added the following inside the theme.typography object:

typography: {
  textDecoration: "line-through",
  letterSpacing: "2px"
},
button: {
  fontStyle: "italic"
}

As mentioned above, I destructured the typography object to create a class for my TypographyExtended component. This let me quickly add text decoration and letter spacing. However, I also can access theme properties directly:

const TypographyExtended = () => {
  const classes = useStyles();
  return (
    <Typography className={classes.typography} component="div">
      <Box
        letterSpacing={4}
        mt={2}
        ml={2}
        fontSize={"body2.fontSize"}
        fontStyle={"button.fontStyle"}
      >
        Letter Spacing 4px
      </Box>
    </Typography>
  );
};

I’ve wrapped a Box component and inside of it I am accessing theme.typography properties. This is a shorthand system developed by Material-UI. I specifically access the button.fontStyle that I override in my theme.

Another kind of of shorthand for spacing lets us quickly add margin and padding. It is a multiplier of default margin already applied to a component. In this example, adding mt={2} sets margin-top: 16px. There are lots of combinations for setting margin and padding on top, right, bottom, and left, plus combos.

Resources

Are you looking for training in Material-UI? Check out my review of the best Material-UI course in Udemy, which has 40+ hours of content and a 30-day money back guarantee

Code Sandbox Link – I have the component using the override method commented out. Fork the sandbox and uncomment to see it in action.

Do you want to expand your JavaScript knowledge? Try these 50 challenging questions.

Customizing Typography

Typography Theme Object, API, and System.

Here’s a great article on the global API system in MUI.

Share this post:

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.