Overriding colors in React Material UI - css

Does anyone know how to override colors in Material UI without using JS?
Is there a way to override colors using CSS only?

Yes. You can absolutely do that and there are multiple ways to go about it. Everything is explained in the official documentation here
The simplest way is to use the sx prop in your component but you can use only css also if you prefer to.

You can use styled to override styles. https://mui.com/system/styled/#main-content
import Box from '#mui/material/Box';
import { styled } from '#mui/system';
styled(Box)`
height: 100px;
width: 100px;
background-color: red;
`

import * as React from 'react';
import { styled } from '#mui/system';
const MyComponent = styled('div')({
color: 'darkslategray',
backgroundColor: 'aliceblue',
padding: 8,
borderRadius: 4,
});
export default function BasicUsage() {
return <MyComponent>Styled div</MyComponent>;
}

Related

Prevent a style (accidently loaded globally) from applying to a control

I'm trying to use TextField of Fluent UI.
import React from 'react';
import { TextField } from '#fluentui/react';
class Try extends React.Component {
render() {
return (
<TextField label="With auto" multiline autoAdjustHeight/>
);
}
}
export default Try;
Then, I realize that there is no space between the label and the text area. I check the CSS and understand that it is due to a label { margin-bottom: 5px; height: 22px } defined in index.css of another component XXX. Many tags and classes are defined in XXX/index.css such as form, label, input, button. Because I have import ./index.css in the component XXX and import ../XXX/index.css in several other components, XXX/index.css is loaded globally. And this XXX/index.css disturbs label of TextField of Fluent UI inside Try.
Does anyone know what I could do to Try component such that its TextField is not disturbed by XXX/index.css?
You may do this.
create another css file and load that css globally or just change that particular css only this the following.
label:not(#dont-apply-label *) { margin-bottom: 5px; height: 22px }
Now when you call the Fluent-Ui component, give a id
<TextField id="dont-apply-label" label="With auto" multiline autoAdjustHeight/>
This might not be best solution out of the box. But worth trying.
Another way can be triggering with class name like the following but not sure gonna work.
label:not(.ms-TextField *) { margin-bottom: 5px; height: 22px }

Unable to change rules of React Bootsrap using CSS Modules

I am trying to change the background color of a react-bootstrap list group item.
My example.js file
import {classes} from "./Sidebar.module.css";
import ListGroup from "react-bootstrap/ListGroup";
import React from "react";
const Sidebar = () => {
return (
<div>
<ListGroup>
<ListGroup.Item className = {classes.Color} >Products</ListGroup.Item>
<ListGroup.Item>Stores</ListGroup.Item>
</ListGroup>
</div>
)
}
Sidebar.module.css file has
.Color{
background-color: red;
Even after giving a custom class name, the background color is still the default color.
If you want to change a default color use !important. Also remove curly braces when you load styles from Sidebar.module.css. Like this
import classes from './Sidebar.module.css';
.Color {
background-color: red !important;
}

Grid Styling - Overwrite style of ag-grid

I have the following style:
.ag-theme-fresh .ag-row-selected {
background-color: #bde2e5;
}`
It comes from a css style file of a theme. But I want to overwrite it with this style:
.ag-theme-fresh .ag-row-even .ag-row-selected {
background-color: #1428df;
}
But it has not effect and my component uses the first style. How can I overwrite the first style 1? I tried with !important but it does nothing.
Should I define my custom style at the beginning of the css file?
UPDATE:
I found I can use the function gridOptions.getRowClass to set the style class to be used. But I would like to solve the issue central (for all the angular grids that I use in my application). Any idea?
You should use ViewEncapsulation
Just add to your component encapsulation: ViewEncapsulation.None:
import { Component, ViewEncapsulation } from "#angular/core";
#Component({
selector: '....',
templateUrl: '....',
styles: [`
.ag-theme-fresh .ag-row-selected {
background-color: #1428df !important;
}
`],
encapsulation: ViewEncapsulation.None
})
To override the ag-grid use you need to use ng-deep as the style defined in angular component do not overide ag-grid css
:host ::ng-deep .ag-header-cell-label {
justify-content: center;
}
update : this will make the style global. By changing the encapsulation set as none (ViewEncapsulation.None) at component will make style global as well.
if you are using sass or scss you could override in the style.scss/sass. this would be applicable at all places
#import "../node_modules/ag-grid-enterprise/dist/styles/ag-grid.scss";
#import "../node_modules/ag-grid-enterprise/dist/styles/ag-theme-alpine/sass/ag-theme-alpine-mixin";
.ag-theme-alpine {
#include ag-theme-alpine(
(
// use theme parameters where possible
alpine-active-color: #c066b2,
)
);
.ag-header-cell-label {
justify-content: center;
}
}
if you have need of doing at a specific grid, prefer custom class and make sub-class for the ag-grid.
You can also apply the styles globally and if you do so it will override the styles for all your ag-Grid components. This might not be an option if you are trying to style the components individually, but it's a good way to give a global base style override.
Also, you should try to use more specific selectors instead of using important.
Here is an example:
.ag-theme-alpine > .ag-row.ag-row-selected {
background : red;
}

Applying CSS stylesheet only to active component

I'm working on a ReactJS app that has a header at the top, a menu on the left, and the "frame" in the middle is where routes and their corresponding components are loaded. I want to be able to apply a CSS stylesheet to specific components only when they are loaded. I also don't want them applied all the time or to the top header or left menu.
My expectation was that adding import 'custom.css'; to a specific component would only apply the stylesheet's styles to that component and it's children when the route is active. Instead, it applies it to the entire page even when the route/component are not loaded.
I understand that an alternative approach is styled components, but, for my use-case, a design company is supplying a stylesheet (which should remain unchanged) that we need to consume only for the sub-module I'm working on and I don't want its styles to affect the rest of the app.
How can I have a stylesheet only applied to my active route/component?
Use simple CSS technique. Suppose you have two components with different css files (say about.css and contact.css). Now consider your both CSS file have one common class with different style properties, like:
about.css
.container{
max-width: 400px;
}
contact.css
.container{
max-width: 500px;
}
Yes in ReactJS both the CSS files will load at the same time and will override any one of the style. so to solve this problem add class to differentiate this styles, like:
about.css
.about-component.container{
max-width: 400px;
}
contact.css
.contact-component.container{
max-width: 500px;
}
If you want apply only when the component is mounted, you can use the lifecycle.
The follow example is based in the idea you are using sass, React, sass-node and have the loaders into webpack.
<pre>
import React from 'react';
import './styles.scss';
class MyComponent {
constructor(props) {
super(props);
this.state = { className: '' }
}
componentDidMount() {
this.setState({
className: 'myOwnClass'
});
}
render(){
return (
<div className={this.state.className}>This is a example</div>
);
}
}
export default myComponent;
</pre>
To be able to only call that specific CSS when you need it you can use CSS Modules. You may need to update your version of react.
When saving your CSS file save it with a ".module.css" eg. "styles.module.css". The CSS in these files can only be used and accessed by hte components where are they are imported. As stated in a tutorial from W3Schools.
Let's say this is your CSS code in styles.module.css:
.container {
color: white;
}
.cont-child {
background-color: red;
}
Then in your JS file you can import the CSS file like this if the JS and CSS files are in the same directory. Make sure you point to the correct path.
import styles from './styles.module.css'
Then in your HTML section you can use it like this:
class Home extends React.Component {
render() {
return(
<main className={ styles.container } >
<div className={ styles["cont-child"]} >
Some div text about something...
</div>
</main>
);
}
}
I currently use both ways to access the selectors, since the styles variable acts like an object. I placed both of them here because the second option is capable of fetching selectors named like "btn-active". Which comes in handy in some situations. Camelcasing is considered cleaner though.
Please note: I originally posted this answer as a reply to a similar question here React CSS - how to apply CSS to specific pages only
I want to be able to apply a CSS stylesheet to specific components
only when they are loaded.
Why not apply the styles inline via React.js?
Step 1. Create the style object for the component:
var componentOneStyle = {
color: 'white',
backgroundColor: 'red'
};
Step 2. Populate the component's style attribute with the style object:
ReactDOM.render(<div style={componentOneStyle}>This is Component One</div>, mountNode);

CSS Modules, React and Overriding CSS Classes

I am using a React component library (React Toolbox), which is outputting this class in their Tab component using CSS Modules and Webpack: label___1nGy active___1Jur tab___Le7N The tab is a className prop I am passing down. The label and active classes are coming from the library. I want to apply a different set of styles on active, something like .tab.active where tab is referring to the styles I have created and active matches the generated selector the library has created but cannot figure out how to do this with css-modules. I need to override this dynamically selector: .label___1nGy.active___1Jur.
[]]2
[]3
Old post but still relevant, so adding an answer to help those with similar issue
While not inherently possible in CSS modules alone, the author of the react-toolbox library has actually solved this particular problem very nicely
Read their github docs which are more in depth on the subject at https://github.com/react-toolbox/react-toolbox#customizing-components
A list of the themeable classes for a particular component is given on the component demo page on their site too
In your case as well as passing a className for tab, you would also create a theme with classes that overrides that desired parts of the default theme and pass that as the theme prop. For example something alog the lines of...
MyComponentWithTabs.css
.tab {
color: white;
}
MyTabTheme.css
.active {
color: hotpink;
}
MyComponentWithTabs.js
import styles from './MyComponentWithTabs.css'
import tabTheme from './MyTabTheme.css'
// blah blah...
return <Tab key={index} className={styles.tab} theme={tabTheme} />
Under the surface this uses a decorator they have abstracted into separate library react-css-themr, I recommend giving that a read too as it explains how the defaults are composed with your overrides in much greater depth, including the different merging strategies they use
I had a similar case, and I solved it like so:
import classNames from 'classnames';
...
const activeClassName = {};
activeClassName[`${styles.active}`] = this.props.isActive;
const elementClassNames = classNames(styles.element, activeClassName);
return <div className={elementClassNames} />
I'm using the classnames package to dynamically add the active class based off of the isActive prop. Instead of an isActive prop you can provide any boolean value.
A more terse way of doing this may be:
const elementClassNames = classNames(styles.element, {[styles.active]: this.props.isActive});
CSS modules won't allow you to safely override the active className (largely by design). Really it should be exposed via an API, e.g. 'activeClassName'.
If the maintainers disagree or you need this quick then you can quite easily add your own active className because your implementing component is managing the index state:
import {Tab, Tabs} from 'react-toolbox';
import styles from './MyTabs.css';
class MyTabs extends React.Component {
state = {
index: 1
};
handleTabChange(index) {
this.setState({ index });
}
render() {
const { index } = this.state;
return (
<Tabs index={index} onChange={this.handleTabChange}>
<Tab label="Tab0" className={index === 0 ? styles.active : null}>
Tab 0 content
</Tab>
<Tab label="Tab1" className={index === 1 ? styles.active : null}>
Tab 1 content
</Tab>
</Tabs>
);
}
}
Disclaimer: Code is untested.
Group style loader
You can use the group-style-lader to override the style of the components. This loader gives you an easy and intuitive way of override the style of the components.
Configure the loader
Install the loader
npm install --save-dev group-style-loader
Configure the loader in your webpack settings
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
'group-style-loader',
'style-loader',
{
loader: "css-loader",
options: {
modules: true
}
}
]
}
]
}
};
You only need to put it, before the style-loader or the mini-css-extract-plugin loader.
Override the style of the components
The next example show as you can to override the style of the Card component from the App component.
You can define the style of your component as you are used to.
card.css
.container {
width: 300px;
height: 400px;
border-radius: 8px;
}
.title {
font-weight: bold;
font-size: 24px;
}
.summary {
margin-top: 24px;
font-size: 20px;
}
The unique difference is that in the Card component, you going to use the mergeStyle function to merge the custom style with the default style of the component.
card.jsx
import React from 'react';
import { mergeStyle } from './card.css';
export function Card({ customStyle }) {
const style = mergeStyle(customStyle);
return (
<div className={style.container}>
<div className={style.title}>Title</div>
<div className={style.summary}>
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor.
</div>
</div>
)
}
Then, in the App component, to override the style of the Card component you need to define the custom style of the Card component using the separator _. All the classes using this separator going to be grouped in the card property of the style object.
app.jsx
.title {
font-size: 32px;
font-weight: bold;
margin: 44px;
}
.list {
display: flex;
}
.card_title {
color: blue;
}
.card_summary {
color: green;
}
Finally, you only need to pass the custom style of the Card component through the customStyle property of it.
app.jsx
import React from 'react';
import { Card } from './card';
import { style } from './app.css';
export function App() {
return (
<div>
<h1 className={style.title}>Group style</h1>
<div className={style.list}>
<Card/>
<Card customStyle={style.card}/>
</div>
</div>
);
}
In the previous example, you have two Cards components, the first uses its default style, and the second uses the customs tyle that we have defined.
You can see a full explanation of how to use the group-style-loader in its repository.
Using :global(.classname) you can override the external classnames.
Even 3rd party library css can be override.
:global(.active) {
color: hotpink;
}
trick in fileName.css
add className-active after declaring className
.className{
background: white;
}
.className-active{
background: black;
}
<div className={'className className-active'} />
<div className={'className-active className'} />
divs always will be black

Resources