100% height not working for Drawer, Material Design React

Viewed 21772

I'm using the responsive drawer from the React Material UI ([Documentation][1])

I'm trying to change it so that the Drawer will always have a height of 100%. To do this, I tried changing the height of the root class which is currently set to 430. However, when I set it to a percentage it just default to the smallest possible height.

import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { withStyles } from 'material-ui/styles';
import Drawer from 'material-ui/Drawer';
import AppBar from 'material-ui/AppBar';
import Toolbar from 'material-ui/Toolbar';
import List from 'material-ui/List';
import { MenuItem } from 'material-ui/Menu';
import TextField from 'material-ui/TextField';
import Typography from 'material-ui/Typography';
import Divider from 'material-ui/Divider';
import { mailFolderListItems, otherMailFolderListItems } from './tileData';

const drawerWidth = 240;

const styles = theme => ({
  root: {
    width: '100%',
    height: 430,
    marginTop: theme.spacing.unit * 3,
    zIndex: 1,
    overflow: 'hidden',
  },
  appFrame: {
    position: 'relative',
    display: 'flex',
    width: '100%',
    height: '100%',
  },
  appBar: {
    position: 'absolute',
    width: `calc(100% - ${drawerWidth}px)`,
  },
  'appBar-left': {
    marginLeft: drawerWidth,
  },
  'appBar-right': {
    marginRight: drawerWidth,
  },
  drawerPaper: {
    position: 'relative',
    height: '100%',
    width: drawerWidth,
  },
  drawerHeader: theme.mixins.toolbar,
  content: {
    backgroundColor: theme.palette.background.default,
    width: '100%',
    padding: theme.spacing.unit * 3,
    height: 'calc(100% - 56px)',
    marginTop: 56,
    [theme.breakpoints.up('sm')]: {
      height: 'calc(100% - 64px)',
      marginTop: 64,
    },
  },
});

class PermanentDrawer extends React.Component {
  state = {
    anchor: 'left',
  };

  handleChange = event => {
    this.setState({
      anchor: event.target.value,
    });
  };

  render() {
    const { classes } = this.props;
    const { anchor } = this.state;

    const drawer = (
      <Drawer
        type="permanent"
        classes={{
          paper: classes.drawerPaper,
        }}
        anchor={anchor}
      >
        <div className={classes.drawerHeader} />
        <Divider />
        <List>{mailFolderListItems}</List>
        <Divider />
        <List>{otherMailFolderListItems}</List>
      </Drawer>
    );

    let before = null;
    let after = null;

    if (anchor === 'left') {
      before = drawer;
    } else {
      after = drawer;
    }

    return (
      <div className={classes.root}>
        <TextField
          id="permanent-anchor"
          select
          label="Anchor"
          value={anchor}
          onChange={this.handleChange}
          margin="normal"
        >
          <MenuItem value="left">left</MenuItem>
          <MenuItem value="right">right</MenuItem>
        </TextField>
        <div className={classes.appFrame}>
          <AppBar className={classNames(classes.appBar, classes[`appBar-${anchor}`])}>
            <Toolbar>
              <Typography type="title" color="inherit" noWrap>
                Permanent drawer
              </Typography>
            </Toolbar>
          </AppBar>
          {before}
          <main className={classes.content}>
            <Typography type="body1">
              {'You think water moves fast? You should see ice.'}
            </Typography>
          </main>
          {after}
        </div>
      </div>
    );
  }
}

PermanentDrawer.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(PermanentDrawer);


  [1]: https://material-ui-next.com/demos/drawers/
7 Answers

Be sure to us minHeight: '100vh' as opposed to just height: 100vh Otherwise the page won't scroll.

Alright, what Ted says is correct. It has to be turtles all the way down (or 100% all the way down in this case :P). I changed my styles to the following (note I started from the responsive drawer example, looks like you are using the permanent drawer, but the same principal applies):

const styles = theme => ({
  root: {
    width: '100%',
    marginTop: 0,
    zIndex: 1,
    height: '100%',
    overflow: 'hidden',
  },
  appFrame: {
    position: 'relative',
    display: 'flex',
    width: '100%',
    height: '100%',
  },
  content: {
    backgroundColor: theme.palette.background.default,
    width: '100%',
    padding: theme.spacing.unit * 3,
    height: 'calc(100% - 56px)',
    marginTop: 56,
    [theme.breakpoints.up('sm')]: {
      height: 'calc(100% - 64px)',
      marginTop: 64,
    },
    'overflow-x': 'scroll',
  },
  gridRoot: {
    flexGrow: 1,
  },
  gridPaper: {
    padding: theme.spacing.unit * 2,
    height: '100%',
  },
});

This still didn't work - the key for me was changing my html and body height (and every other parent above root) to 100% height (so the html, body, and #app where my react app is rendered). Here is my app.scss:

html {
  height: 100%;
}

body {
  height: 100%;
  margin: 0px;
}

#app {
  height: 100%;
}

Hope this helps!

Adding height: '100%' to both the body and html worked for me

A percentage in css is relative to the size of its container. If you want something to be 100% height then I suggest using JS to get the window height, otherwise you'll need to set a static height.

Using height: '100vh' on the Drawer component and using the following style on the content worked for me:

[theme.breakpoints.up('md')]: {
  marginLeft: drawerWidth
}

I struggled with this same issue, and after reading the comments and finding my solution. I think the biggest takeaway is to understand that the Drawer has a default CSS property "Top: 0". this in terms pushes the element to the top left which makes it look like nothing is happening when the height is changed. So if simply changing the height doesn't fix your issue take a look at adding top: "auto". I hope this helps someone.

Related