CSS styles duplication when using computed class names
See original GitHub issue- The issue is present in the latest release.
- I have searched the issues of this repository and believe that this is not a duplicate.
Current Behavior 😯
When creating CSS classes dependents on passed props
values, the styles are duplicated when the component refreshes.
Expected Behavior 🤔
The styles should properly be updated, removing any duplicates and unused by previous calls to makeStyles
.
Steps to Reproduce 🕹
Declaring styles like this will create duplicates every time the component using the styles refresh :
const useStyles = makeStyles((theme) => ({
testElement: ({ index, bgColor }) => ({
[`& div:nth-child(${index})`]: {
backgroundColor: bgColor
},
[`& div:not(:nth-child(${index}))`]: {
backgroundColor: theme.palette.common.white
}
})
}));
Context 🔦
I noticed this behavior when debugging some styles I use in a project to render striped tables. The class renders custom striped tables given certain parameters.
Actual rules being applied
/**
* Make table rows alternate in color. By default, every even row will have an alternate color.
*
* Usage :
*
* const useStyles = makeStyles(theme => ({
*
* table: {
* ...themedTableRows(theme(theme)
* }
*
* }));
*
*
* Ex: themedTableRows(theme, 1, 0) // defaults
* - row
* - alternate row
* - row
* - alternate row
*
* Ex: themedTableRows(theme, 2)
* - row
* - row
* - alternate row
* - alternate row
* - row
* - row
* - alternate row
* - alternate row
*
* Ex: themedTableRows(theme, 3, 1)
* - row (skipped)
* - row (skipped)
* - row (skipped)
* - row
* - row
* - row
* - alternate row
* - alternate row
* - alternate row
* - row
* - row
* - row
* - alternate row
* - alternate row
* - alternate row
*
* @param {Object} theme Material UI palette
* @param {Number} groupSize the number of rows to alternate
* @param {Number} offset skip the number of first groups
* @return {Object} classes to extend a rule with
*/
export const themedTableRows = (theme, groupSize = 1, offset = 0) => ({
[groupSize < 2 ? '&:nth-of-type(even)' : Array.from({ length: groupSize }, (_, k) => `&:nth-child(${groupSize * 2}n+${k + groupSize + 1 + (offset * groupSize)})`).join(',')]: {
backgroundColor: theme.palette.type === 'dark' ? darken(theme.palette.action.hover, 0.5) : lighten(theme.palette.action.hover, 0.4),
},
'&.Mui-selected': {
backgroundColor: theme.palette.type === 'dark' ? darken(theme.palette.secondary.dark, 0.7) : lighten(theme.palette.secondary.light, 0.6),
},
[groupSize < 2 ? '&.Mui-selected:nth-of-type(even)' : Array.from({ length: groupSize }, (_, k) => `&.Mui-selected:nth-child(${groupSize * 2}n+${k + groupSize + 1 + (offset * groupSize)})`).join(',')]: {
backgroundColor: theme.palette.type === 'dark' ? darken(theme.palette.secondary.dark, 0.65) : lighten(theme.palette.secondary.light, 0.4),
}
});
I was adding :hover
styles when I noticed the multiplication of overrides in the developer console.
Your Environment 🌎
`npx @material-ui/envinfo`
System:
OS: Linux 5.4 Ubuntu 20.04.1 LTS (Focal Fossa)
Binaries:
Node: 14.5.0 - ~/.nvm/versions/node/v14.5.0/bin/node
Yarn: 1.22.10 - ~/.nvm/versions/node/v14.5.0/bin/yarn
npm: 6.14.5 - ~/.nvm/versions/node/v14.5.0/bin/npm
Browsers:
Chrome: 88.0.4324.96
Firefox: 85.0
npmPackages:
@material-ui/core: ^4.11.3 => 4.11.3
@material-ui/lab: ^4.0.0-alpha.57 => 4.0.0-alpha.57
@material-ui/pickers: ^4.0.0-alpha.12 => 4.0.0-alpha.12
@material-ui/styles: 4.11.3
@material-ui/system: 4.11.3
@material-ui/types: 5.1.0
@material-ui/utils: 4.11.2
@types/react: 16.9.50
react: ^16.13.1 => 16.13.1
react-dom: ^16.13.1 => 16.13.1
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:6 (4 by maintainers)
Top Results From Across the Web
CSS styles duplication when using computed class names
When creating CSS classes dependents on passed props values, the styles are duplicated when the component refreshes. Expected Behavior. The ...
Read more >Can a dynamic class be styled using CSS? - Stack Overflow
Yes it is possible just by using CSS only. Option #1 - Match by prefix value. Use CSS Class selector ^="class" which select...
Read more >Reusing Styles - Tailwind CSS
Managing duplication and creating reusable abstractions. Tailwind encourages a utility-first workflow, where designs are implemented using only low-level ...
Read more >Using dynamic styling information - Web APIs | MDN
In many cases, and where possible, it is best practice to dynamically manipulate classes via the className property since the ultimate ...
Read more >How to customize - Material UI - MUI
These class names can't be used as CSS selectors because they are unstable. Overriding styles with class names. If you want to override...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@yanickrochon Not yet, we start moving iteratively. We are moving toward the
styled()
andsx
API. https://next.material-ui.com/components/slider/#unstyled-slider gives more context (looking at the demos)An update, we have now made enough progress with the new
@material-ui/styled-engine
package in v5 to move toward a progressive removal of the@material-ui/styles
package (based on JSS). The current plan:sx
prop +styled()
API). We might for instance, invest in the documentation for using react-jss that has more or less the same API. We could also invest in an adapter to restore the previous API but with emotion, not JSS.withStyles
/makeStyles
API).This was made possible by the awesome work of @mnajdova.