I'm working on a React project that uses MUI and Sass. Currently there are multiple scss-files full of !important to overwrite the MUI styles with sass. I tried to fix this by removing the !important's and adding:
import { StyledEngineProvider } from '#mui/material/styles';
import CssBaseline from '#mui/material/CssBaseline'
<CssBaseline />
<StyledEngineProvider injectFirst>
*** component tree here ***
</StyledEngineProvider>
as suggested here: Issue with #Mui and modularized scss competing intermittently. How to consistently override #mui default styling with scss modules?
Which seemed to work at first but stops working when you focus on a component. For example this button turns white with a blue border when hovered over:
scss
.button {
width: 250px;
height: 50px;
border: 1px solid grey;
border-radius: 15px;
text-transform: none;
}
.go-button {
#extend .button;
background-color: grey;
color: whitesmoke;
}
reactjs
<Button
className="go-button"
variant="outlined"
onClick={handleClick}
>
Go
</Button>
We are not using modules or makeStyles. What would be the best way to overwrite MUI without the !important's?
The default styles for many MUI components will include some styles for specific states like :hover, .Mui-focused that have a higher specificity than the styles of the default state. When overriding those styles you need to use the same specificity.
For instance, Button has default styles specific to hover, so you will need to specify style overrides for the hover state.
For example, here's one possible way to define your button styles:
.button {
width: 250px;
height: 50px;
border: 1px solid grey;
border-radius: 15px;
text-transform: none;
}
.go-button {
#extend .button;
background-color: grey;
color: whitesmoke;
}
.go-button:hover {
#extend .go-button;
background-color: #999;
}
According to my knowledge experience, you must use styled-components with MUI because they have a better pair rather then SCSS, with better pair you have better performance of the website & with styled-components you can easily modify the changes of MUI.
Visit this link for advanced usage
Related
Hi everyone im in trouble with active Link, i use Styled Component.
I want my link to be Red when i'm on active link but nothing work.
I tried ActiveCLassName but this not work too.
can someone help me?
thanks a lot
const NavLink = styled(Link)`
display: flex;
justify-content: center;
align-items: center;
height: 100%;
padding: 0 10px;
list-style-type: none;
text-decoration: none;
color: black;
background-color: yellow;
border: 0.1px solid lightgrey;
`;
export default function Nav() {
return (
<NavWrapper>
<UlNav>
<LiNav>
<NavLink to="/Burgers">Burgers</NavLink>
</LiNav>
<LiNav>
<NavLink to="/Burgers">Pizza</NavLink>
</LiNav>
<LiNav>
<NavLink to="/Burgers">Drinks</NavLink>
</LiNav>
</UlNav>
</NavWrapper>
)};
Issues
The issue I see is you are styling the Link component instead of the NavLink component. The Link component doesn't take any additional props for handling active links.
Solution
The NavLink component uses a .active class by default, so of you don't need any special classname you should use this class.
Example:
import { NavLink as BaseNavLink } from "react-router-dom";
const NavLink = styled(BaseNavLink)`
display: flex;
justify-content: center;
align-items: center;
height: 100%;
padding: 0 10px;
list-style-type: none;
text-decoration: none;
color: black;
background-color: yellow;
border: 0.1px solid lightgrey;
&.active {
.... your active CSS rules here
}
`;
Tested and works in both RRDv5 and RRDv6.
RRDv5
RRDv6
"/drinks"
"/burgers"
Your code is missing some stuff, like I am not seeing anywhere you are setting color: red like you want. Basically, the active link will have the class active applied, so either using a normal stylesheet or inside your styled(Link, you have to write a rule for that class that does what you want.
Like it says here Use 'active' state from React Router in Styled Components. You may have to use the &.active selector to apply the styles.
activeClassName just changes what the class name is, which isn't what you want. By default it is active which is fine, you just have to write the CSS rule to match it. https://v5.reactrouter.com/web/api/NavLink/activeclassname-string
At the moment I'm using SCSS, as it is easy to use with NextJS. I really like how this system works, using the SCSS modules, and so I would also like to use it when using Material-UI. Material-UI uses JSS, which is a lot of boilerplate to write every time. Additionally, I prefer not to work with two ways of styling (SCSS modules and JSS). I already changed the order of CSS injection, so that I can use my SCSS modules on Material-UI components. However, I'm wondering if there is a way to overwrite styles of Material-UI components using SCSS modules? I have tried the following and a few similar things, but nothing seemed to work:
import styles from "./Login.module.scss";
import Button from "#material-ui/core/Button";
function Login() {
return (
<section>
<Button className={styles.button} variant="contained" color="primary">
Verify
</Button>
</section>
);
}
export default Login;
.button {
padding: 10px;
margin-bottom: 10px;
.MuiButton-containedPrimary {
border: 2px solid red;
background-color: red;
}
}
Below is the correct syntax:
.button {
padding: 10px;
margin-bottom: 10px;
&:global(.MuiButton-containedPrimary) {
border: 2px solid red;
background-color: red;
}
}
The example above has two key changes:
Using :global(.MuiButton-containedPrimary). Without using :global, CSS modules will transform the MuiButton-containedPrimary into a class name unique to this module and then it won't match what Material-UI puts on the button.
Adding the & in front effectively creates a selector like .button.MuiButton-containedPrimary matching an element with both classes on it. Your original syntax would treat .MuiButton-containedPrimary as a descendant selector and only match elements with that class that are a descendant of the button rather than the button itself.
You can use makeStyles of #material-ui. And pass to classes to override CSS default of material-ui.
import { makeStyles } from "#material-ui/styles";
const useStyle = makeStyles(() => ({
root: {
padding: "10px",
marginBottom: "10px",
},
containedPrimary: {
border: "2px solid red",
backgroundColor: "red"
}
}))
function Login() {
const classes = useStyle();
return (
<section>
<Button classes={classes} variant="contained" color="primary">
Verify
</Button>
</section>
);
}
tried to change the antd carousel dots styles, it can be able to implement with CSS but not with styled-components(CSS is not allowed in my project). as im new to front-end dont know the proper solution for this.
here is the code example https://stackblitz.com/edit/react-opnojd-rfagtz?file=index.js
thanks in advance :)
When using styled-component, the style would be applied with className sc-....
In your case, its style would be applied in div containing .slick-slider.
But, .ant-carousel is className for parent of that.
So, if it was included in the selector, style will be not applied.
Try this.
const CarouselWrapper = styled(Carousel)`
> .slick-dots li button {
width: 6px;
height: 6px;
border-radius: 100%;
}
> .slick-dots li.slick-active button {
width: 7px;
height: 7px;
border-radius: 100%;
background: red;
}
`;
We've a large project that exist of multiple styled components.
But for a next release and design update of that component we'll working together with a new partner that will deliver the styleguide and a CSS file that they are created for our client.
So I'm looking how I can re-use the styles of our partner in a styled component.
Do you think it's a good idea to do something like:
const PrimaryButton = styled(".btn-primary)``.
Instead of:
const PrimaryButton = styled.button``;
Actually, I can not find any working example, thus I think it's not possible... So, does someone know how I can do something like this?
Ehm, and for some reason I want to avoid to have something like this...
<PrimaryButton className="btn-primary"></PrimaryButton>
You can reuse styled components by extending the styles.
const Button = styled.button`
color: palevioletred;
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
`;
// A new component based on Button, but with some override styles
const PrimaryButton = styled(Button)`
color: blue;
border-color: blue;
`;
I've been trying to use styled-components with the alpha version of material-ui
According to the documentation, this should work out of the box.
This code:
const StyledButton = styled(Button)`
color: red;
text-transform: uppercase;
`;
return <StyledButton>Button</StyledButton>;
will generate something like this:
<button tabindex="0" class="MuiButtonBase-root-3177716317 sc-bdVaJa sxRGN" type="button" role="button">
...
</button>
It looks good.
However, the only problem I have is the order of the injected CSS styles (pic). Styles from styled-components are injected before MUI's styles which make their priority lower.
Is there any way to solve this without using !important?
In the current release (i.e. non-alpha) version, what you've asked would indeed require !important basis:
"Note that CSS properties defined inline are given priority over those defined in a CSS class. You need to use !important to take precedence over the inline style."
Ref: http://www.material-ui.com/#/customization/styles
Perhaps the alpha hasn't quite moved away from this inline requirement yet or it is still a work-in-progress.
What I've done to overcome this sort of thing myself is to (unfortunately) recreate the entire CSS on a standard <button> element when I need such a solution. Here's an example of how I'm doing that with a react-photonkit "theme"
// #flow
import styled from 'styled-components';
const PhotonStyledButton = styled.button`
font-family: Arial, Roboto, Helvetica, sans-serif;
height: 30px;
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 12px !important;
line-height: 1.4;
text-align: center;
white-space: nowrap;
vertical-align: middle;
cursor: default;
background-image: none;
border: 1px solid transparent;
border-radius: $default-border-radius;
box-shadow: 0 1px 1px rgba(0,0,0,.06);
-webkit-app-region: no-drag;
&:focus {
outline: none;
box-shadow: none;
}
color: #333;
border-top-color: #c2c0c2;
border-right-color: #c2c0c2;
border-bottom-color: #a19fa1;
border-left-color: #c2c0c2;
background-color: #fcfcfc;
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#fcfcfc), color-stop(100%,#f1f1f1));
background-image: -webkit-linear-gradient(top, #fcfcfc 0%, #f1f1f1 100%);
background-image: linear-gradient(to bottom, #fcfcfc 0%, #f1f1f1 100%);
&:active {
background-color: #ddd;
background-image: none;
}
`;
export default PhotonStyledButton;
styled-components in general is compatible with any component library. When you write styled(AnotherComponent) we take that component and inject an automatically generated class name. This means essentially it's the same thing as writing <AnotherComponent className="sc-asdf123" />!
The current version of material-ui specifically is a bit difficult to custom style because it uses inline styles. From the MaterialUI documentation:
Note that CSS properties defined inline are given priority over those defined in a CSS class. You need to use !important to take precedence over the inline style.
This means simply using styled(MaterialButton) won't work as the passed-in styles will mostly just be ignored. You need to bump the specificity of your styles to override the inline styles that material-ui ships with. (this article is a great primer on specificity if you're not familiar with the details)
Answer for the alpha version of material-ui
The current alpha version of material-ui has switched to using JSS under the hood. (which is CSS in JS not inline styles, like styled-components) This means the issue is likely to be that the styled-components styles are injected after the default material-ui styles. (which are injected by JSS)
JSS supports custom injection points so you might be able to add a <!-- jss --> comment to the HEAD of your HTML to make sure JSS injects its CSS before the styled-components injected CSS?
Answer for the current version of material-ui
There are two ways to bump the specificity of the styled-components injected styles, one more tedious and one a bit more "hacky". The first one is adding !important at the end of all of your styles:
const Button = styled(MaterialButton)`
color: blue!important;
`
While this works in most cases it gets tedious very fast when you have lots of custom styling in a component. The better way is to use the class name hack:
const Button = styled(MaterialButton)`
&&& {
color: blue;
}
`
These ampersands get replaced with the automatically generated class name meaning the outputted CSS looks something like this:
.sc-asdf123.sc-asdf123.sc-asdf123 {
color: blue;
}
This bumps specificity by a big margin, thusly overriding the defined inline styles, and is less annoying than having to put !important after each rule.
Now we can use <!-- material-ui --> to make sure the styles are injected after it.
By default, Material-UI will look for a html comment named to inject styles after. By adjusting the placement of this comment within your HTML body you can control the order that CSS rules are applied to your components. (ref)