DEV Community

Berkay Sonel
Berkay Sonel

Posted on

How to Create Beatiful Snackbar Component with Material UI + React + CSS in sx🤔

Snackbar components play a crucial role in providing feedback and notifications to users in a visually appealing and non-intrusive manner. With the power of Material-UI and React, we can create stunning and customizable snackbars that integrate into our applications.

Prerequisites:

To follow along with this tutorial, you should have a basic understanding of React and have Material-UI installed in your project. Make sure you have set up your development environment (I suggest to use create-react-app) before proceeding.
You have to install Material UI components:

npm install @mui/material @emotion/react @emotion/styled
Enter fullscreen mode Exit fullscreen mode

Let's start with a simple MUI Snackbar component:

First, we import the Snackbar component from Material-UI using the following import statement:

import Snackbar from "@mui/material/Snackbar";
Enter fullscreen mode Exit fullscreen mode

Next, we define our functional component, which will return the MUI Snackbar component with the necessary state and functions. The state variable open manages the visibility of the snackbar, and the handleClose function is responsible for closing the snackbar. Here's an example of how the component may look:

import React, { useState } from 'react';
import Snackbar from '@mui/material/Snackbar';

const MySnackbar = () => {
  const [open, setOpen] = useState(false);

  const handleClose = (event, reason) => {
   // this condition will prevent dissapering Snackbar when clicking away
    if (reason === 'clickaway') {
      return; 
    }

    setOpen(false);
  };

  return (
    <div>
      <button onClick={()=>setOpen(true)}>Activate Snackbar</button>
      <Snackbar 
       open={open} 
       onClose={handleClose} 
       autoHideDuration={4000}
       message="Hello World!"
      />
    </div>
  );
};

export default MySnackbar;
Enter fullscreen mode Exit fullscreen mode

So, let's break it down:

  • We have the open state variable that manages the open prop of the Snackbar component. By updating the open state, we control whether the Snackbar is visible or not.

  • The button there for just to make open state true so we can see our Snackbar.

  • The onClose prop of the Snackbar component is handled by the handleClosefunction. This function takes two arguments: event and reason. When the Snackbar is closed, we check the reason. If the reason is 'clickaway', indicating that the user clicked away from the Snackbar, we don't close it. This prevents the Snackbar from disappearing unintentionally.

  • To determine when the Snackbar should automatically close, we use the autoHideDuration prop. This prop defines the duration, in milliseconds, for which the Snackbar will be displayed before automatically closing. In our example, the Snackbar will be shown for 4000 milliseconds (4 seconds) before it closes.

  • Lastly, we have the message prop, which sets the text content that will be displayed in the Snackbar.

Let's look our Snackbar:

Image description

It is not the best looking Snackbar 🙄, but we can change it.

Styling Snackbar

We have the ability to customize the style of its elements using the sx prop. However, the interesting part lies in our desire to specifically style the SnackbarContent component. SnackbarContent is a component provided by Material-UI that is used as the content container within the Snackbar component.

<Snackbar 
       open={open} 
       onClose={handleClose} 
       autoHideDuration={4000}
       message="Hello World!"
       ContentProps={{
        sx:{
          //Content styles goes here
        }
       }}
/>
Enter fullscreen mode Exit fullscreen mode
  • ContentProps is props that applied to SnackbarContent and sx is the "lets you work with a superset of CSS that packages all of the style functions exposed in @mui/system"

Let's start with a simple style change:

<Snackbar 
       open={open} 
       onClose={handleClose} 
       autoHideDuration={4000}
       message="Hello World!"
       ContentProps={{
        sx:{
          border: "1px solid black",
          borderRadius: "40px",
          color: "black",
          bgcolor: "lightgreen",
          fontWeight: "bold",
        }
       }}
/>
Enter fullscreen mode Exit fullscreen mode

So, we add border, change colors and font weight.

Our new Snackbar should look like this:

Image description

It's sure better, but there is always things to improve

Let's focus the text alignment, I really like centered texts in Snackbar. But adding textAlign:"center" in sx props directly will not work, Why ?
It's because we are only styling the SnackbarContent component. SnackbarContent also contains additional containers, such as the message and action containers. To align the text properly, we need to override the styles of the message container in ContentProps, to make this happen we can use a syntax like below:

<Snackbar 
       open={open} 
       onClose={handleClose} 
       autoHideDuration={4000}
       message="Hello World!"
       ContentProps={{
        sx:{
          border: "1px solid black",
          borderRadius: "40px",
          color: "black",
          bgcolor: "lightgreen",
          fontWeight: "bold",
          textAlign: "center",
          // centering our message
          width:"100%",
          "& .MuiSnackbarContent-message":{
            width:"inherit",
            textAlign: "center",
          }
        }
       }}
/>
Enter fullscreen mode Exit fullscreen mode

What are we doing here?

  • First we add width prop to our SnackbarContent styles, which is width:"100%", We should add this because we want to fill all the spaces of Snackbar with SnckbarContent

  • Then we select the message wrapper: "& .MuiSnackbarContent-message":{}, this is how we select elements in Material UI. The "&" symbol is used as a reference to the current component or container and ".MuiSnackbarContent-message" portion of the selector targets the specific class name associated with the message element within the SnackbarContent component.

  • Next we add, width:"inherit",textAlign: "center", inside of message container we select above.

Finally we have a centered Snackbar :

Image description

It is better right 😌

You can add additional styles to further customize the SnackbarContent component according to your preferences.

I suggest you to also add a Transition Property or change position of Snackbar easiliy with anchorOrigin.

Code Sandbox link

Top comments (0)