The Material-ui Drawer does not function properly when used with an external CSS file

For my project, I'm working on a Sidebar design that is inspired by the Mini Variant drawer demo available at this link. However, the project requirements mandate that all CSS styling should be done in a separate CSS file rather than directly within the JS file. I've managed to style the sidebar based on the demo, but now I need to find a way to separate and implement the CSS styles effectively.

Currently, the sidebar renders with default settings, but most of the CSS classes are not functioning as intended except for one: listItem. This specific class successfully alters the height of a ListItem, which is quite peculiar. The rest of the CSS classes seem to have no effect on the appearance of the sidebar.

Below is the non-functional version where the CSS is imported from a separate file:

.root {
    display: flex;
}

.drawerOpen {
    top: 70px; 
    bottom: 70px;
    position: fixed;
    white-space: nowrap; /*text doesn't shrink into side*/
    width: 240;
    transition: width 2s;
}

.drawerClose {
    top: 70px; 
    bottom: 70px;
    position: fixed;
    width: 240;
    overflow-x: hidden; /*hides text when drawer is closed*/
    transition: width 2s;
}

.iconButton {
    margin-top: 15px;
    margin-bottom: 7px;
}

.listItem { 
    height: 75px;
}

SideBar.js:

import React, { Component } from "react";
import PropTypes from "prop-types";
import Drawer from "@material-ui/core/Drawer";
import { withStyles } from "@material-ui/core/styles";
import { IconButton, Divider, ListItemIcon } from "@material-ui/core";
import { List, ListItem, ListItemText } from "@material-ui/core";
import InboxIcon from "@material-ui/icons/MoveToInbox";
import MailIcon from "@material-ui/icons/Mail";
import ChevronRightIcon from "@material-ui/icons/ChevronRight";
import ChevronLeftIcon from "@material-ui/icons/ChevronLeft";
import "../css/SideBar.css";

class Sidebar extends Component {
  state = {
    open: false
  };

  handleSidebarToggle = () => {
    this.setState({ open: !this.state.open });
  };

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

    return (
      <div className="root">
        <Drawer
          variant="permanent"
          anchor="left"
          open={open}
          className={(open === true) ? "drawerOpen" : "drawerClose"}
        >
          <div>
            <Divider />
            <IconButton
              className="iconButton"
              onClick={this.handleSidebarToggle}
            >
              {open === false ? <ChevronRightIcon /> : <ChevronLeftIcon />}
            </IconButton>
          </div>
          <List>
            <Divider />
            <ListItem className="listItem" button>
              <ListItemIcon>
                <InboxIcon />
              </ListItemIcon>
              <ListItemText primary="Info" />
            </ListItem>
            
            ... // Additional list items
            
          </List>
        </Drawer>
      </div>
    );
  }
}
export default Sidebar;

And here is the functional version combining the JS and CSS code:

import React, { Component } from "react";
import PropTypes from "prop-types";
import Drawer from "@material-ui/core/Drawer";
import { withStyles } from "@material-ui/core/styles";
import { IconButton, Divider, ListItemIcon } from "@material-ui/core";
import { List, ListItem, ListItemText } from "@material-ui/core";
import InboxIcon from "@material-ui/icons/MoveToInbox";
import MailIcon from "@material-ui/icons/Mail";
import ChevronRightIcon from "@material-ui/icons/ChevronRight";
import ChevronLeftIcon from "@material-ui/icons/ChevronLeft";
import "../css/SideBar.css";

const styles = theme => ({
  root: {
    display: "flex",
  },
  
  ... // Add more styled classes
  
  listItem: { 
    height: "75px"
  }
});

... // Continue the component implementation

export default withStyles(styles, { withTheme: true })(Sidebar);

Answer №1

If you want to separate your styles into a different file, you can create a .js file and reference it in your component.

Material-UI utilizes CSS-in-JS, which you can learn more about by visiting this link: https://material-ui.com/customization/css-in-js/

In your case, you can create a styles.js file within the same folder as your component (or any desired location) with the following content:

export default const styles = {
  .root {
    display: flex;
  }

  .drawerOpen {
    top: 70px; 
    bottom: 70px;
    position: fixed;
    white-space: nowrap; /*text doesn't shrink into side*/
    width: 240;
    transition: width 2s;
  }

  .drawerClose {
    top: 70px; 
    bottom: 70px;
    position: fixed;
    width: 240;
    overflow-x: hidden; /*hides text when drawer is closed*/
    transition: width 2s;
  }

  .iconButton {
    margin-top: 15px;
    margin-bottom: 7px;
  }

  .listItem { 
    height: 75px;
  }
}

Then, in your component, you can reference these styles like so:

import styles from "./styles"

... component code ...

export default withStyles(styles)(Sidebar);

To further customize Material-UI components, check out this link for more information on styling overrides: https://material-ui.com/customization/overrides/

I hope this explanation proves helpful to you.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The relationship between formatting context and atomic inline-level boxes is crucial for understanding

