Styling Material-UI Pseudo-Classes and Pseudo-Elements: Before, After, Hover, and Active

Styling pseudo-classes and pseudo-elements in Material-UI can be challenging. It requires knowledge of two topics:

  • Material-UI styling API and class selectors
  • Proper JSS selector syntax

In this article I’ll provide examples of selecting “pseudos” on a variety of Material-UI components.

I’ll also discuss the difference between a pseudo-class and a pseudo element.

***UPDATE for MUI 5: Material-UI moved to a new styling API where styling is applied using the sx prop. If you are using MUI v5, simply write the styling code directly in the sx prop instead of using makeStyles and classes. I’m working on updating all my articles, but until I’m finished you can read my guide to the MUI sx prop to learn more.

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

Pseudo-Class Vs. Pseudo-Element

After researching this topic, I finally know the simple differences between pseudo-classes and pseudo-elements.

“A pseudo-class is a selector that selects elements that are in a specific state.”

MDN Docs

Pseudo-classes can be based on the natural state of an element, such as :last-child. They can be based on a user interaction, such as :hover. Notice the selectors start with a single colon. Here is the full list of classes.

“[Pseudo-Elements] act as if you had added a whole new HTML element into the markup”

MDN Docs

Pseudo-elements are sort of like imaginary elements that are available as needed, such as ::first-line. There are far fewer pseudo-elements than pseudo-classes. Notice the selectors start with a double colon. For years I didn’t know why there was sometimes one colon, sometimes two in a selector.

Styling ::Before and ::After In A Material-UI TextField

The TextField component is composed of several more basic components. This provides an opportunity for placing content precisely using the pseudo-elements ::before and ::after.

I created the following TextField as an example:

Material-UI Styling ::before and ::after

It is wrapped in a form, and I targeted the form’s root class to add a checkbox outside the TextField using ::before.

Inside the TextField, I targeted the label and added the arrow using ::after.

//useStyles
tfRoot: {
  //.MuiTextField-root
  "&::before": {
    content: '"\\2610"',
    width: "1em",
    display: "inline-block",
    marginTop: "8px",
    fontSize: 24
  },
  "& label::after": {
    content: '"→"',
    width: "2em",
    textAlign: "center",
    display: "inline-block",
    fontSize: 24
  }
}

//In the return statement
<form className={classes.tfRoot} noValidate autoComplete="off">
  <TextField
    id="outlined-secondary"
    label="Outlined secondary"
    variant="outlined"
    color="secondary"
  />
</form>

Notice that it is the form that has class tfRoot.

There are two important things to notice. First, if I wanted to target the TextField directly for the ::before element I could have by adding class .MuiTextField-root. Be aware that this changes the position of the checkbox.

Second, notice the JSS syntax. No space after the & means that it is a direct selector, a space means it is selecting a child.

Here’s the complete guide to styling TextField. Read here to learn how to override the TextField border color.

Styling :Hover and :Active Pseudo-Classes In A Material-UI Button

Button components naturally have a lot of user interaction and have many pseudo-classes applied automatically during those interactions.

With the code below I targeted a Button’s hover and active states:

//useStyles
btnRoot: {
  "&:hover": {
    backgroundColor: "orange"
  },
  //click the button to see this take effect
  "&:active": {
    border: "1px black solid",
    backgroundColor: "green"
  }
}

//return statement
<Button className={classes.btnRoot} variant="contained">
  My Button!
</Button>

The active state is applied during user interaction with the button (literally the time that the mouse button is depressed). I have captured the effect using the “Force element state” functionality in Chrome dev tools.

Material-UI Button hover and active

Material-UI Button is relatively easy to style. I simply applied a class via the classNames property and was able to target the appropriate states with JSS & syntax.

Read here to learn how to align Buttons perfectly using the Box component.

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

Here’s how to add hover styling to Bootstrap buttons.

Share this post:

Leave a Comment

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