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.

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.

tfRoot: {
  "&::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">
    label="Outlined secondary"

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:

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!

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.


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

Share this post:

Leave a Comment

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