
In this article, we are going to build a responsive Drawer that adjusts itself according to screen size using material-UI framework. If you are new visit here for installing and getting started with Material-UI.
In the code below first we will set up a simple drawer then we will add a feature of hiding the drawer according to the screen size.
Let’s get started, open up your text editor, and write the following code:
Drawer
import React from 'react';
import AppBar from '@material-ui/core/AppBar';
import Drawer from '@material-ui/core/Drawer';
import Toolbar from '@material-ui/core/Toolbar';
import Divider from '@material-ui/core/Divider';
import Hidden from '@material-ui/core/Hidden';
import List from '@material-ui/core/List';
import IconButton from '@material-ui/core/IconButton';
import MenuIcon from '@material-ui/icons/Menu';
import ListItem from '@material-ui/core/ListItem';
import ListItemText from '@material-ui/core/ListItemText';
import Typography from '@material-ui/core/Typography';
import {makeStyles} from '@material-ui/core/styles';
import img1 from './img1.jpg';
import img2 from './img2.jpg';
const drawerWidth = 240;
const useStyles = makeStyles((theme) => ({
drawer: {
width: drawerWidth,
flexShrink: 0,
},
toolbar : theme.mixins.toolbar,
content : {
flexGrow: 1,
padding: theme.spacing(3),
marginLeft: 300,
}
}));
export default function App() {
const classes = useStyles();
const drawer = (
<div>
<div>
<Divider />
<List>
{['Search','Browse','Category'].map((anchor,text) => (
<ListItem button key = {anchor}>
<ListItemText primary = {anchor}/>
</ListItem>
))}
</List>
<Divider />
<List>
{['Services','About Us','Contact Us'].map((anchor,text) => (
<ListItem button key = {anchor}>
<ListItemText primary = {anchor}/>
</ListItem>
))}
</List>
</div>
</div>
)
return (
<div>
<AppBar position = 'fixed'>
<Toolbar>
<Drawer
classes={{
paper: classes.drawer,
}}
open
variant = 'permanent'
>
{drawer}
</Drawer>
</Toolbar>
</AppBar>
<div className={classes.content}>
<div className={classes.toolbar} />
<img src={img1} style={{height:'auto' , width:'80%'}}
alt = "img1" />
<Typography paragraph>
I inadvertently went to See's Candy last week (I was
in the mall looking for phone repair), and as it turns
out, See's Candy now charges a dollar -- a full dollar
-- for even the simplest of their wee confection
offerings. I bought two chocolate lollipops and two
chocolate-caramel-almond things. The total cost was
four-something. I mean, the candies were tasty and all,
but let's be real: A Snickers bar is fifty cents.
After this dollar-per-candy revelation, I may not
find myself wandering dreamily back into a See's
Candy any time soon.
</Typography>
<img src={img2} style={{height:'auto' , width:'80%'}} alt = "img1" />
<Typography paragraph>
Spending time at national parks can be an exciting
adventure, but this wasn't the type of excitement she was
hoping to experience. As she contemplated the situation
she found herself in, she knew she'd gotten herself in a
little more than she bargained for. It wasn't often that
she found herself in a tree staring down at a pack of
wolves that were looking to make her their next meal.
</Typography>
</div>
</div>
);
}
In the above code first, we define the width of our drawer which is 240px. Then in the App()
function, we have defined our drawer
which contains the list of items such as Browser, Category, etc. To make our app visual we have added an AppBar on top of this we will have our drawer. The way we create drawer is by using material-UI Drawer
tag. Since our drawer should be visible we pass open
props to our Drawer
tag. Also, we have passed variant
to permanent
so that our other content on the page does not get block out.
Next, we write out App content. The classes.toolbar
property in the div
tag tells that our content should be below the AppBar. Also, our content should have left margin of at least 240px so it does not hide behind our drawer. The output of the following App we something look like this:


