Customize Material UI components by incorporating SASS classes

Currently, I am using Material UI components but I want to streamline my styles by moving them all into a .scss file. Right now, I have a significant styles object within the same JavaScript file where I am utilizing the Material UI components. This styles object is passed to the Material UI components through the style prop, essentially resulting in inline styling. My aim is to eliminate this practice. Additionally, I have nested components (both Material UI and custom React ones) within these Material UI components.

 const styles= {//my css styles go here}

<TableRowColumn key={index} style={styles.column}>
     <span className="checkbox-thing">
       <input
         ....
       />
     </span>
</TableRowColumn>

I have looked at the override documentation: Material UI Next Customization Overrides

I also came across this Stack Overflow question: How to style material ui next components with styled components and SASS

In my opinion, neither of these resources provides clear guidance on how to use an external .scss file to store styles and then reference those class names within the Material UI component. Ideally, I would like to achieve something similar to working with normal HTML elements:

<input   
    type="checkbox"
    checked={
      this.props.isChecked
    }
    className="someClassInTheSCSSFile"
/>

To sum up, my goals are:

  • Move my large styles object into separate classes in a .scss file

  • Reference a class from the .scss file and apply it to a Material UI component

Answer №1

It's a mystery why this approach is suddenly working now when it didn't before, but using

className="someClassInTheSCSSFile"
seems to do the trick as long as my .scss file includes something like:

//.scss file

.someClassInTheSCSSFile {
   color: blue;
   //rest of the styles go here
}

So, in short, utilizing the className prop directly inside MATERIAL UI components does work. For example, my code snippet below functions as intended:

//Javascript file

<TableRowColumn key={index} className="someClassInTheSCSSFile">
 <span className="checkbox-thing">
   <input
     ....
   />
 </span>
</TableRowColumn>

The real challenge arises when trying to dynamically pass a value to the CSS property. Let's say the width attribute of the TableRowColumn component shouldn't be hardcoded in the .scss file. When I attempt to achieve this without using inline styling, it becomes quite problematic. If the colWidth parameter needs to be passed into the css width attribute of the TableRowColumn component, it seems nearly impossible at the moment. The workaround involves:

//Javascript File

<TableRowColumn key={index} style={{width:`${coldWidth}`}} className="someClassInTheSCSSFile">
 <span className="checkbox-thing">
   <input
     ....
   />
 </span>
</TableRowColumn>

This leads to inline styling, which goes against my initial goal. Thus, I end up with both inline styling and a className that references my .scss file, making the solution seem clunky and cumbersome. Can the attr() function within the .scss file offer a better alternative? Unfortunately, according to MDN (https://developer.mozilla.org/en-US/docs/Web/CSS/attr), only strings can be supported by this method, while other data types are not widely recognized in mainstream browsers. Take a look at this codepen (https://jsfiddle.net/hmr0hckf/131/) for a demonstration. Ultimately, it seems that inline styling is unavoidable if dynamic changes to css attributes are required.

Answer №2

Implementing Webpack with node-sass and sass-loader

Getting the hang of it! Just gather all your styles in one or multiple .scss files, business as usual. Let's say you have a class called "nodeContent."

.nodeContent {
   position: absolute;
   top: 0;
   bottom: 0;
   display: flex;
   align-items: center;
}

All you have to do is import your styles and access the class names like properties of your styles object. For instance, if I have a Sass file named styles.scss in the same directory as my component, I can import them this way:

import * as styles from './styles.scss'

The 'styles' variable is an object that allows me to refer to my classes similar to any other object property. So, when I want to apply the nodeContent class on a material component, I can simply do this:

<Card className={styles.nodeContent} />

If You're Not Using Webpack (not entirely certain on this)

You may compile your .scss files into .css format and link them as a stylesheet in your index.html file. Subsequently, you should be able to use the classNames as strings as demonstrated above. Here's a related article I came across where they import the css file within their component:

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

A navigation bar resembling the style of Google's Inbox web application

I am in the process of developing a react web application and implementing material ui for the project. My goal is to create an appbar similar to the one featured in Google Inbox (refer to screenshot below). Although I have imported the Appbar component fr ...

The asynchronous ajax request is leading to a browser freeze

In the HTML page, I have two sets of a and p elements that are initially set to display:none. At the bottom of the page, there is a function being called with their respective ID's and values, which will enable one of them based on certain conditions ...

Attempting to update an AJAX field with the returned value, but it only updates after clicking away from it

Image of form utilizing AJAX & JS The current setup involves a maintainer that uses AJAX to update the "Calc" field in response to a number entered in the "Order No" field. The issue is that the "Calc" field does not update immediately after typing in the ...

Creating responsive D3.js charts for various screen sizes and devices

After creating a chart using d3.js, I noticed that the chart does not resize when zooming in or out on the web browser window. Below is the code snippet of what I have attempted so far: <!DOCTYPE html> <html> < ...

What is the best way to stack several items vertically beside an image?

As a beginner in the world of web development, I recently embarked on my first project. However, I am facing an issue where I cannot align multiple elements under each other next to an image. One element floats at the top beside the image, while the other ...

Changing the visibility of a button based on a checkbox in JavaScript - here's how

Just starting out with JS and working on a react project. I need to toggle the visibility of a button from false to true when a checkbox is checked. Here's my code, I believe the logic is correct but it's not updating the UI. Any suggestions are ...

Encountering an issue when trying to send data with Axios client to the child component

I'm encountering an issue while attempting to pass data to a child component for rendering. import axios from 'axios'; import React from 'react'; import MovieCard from './MovieCard'; import { useState, useEffect } from ...

Creating a custom type for the parameter of an arrow function in Typescript

I need assistance defining the type for an object parameter in an arrow function in TypeScript. I am new to TypeScript and have not been able to find any examples illustrating this scenario. Here is my code: const audioElem = Array.from(videoElem.pare ...

extract information from an external JSON document

I have a JSON file filled with data, along with a JSX file containing a button and a div. I'm looking to extract the data from the JSON file and display it in the div when the button is clicked. However, I'm at a loss on how to achieve this. The ...

What is the best way to stop a current action when a new action is initiated?

My current setup involves an action creator that performs a costly calculation and triggers an action when the user inputs data in real-time. The challenge arises when multiple inputs are entered, as I want to avoid running the entire expensive calculati ...

What causes the static data on each request in Next.js dynamic pages?

I'm encountering an issue with a dynamic page called [className].js. I am using getServerSideProps to fetch data, but for some reason, regardless of which link I click, it always displays the data from the first set. How can I ensure that the specifie ...

Combine the content from multiple text areas and submit it to another text area

****UPDATE**** Thanks to @JasonB, I was able to resolve the previous issue mentioned. Now, I have three additional textareas on the same form that should only appear when their respective checkboxes are clicked. How can I integrate this into my current sc ...

Is the input box failing to show up on your screen?

I recently tackled the task of creating a commenting feature for RSS articles Throughout my journey with PHP coding, I encountered an issue where the input box for comments was not displaying. https://i.stack.imgur.com/gJIlu.png Check out the snippet fr ...

Tips for filling in the values for the options in a select dropdown menu

Currently, I am facing a strange bug related to the select element. Whenever I open the dropdown, there is always a mysterious black option at the top. This is how my HTML looks like: This particular element is part of my test controller. <select ng- ...

Received an unexpected argument count of 1 instead of the expected 0 while passing a function as a prop to a child component

I transferred the deleteImgfunc function from the insertFarmDiaryDetail component to the InsertFarmDiarySubPage component, which acts as a child component. DeleteImgfunc is a parameter-receiving function. Despite creating an interface and defining paramet ...

Encountering an error during package installation in Npm

Recently, as I was working on a reactjs project and trying to install new packages using npm, an unexpected issue arose. Every time I attempted to add a package, the npm installer would throw the same error. Despite my attempts to fix the problem by reinst ...

The styles defined in CSS do not have an impact on EJS templates that have GET route paths stacked

I have a CSS file located in the public directory and two EJS templates in the views directory. The CSS file works fine when using this route: app.get('/theresa', (req, res) => { res.render('templates/home') }) However, when I ...

The propagation of SVG events from embedded images via the <image> elements

I'm currently developing a diagramming tool using HTML, CSS, and Javascript with SVG for the drawing canvas. This tool consists of predefined "building blocks" that users can place on the canvas, rather than allowing free-hand drawing of shapes. Each ...

How can you make the browser window scroll horizontally when a div is clicked using jQuery?

I have an image of an arrow inside a div. The div is positioned fixed in the bottom right corner of an extremely wide page. Is there a way to utilize jQuery to scroll the window 600px to the right each time the arrow is clicked? Also, can I detect when th ...

Function compilation did not succeed in the module

I've put together a MERN (MongoDB, ExpressJS, React, Node) project using express-generator (express myNewApp). Within a react component, I have implemented this ES6 code snippet: onChange = (event, { newValue }) => { // Line 53 this.setSt ...