-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CSS rules specificity is order dependent on chips #16374
Comments
@jbblanchet I fail to see the problem. Could you expand on what's wrong? |
@jbblanchet Oh, this is a bug. Thanks for providing more details! I believe that the import is wrong. What do you think of this diff?: diff --git a/packages/material-ui/src/Chip/Chip.js b/packages/material-ui/src/Chip/Chip.js
index 08ae064eb..8214233b9 100644
--- a/packages/material-ui/src/Chip/Chip.js
+++ b/packages/material-ui/src/Chip/Chip.js
@@ -8,7 +8,7 @@ import { emphasize, fade } from '../styles/colorManipulator';
import { useForkRef } from '../utils/reactHelpers';
import unsupportedProp from '../utils/unsupportedProp';
import { capitalize } from '../utils/helpers';
-import '../Avatar/Avatar'; // So we don't have any override priority issue.
+import '../Avatar'; // So we don't have any override priority issue.
export const styles = theme => {
const height = 32; Do you want to submit a pull request? :) |
@oliviertassinari Sorry for the delay. Re-reading my description right now, I'm missing half of the info, I probably shouldn't have opened this during a rush between 2 meetings. 😄 @marcelosuzumura Thanks for completing my bug report, this is exactly the behavior I was seeing. 👍 I sadly have no idea if this is the right fix or not, I've never used emotion in any project so it's unclear to me what happens in the background to create the css, but from the comments I'd say it's probably it. |
Isn't this a general issue that should be resolved in some other way? The current approach hurts tree shaking because it pre-emptively imports components whose classNames might appear on the same |
@eps1lon What other way do you have in mind? For instance, take styled-components, you would have to import the component and to reference it in the selector. In this very occurrence of the problem, I believe that the cjs and esm versions of the Avatar components are loaded. It can't work correctly. |
I would've included this and not just asked if it was possible. It's in general an issue for tree-shaking not just because it bloats the bundle for possible specificity conflicts but also because it violates A naive approach would guarantee that the stylesheet order is stable but I'm not sure how big of a perf hit that would be. |
@eps1lon @oliviertassinari this is the exact issue I mentioned in #15355 (comment) btw |
There is another possible solution explored in #16609 (comment). |
We can see the issue right now on https://material-ui.com/components/chips/ |
@davidbonnet Do you want to handle the proposed fix #16374 (comment)? |
@oliviertassinari Hey! I was going through the issue and I liked the idea of increasing the specificity in #16609 . So, from all the reading I understood that you are suggesting increasing specificity of the .MuiChip-avatar class so it cannot be overridden by another class. And my query is, does it affect any other piece of code or create some bugs I am not aware of? This might be a silly doubt but I am new to this so could you please help me out? |
@Dhruvi16 We need to be cautious when we increase the specificity as it makes overrides harder, especially for people that don't know much about how CSS specificity works. Aside from it, no, I'm not aware of any other issue. |
@Dhruvi16 In our case, I think that we should apply #16374 (comment), It would already be a great step. Do you want to take care of it? :) |
Yes, I will do it. But it hurts tree shaking as mentioned earlier. So, do you think this is the best idea we can go with? |
I have no idea what's the best option. They all their pros and cons. IMHO it won't make a big difference, if we can optimize for the least amount of work to close this issue, it's fine by me.
|
I think the best thing to do will be avoid conflicting style properties. But I am not sure if that is possible. So the next best thing we can do is apply the solution in #16374 (comment) and move forward with this. I can send a PR if you agree on this. |
@Dhruvi16 Sounds good to me. If we can solve 60% of the problem with this simple change, it's good to take, it would already significantly reduce the priority of this issue compared to the other one we have :). |
Based on mui#16374 (comment)
Found this via #16609 I'm currently on
|
Wanted to create a reproduction for you. Sorry for the rushed reply yesterday - was leaving the office. I've created a repo https://github.com/idisclosure-legalx/mui-chip that demonstrates the issue with Next. Please let me know if there's anything else I can help with. |
@hibearpanda Thanks for the reproduction with Next.js. We can observe it too on the documentation that uses Next.js. Does it reproduce outside? Could it be a Next.js specific issue? |
This issue is not specific to next. I'm experiencing it with Create React App when running |
OK thanks, there is a new hypothesis I need to verify. Let's say we mark the Avatar module side effect free, the Avatar has a side effect on the CSS injection order, and webpack? decides to remove the import. 🔥 |
Maybe related to #16609 I've seen the avatar issue and a similar issue with the margin-left property with |
@pcwa-ahendricks if the side effect free theory is verified, then yes, it should be the same. |
Okay. I can confirm that |
@hibearpanda's reproduction confirms the theory of #16374 (comment). We need a way to mark the Avatar import, not side effect free. The following seems to do the job: diff --git a/packages/material-ui/src/Chip/Chip.js b/packages/material-ui/src/Chip/Chip.js
index 5a7d605d7..2eb5635ec 100644
--- a/packages/material-ui/src/Chip/Chip.js
+++ b/packages/material-ui/src/Chip/Chip.js
@@ -7,7 +7,11 @@ import { emphasize, fade } from '../styles/colorManipulator';
import useForkRef from '../utils/useForkRef';
import unsupportedProp from '../utils/unsupportedProp';
import capitalize from '../utils/capitalize';
-import '../Avatar'; // So we don't have any override priority issue.
+import Avatar from '../Avatar';
+
+// Force a side effect so we don't have any override priority issue.
+// eslint-disable-next-line no-unused-expressions
+Avatar.styles;
export const styles = theme => {
const backgroundColor = Does somebody want to try it out? @pcwa-ahendricks For #16609, the concern is different, the solution proposed here wouldn't scale to the case where somebody implements a custom button with styled-components (SC). Because the user uses SC, he has configured the CSS injection order to have Material-UI first and SC second, this means that for two CSS selectors of specificity 1, SC gets precedence (win). Now, if you consider that Safari adds a margin to the native button element, the SC button likely has a button margin reset to 0. The Modal CSS selector is: |
Avatar.styles; Playing around with |
@NMinhNguyen Thank you for looking at it. I'm not familiar with webpack tree shaking pipeline. Do you know if the uglify/terser step happens before or after the webpack tree shaking step? cc @eps1lon |
@oliviertassinari not too sure, sorry! |
I believe the issue occurs for other components as well, not only for the On dev, the |
@jperasmus Thanks for the report. Yes, it's possible. We might want to increase the specificity here too. |
This comment has been minimized.
This comment has been minimized.
Not sure why this is marked off topic. The same import order issue is happening for Button and Typography components as well. The import orders are not consistent between dev and prod when importing using destructuring import { Typography, Button } from '@material-ui/core' Tested on the Next-js typescript example in the mui repo. |
Damn, I have the same @karpkarp. Have you found any solution? |
@gpessa we ended up switching off the example from the mui repo for Next.js, specifically the For now this is what we have in prod
|
I'm also experiencing same issue, the order of added styles tag are different between dev and prod builds. I'm using CRA. Not sure the issue comes from jss, mui, or a conflict with webpack configs? |
same here,
prod , dev Different |
I solved the issue by by creating my own generateClassName function, by doing this you can create unique classNames for production and make sure the classNames will be unique. I also increase the specify of my customisations for mui classes (e.g. Mui-Paper) to <ThemeProvider theme={theme}>
<StylesProvider generateClassName={generateClassName}>
<BotEditor />
</StylesProvider>
</ThemeProvider> the mui default function can be found here Here you can find my code for createGenerateClassName: https://gist.github.com/code-guru/cd6e74f287bcda0d456d8087e7b5ca74 |
tracing down this same issue, just happening for a customization of
This worked for me, but can confirm that it increased bundle size, for me it was 100kb increase as reported by next.js cli, so kind of a non starter. I then was experimenting with the suggestion in the FAQ on the material ui site, by making sure to wrap with a Should for example, in next.js
if I do a production prefix, it breaks completely. if I leave the options empty, it renders, but I still have the same issue. in trying @Code-guru 's suggestion above, the app is back to a broken state. I set up my app initially following the next js material ui example app: https://github.com/mui-org/material-ui/tree/master/examples/nextjs i'll get a minimal working repo up soon. The only overriding i'm doing to button is through the classes api. |
update, I was able to fix this. in my wrappers for mui, I was importing in a few places in the style of destructuring from
I then had a component that was in my wrapper, that was outside of the wrapper directory. I changed the button wrapper to do direct imports instead:
and things started working again. lesson learned, for wrappers in my case, import directly from material component. |
In v4, looking at the chips demo, the css rules specificity is dependent on the order of the css, which is problematic when using any build tools that might change the order
Expected Behavior 🤔
The should be no specificity conflict between classes.
Current Behavior 😯
Looking at the chips demo on your website, the generated code has both a
.MuiChip-avatarColorPrimary
and.MuiAvatar-colorDefault
class defining thecolor
andbackground-color
css attributes. Same thing happens with.MuiChip-avatar
and.MuiAvatar-root
both definingwidth
,height
andfont-size
.Steps to Reproduce 🕹
in https://material-ui.com/components/chips/, inpect element on the first blue chip shows:
The text was updated successfully, but these errors were encountered: