How to Create Beatiful Snackbar Component with Material UI + React + CSS in sx🤔
Tags: react, ui, css, frontend
Published: 2023-07-10 14:04:04

**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
```

### 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";
```
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;
```
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 **_handleClose_**function. 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hnxn5cuo8z4tmq7dl8d0.png)

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
        }
       }}
/>
```

- **_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",
        }
       }}
/>
```
So, we add border, change colors and font weight.

Our new Snackbar should look like this:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0fx24mcr1caoc4380rkg.png)

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](https://mui.com/material-ui/api/snackbar-content/#css). 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",
          }
        }
       }}
/>
```
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zewwrieo2girxbw50kzb.png)

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](http://reactcommunity.org/react-transition-group/transition) or change position of Snackbar easiliy with [anchorOrigin](https://mui.com/material-ui/react-snackbar/#positioned-snackbars).

[Code Sandbox link](https://codesandbox.io/s/amazing-shirley-962ykp?file=/src/App.js)