Check out this link for more information on inline boxes An inline box is a unique element that falls under the category of both inline-level and participates in its containing inline formatting context. When a non-replaced element has a 'display&ap ...

What could be causing these alerts to appear whenever I execute certain npm react commands?

There are a total of 6 high severity vulnerabilities. To resolve all problems, including any breaking changes, execute the following command: npm audit fix --force ...

Why am I seeing numbers in the output when I log the data from the res.write(data) function in Node.js?

While working with Node.js on my Raspberry Pi, I encountered an issue where reading a local file 'test.html' resulted in hex output instead of the expected HTML format. Can someone explain why this might be happening? Additionally, I am aware tha ...

The drop-down button unexpectedly disappears when using Bootstrap in combination with jQuery autocomplete

I have some javascript code that is structured like: <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>jQuery UI Autocompl ...

Having difficulty in closing Sticky Notes with JavaScript

Sticky Notes My fiddle code showcases a functionality where clicking on a comment will make a sticky note appear. However, there seems to be an issue with the Close Button click event not being fired when clicked on the right-hand side of the note. I have ...

Autocomplete with Material-UI: Display value in label when option is selected, not the label itself

I have a customized MUI Autocomplete setup where I'm utilizing react-hook-form in conjunction with Material UI Autocomplete. The Autocomplete component is being populated with options from the options prop. My goal is to have the selected option&apo ...

Tips for CSS and jQuery: Show link when hovered over and switch the visibility of a content div

I'm facing an issue with a link in the horizontal navigation bar. When a user hovers over it, I want another div to slide down just below it. The problem is that using the .toggle method doesn't work as expected. It continuously toggles the div e ...

My locale NUXT JavaScript files are being blocked by Content Security Policy

I've been working on implementing CSP headers for my website to ensure data is loaded from trusted sources. However, I'm facing an issue where CSP is blocking my local JS files. Here's a snippet from my nuxt.config.js: const self = 'lo ...

The function `res.json()` is being called before the for loop has completed its execution

I am facing an issue with my application where the endpoint is supposed to fetch data from a MongoDb Database and return the results to the client. However, I am encountering a problem where an empty array is being sent before my for(){} loop finishes exec ...

Creating a layout with Bootstrap 4 cards split into two rows

I need to change my layout from 3 columns to 2 columns. I know I can achieve this using CSS like the code snippet below, but I'm curious if there's a built-in Bootstrap method for this: .card-columns { -webkit-column-count: 2; -moz-column-co ...

Is it possible to dynamically alter a CSS property using styled components when an onClick event occurs?

Hey there, I'm pretty new to React and currently exploring styled components for the CSS styling of my components. One of the components I've created is a button called SummonButton: const SummonButton = styled.button` height: 50px; borde ...

Tips for sending a form and showing results without the need to refresh the page

I am currently working on developing a basic calculator that takes a user input number and displays the calculated output without redirecting or reloading the page. However, since I have no experience with JavaScript (js) and Ajax, I am seeking assistance ...

Steps to create a responsive iframe for Slideshare

Recently, I included a slideshare iframe presentation on my webpage. Here is the code snippet I used: <iframe src="//www.slideshare.net/slideshow/embed_code/key/HQoiz6GR1oLe1n" width="860" height="600" frameborder="600" marginwidth="0" marginheight="0 ...

Using jQuery Ajax to send data and retrieve responses in the Codeigniter framework

I am struggling with passing values in CodeIgniter and I need some guidance. Could you provide an example code snippet using CodeIgniter to send a value from a view to a controller using Ajax and jQuery, and then display the result on the same page? In my ...

Using React-Router to manage URL parameters

//BlogPostPage const BlogPostPage = ({ match }) => { const title = match.params.title; return ( <> <h1> This is {title} Blog Post </h1> </> ); } export default BlogPostPage; //Webs ...

A JavaScript function utilizing lodash's forEach method that is returning an undefined value

I've encountered a problem while developing a ReactJS app. In one of my functions called filterSelected, I have a for loop that iterates through an array of region names (e.g. ["Thailand", "Malaysia"]) and is supposed to return an array of their corre ...

After updating the INNERHTML, the NAV tag content is no longer functional

I am facing an issue with replacing the contents of a NAV tag that contains UL list items. The original HTML within the NAV tag works perfectly fine, but when I replace it with my own HTML - which matches the original word for word - the dropdown functiona ...

Filter array to only include the most recent items with unique names (javascript)

I'm trying to retrieve the most recent result for each unique name using javascript. Is there a straightforward way to accomplish this in javascript? This question was inspired by a similar SQL post found here: Get Latest Rates For Each Distinct Rate ...

extract information from local storage using AngularJS

I'm having trouble getting the filter to work in my AngularJS project with local storage. Even though there are no errors, nothing happens when I type words into the input field. Can someone lend a hand? :) html: <div ng-app="myApp" ng-controller ...

Synchronize the completion of multiple promises in ExpressJs before sending a response

My POST API contains some logic that needs to wait for all promises to finish before sending the response. However, I'm facing an issue with making my server wait using await Promise.all(tasks); I've tried various approaches and even used librar ...