Reputation: 515
I am utilizing Material UI components but want to move all my styles into a .scss
file. Currently, I have a large styles object in the same javascript file where I use the Material UI components. This styles object is being passed to the Material UI components via the style
prop. This as I see it is more or less just inline styling and my goal is to eliminate this pattern. I have other nested components (Material UI ones as well as custom React ones) within these Material UI components. Here is an example I am working with:
const styles= {//all my css styles in here}
<TableRowColumn key={index} style={styles.column}>
<span className="checkbox-thing">
<input
....
/>
</span>
</TableRowColumn>
I have referenced the override documentation: https://material-ui-next.com/customization/overrides/
As well as this Stack Overflow question: How to style material ui next components with styled components and SASS
Both of these in my opinion do not make it clear how to go about using an external .scss
(where the styles would live) and referencing the class names in that file into the Material UI component. I simply was to be able to do something like this, which is currently easy to accomplish with normal HTML elements:
<input
type="checkbox"
checked={
this.props.isChecked
}
className="someClassInTheSCSSFile"
/>
In summary I want to:
Remove my large styles object into separate classes into a .scss
file
Reference a class in the .scss
file and pop it into a Material UI component
Upvotes: 2
Views: 11996
Reputation: 515
I have no rhyme or reason as to why this started working now as opposed to when I had tried before, but using className="someClassInTheSCSSFile"
ended up working provided my .scss
file contained something similar to:
//.scss file
.someClassInTheSCSSFile {
color: blue;
//rest of the styles go here
}
In summary, using the className
prop directly inside MATERIAL UI components works. So using the example code from my question the following works:
//Javascript file
<TableRowColumn key={index} className="someClassInTheSCSSFile">
<span className="checkbox-thing">
<input
....
/>
</span>
</TableRowColumn>
Now, what is actually really interesting (and disappointing) is when you want to pass a value to the CSS. For example, say this TableRowColumn
component has a width
attribute but I do not want to hard code it into my .scss
file. Sticking with my pattern of not using any inline styling, this presents a challenge. Lets says this TableRowColumn
component is inside a function that takes a parameter called colWidth
. When the function is called, I want to then dynamically pass this colWidth
value into my css width
attribute of this TableRowColumn
component. However, this ends up, as far as I can tell, being an impossible task at the moment. What can be done is:
//Javascript File
<TableRowColumn key={index} style={{width:`${coldWidth}`}} className="someClassInTheSCSSFile">
<span className="checkbox-thing">
<input
....
/>
</span>
</TableRowColumn>
But this is inline styling. Exactly what I was trying to avoid. So now, I end up having both inline styling AND a className
that references my .scss
file. Arguably more clunky and burdensome. How about if I use the attr()
function inside my .scss
? Well, according to MDN (https://developer.mozilla.org/en-US/docs/Web/CSS/attr) this will only support Strings being passed and all other types are not supported in mainstream browsers. Ouch. Refer to this codepen (https://jsfiddle.net/hmr0hckf/131/) for an example of this in action. Moral of the story, I'm stuck with inline styling for any css attribute where I want to dynamically alter the value.
Upvotes: 2
Reputation: 562
You're pretty close. Put all of your styles into one or many .scss files, like you normally would. For example, a class named "nodeContent."
.nodeContent {
position: absolute;
top: 0;
bottom: 0;
display: flex;
align-items: center;
}
All you need to do is import your styles and access the class names as property of your styles object. See below in this example I have a Sass file named styles.scss
in the same directory as my component. In my component I can import them like this:
import * as styles from './styles.scss'
The styles is an object and I can reference my classes like I would any other property of an object. So if I want to use the nodeContent class on a material component, I can do this:
<Card className={styles.nodeContent} />
I think you can compile your .scss files to .css and reference them as a in your index.html file. After that, I think you should be able to reference the classNames as a string like you showed above. Here's the article I just read that is similar, except they import the css file in their component: https://hackernoon.com/using-sass-with-create-react-app-without-ejecting-b5f4f827ed9e
Upvotes: 0