But if you make your screen smaller you will notice that our Drawer sticks their and content gets smaller and smaller. We don’t want that we want our drawer to automatically hide if the display screen is smaller so that the user can read our content. So to make drawer hide we will be using material-UI Hidden
tag.
Modify the code as follows:
Responsive Drawer
import React from 'react';
import AppBar from '@material-ui/core/AppBar';
import Drawer from '@material-ui/core/Drawer';
import Toolbar from '@material-ui/core/Toolbar';
import Divider from '@material-ui/core/Divider';
import Hidden from '@material-ui/core/Hidden';
import List from '@material-ui/core/List';
import IconButton from '@material-ui/core/IconButton';
import MenuIcon from '@material-ui/icons/Menu';
import ListItem from '@material-ui/core/ListItem';
import ListItemText from '@material-ui/core/ListItemText';
import Typography from '@material-ui/core/Typography';
import {makeStyles} from '@material-ui/core/styles';
import img1 from './img1.jpg';
import img2 from './img2.jpg';
const drawerWidth = 240;
const useStyles = makeStyles((theme) => ({
drawer: {
width: drawerWidth,
flexShrink: 0,
},
toolbar : theme.mixins.toolbar,
content : {
flexGrow: 1,
padding: theme.spacing(3),
[theme.breakpoints.up('sm')]: {
marginLeft: 300,
},
}
}));
export default function App() {
const classes = useStyles();
const [state,setSmallDevice] = React.useState(false);
const handleSmallDevice = () => {
setSmallDevice(!state);
};
const drawer = (
<div>
<div>
<Divider />
<List>
{['Search','Browse','Category'].map((anchor,text) => (
<ListItem button key = {anchor}>
<ListItemText primary = {anchor}/>
</ListItem>
))}
</List>
<Divider />
<List>
{['Services','About Us','Contact Us'].map((anchor,text) => (
<ListItem button key = {anchor}>
<ListItemText primary = {anchor}/>
</ListItem>
))}
</List>
</div>
</div>
)
return (
<div>
<AppBar position = 'fixed'>
<Toolbar>
<Hidden smUp implementation="css">
<IconButton
color="inherit"
aria-label = "open drawer"
edge = 'start'
onClick = {handleSmallDevice}
> <MenuIcon />
</IconButton>
<Drawer
classes={{
paper: classes.drawer,
}}
open={state}
onClose = {handleSmallDevice}
>
{drawer}
</Drawer>
</Hidden>
<Hidden xsDown implementation="css"> <Drawer
classes={{
paper: classes.drawer,
}}
open
variant = 'permanent'
>
{drawer}
</Drawer>
</Hidden>
</Toolbar>
</AppBar>
<div className={classes.content}>
<div className={classes.toolbar} />
<img src={img1} style={{height:'auto' , width:'80%'}}
alt = "img1" />
<Typography paragraph>
I inadvertently went to See's Candy last week (I was
in the mall looking for phone repair), and as it turns
out, See's Candy now charges a dollar -- a full dollar
-- for even the simplest of their wee confection
offerings. I bought two chocolate lollipops and two
chocolate-caramel-almond things. The total cost was
four-something. I mean, the candies were tasty and all,
but let's be real: A Snickers bar is fifty cents.
After this dollar-per-candy revelation, I may not
find myself wandering dreamily back into a See's
Candy any time soon.
</Typography>
<img src={img2} style={{height:'auto' , width:'80%'}} alt = "img1" />
<Typography paragraph>
Spending time at national parks can be an exciting
adventure, but this wasn't the type of excitement she was
hoping to experience. As she contemplated the situation
she found herself in, she knew she'd gotten herself in a
little more than she bargained for. It wasn't often that
she found herself in a tree staring down at a pack of
wolves that were looking to make her their next meal.
</Typography>
</div>
</div>
);
}
The Hide
tag hides the content under it up to certain breakpoints it has reached. In the above code, we have used to hide tag. So if the screen is smaller we want our drawer to hide. Also, we want to display some kind of button so that the user can click on it to open the drawer. So for toggling the drawer we need some kind of state which tells that whether the drawer is open or close and based on this we open or close the drawer. We are using React.useState()
hook to define our drawer state.
So basically we are having to drawer wrapped inside the Hide
tag. One of them will be shown and the other one will be hidden based on the screen size. The smUp
props in the Hide
tag says that if the screen size if 600px or more hide the content which is inside the tag or in other words if the screen is large enough make the drawer visible and permanent. Also in our classe.content
property, we have specified:
[theme.breakpoints.up('sm')]: {
marginLeft: 300,
},
which will leave 300px margin from left if the drawer on open and permanent so our content does not get hidden under the drawer. The xsDown
props in the second Hide
tag hide our permanent drawer or in other words, it will show our toggling drawer.

