-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
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
[ScopedCssBaseline] The box-sizing style of the child components is overwritten #20461
Comments
@newrice Oh wow, thanks for raising. It's working with
What do you think? |
I propose we go with 1. What do you think? diff --git a/docs/src/pages/components/css-baseline/css-baseline.md b/docs/src/pages/components/css-baseline/css-baseline.md
index 286b8be42..316264d5c 100644
--- a/docs/src/pages/components/css-baseline/css-baseline.md
+++ b/docs/src/pages/components/css-baseline/css-baseline.md
@@ -32,16 +32,20 @@ It's possible to apply the baseline only to the children by using the `ScopedCss
```jsx
import React from 'react';
import ScopedCssBaseline from '@material-ui/core/ScopedCssBaseline';
+import MyApp from './MyApp';
export default function MyApp() {
return (
<ScopedCssBaseline>
{/* The rest of your application */}
+ <MyApp />
</ScopedCssBaseline>
);
}
```
+> ⚠️ Make sure you import `ScopedCssBaseline` first to avoid box-sizing conflicts as in the above example.
+
## Approach
### Page |
@oliviertassinari Thank you very much, your comment helped me. I think that document will help beginners like me🙏 |
@newrice We are happy to hear that you solved your issue. Do you want to submit a pull request? :) |
@oliviertassinari Oh! If it’s ok, I want to do it✨ |
Go for it. The issue with 2. is that it could create surprises for people when switching between the two, it could be a breaking change for existing users (but small impact as a recent feature). |
@oliviertassinari Hi. Is there any way to use ScopedCssBaseline yet still keep the |
@binh1298 If you are using v4, this issue describes the solution. If you are using v5 with sc, the solution still apply. If you are using v5 with emotion then I have no idea. I'm reopening. |
As far as I can see the |
@mnajdova Both CssBaseline and ScopedCssBaseline are using the styled API since very recently. |
Ah my bad, was looking into older version. |
I have reopened without a reproduction, my bad. I tried in https://codesandbox.io/s/the-box-sizing-style-of-the-child-components-is-overwritten-forked-kze77?file=/src/Demo.js:125-194 but I couldn't see the error. We get this in the .MuiScopedCssBaseline-root * {
box-sizing: inherit;
}
.css-weuz2y-MuiInputBase-input-MuiOutlinedInput-input {
box-sizing: content-box;
} which is correct. Now, it gets interesting, if I render the same demo in the documentation: This time, the CSS swap: .css-weuz2y-MuiInputBase-input-MuiOutlinedInput-input {
box-sizing: content-box;
}
.MuiScopedCssBaseline-root * {
box-sizing: inherit;
} As far as I know, there are no solutions with emotion. The trick we have for JSS only works with styled-components. cc @Andarist in case it could interest him. I would propose we document the limitation and close. |
What do you do for SC? |
@Andarist From what I understand JSS and SC rely on the JavaScript execution order while emotion relies on prop spreading. The solution I propose is to update:
https://next.material-ui.com/components/css-baseline/#scoping-on-children |
Not sure if I understand this correctly. With |
Questions
Ok, this is what I recall @mnajdova saying.
@Andarist From what I understand, at the styled() creation time, an injection order is reserved:
Global CSS vs. styledI have also noticed that they enforce the global style to always be injected first in SC: I recall looking into emotion-js/emotion#2213, it seems that emotion does the same as SC. Global CSS are injected first: https://codesandbox.io/s/emotion-issue-template-forked-31990?file=/src/index.js:0-639. Alternative solutionI had also considered solving this issue by using Is this issue important?Not really. We can defer it post v5. |
I have tried the diff --git a/packages/material-ui/src/ScopedCssBaseline/ScopedCssBaseline.d.ts b/packages/material-ui/src/ScopedCssBaseline/ScopedCssBaseline.d.ts
index d21c164ab0..4252db2fe0 100644
--- a/packages/material-ui/src/ScopedCssBaseline/ScopedCssBaseline.d.ts
+++ b/packages/material-ui/src/ScopedCssBaseline/ScopedCssBaseline.d.ts
@@ -14,6 +14,11 @@ export interface ScopedCssBaselineTypeMap<P = {}, D extends React.ElementType =
/** Styles applied to the root element. */
root?: string;
};
+ /**
+ * The class name used to scope the CSS baseline styles.
+ * @default 'MuiScope'
+ */
+ scopeId?: string;
};
defaultComponent: D;
}
diff --git a/packages/material-ui/src/ScopedCssBaseline/ScopedCssBaseline.js b/packages/material-ui/src/ScopedCssBaseline/ScopedCssBaseline.js
index 2b2c30be5a..5839a65197 100644
--- a/packages/material-ui/src/ScopedCssBaseline/ScopedCssBaseline.js
+++ b/packages/material-ui/src/ScopedCssBaseline/ScopedCssBaseline.js
@@ -3,14 +3,10 @@ import PropTypes from 'prop-types';
import clsx from 'clsx';
import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled';
import useThemeProps from '../styles/useThemeProps';
-import experimentalStyled from '../styles/experimentalStyled';
+import GlobalStyles from '../GlobalStyles';
import { html, body } from '../CssBaseline/CssBaseline';
import { getScopedCssBaselineUtilityClass } from './scopedCssBaselineClasses';
-const overridesResolver = (props, styles) => {
- return styles.root || {};
-};
-
const useUtilityClasses = (styleProps) => {
const { classes } = styleProps;
@@ -21,45 +17,41 @@ const useUtilityClasses = (styleProps) => {
return composeClasses(slots, getScopedCssBaselineUtilityClass, classes);
};
-const ScopedCssBaselineRoot = experimentalStyled(
- 'div',
- {},
- {
- name: 'MuiScopedCssBaseline',
- slot: 'Root',
- overridesResolver,
- },
-)(({ theme }) => ({
- /* Styles applied to the root element. */
- ...html,
- ...body(theme),
- '& *, & *::before, & *::after': {
- boxSizing: 'inherit',
- },
- '& strong, & b': {
- fontWeight: theme.typography.fontWeightBold,
- },
-}));
+export const styles = (scopeId) => (theme) => {
+ let defaultStyles = {
+ [`&.${scopeId}`]: {
+ ...html,
+ ...body(theme),
+ '& *, & *::before, & *::after': {
+ boxSizing: 'inherit',
+ },
+ '& strong, & b': {
+ fontWeight: theme.typography.fontWeightBold,
+ },
+ },
+ };
+
+ const themeOverrides = theme.components?.MuiScopedCssBaseline?.styleOverrides?.root;
+ if (themeOverrides) {
+ defaultStyles = [defaultStyles, themeOverrides];
+ }
+
+ return defaultStyles;
+};
const ScopedCssBaseline = React.forwardRef(function ScopedCssBaseline(inProps, ref) {
const props = useThemeProps({ props: inProps, name: 'MuiScopedCssBaseline' });
- const { className, component = 'div', ...other } = props;
+ const { scopeId = 'MuiScope', className, component: Component = 'div', ...other } = props;
- const styleProps = {
- ...props,
- component,
- };
+ const styleProps = props;
const classes = useUtilityClasses(styleProps);
return (
- <ScopedCssBaselineRoot
- as={component}
- className={clsx(classes.root, className)}
- ref={ref}
- styleProps={styleProps}
- {...other}
- />
+ <React.Fragment>
+ <GlobalStyles styles={styles(scopeId)} />
+ <Component ref={ref} className={clsx(classes.root, className, scopeId)} {...other} />
+ </React.Fragment>
);
});
@@ -85,6 +77,11 @@ ScopedCssBaseline.propTypes /* remove-proptypes */ = {
* Either a string to use a HTML element or a component.
*/
component: PropTypes.elementType,
+ /**
+ * The class name used to scope the CSS baseline styles.
+ * @default 'MuiScope'
+ */
+ scopeId: PropTypes.string,
};
export default ScopedCssBaseline; But it's not working either. The specificity of the CSS selectors are the same, but emotion doesn't guarantee that |
Still not any solutions? |
I got a little bit lost when it comes to the exact role of Emotion in all of this - if you want any help with Emotion, I would appreciate if somebody could explain the issue once more and provide a repro case for it. I could then happily jump into analyzing it. |
Today I tried to migrate from |
Looks like it was something related to |
I recently ran into this issue using the latest MUI (using Emotion). When trying to find a reduced test case, I found two different cases that trigger the issue, and case 1 ended up being what was happening in my app:
Both of these cases end up looking like this: In both cases, it's due to the ScopedCssBaseline styles getting inserted after the TextField (or, more specifically, the InputBase) styles. See explanation below for more info. Case 1 is easy to avoid (just don't use Ideally, I think it'd be nice to remove those Explanation on what's causing the issue in these casesThis is somewhat redundant with info earlier in the thread, but I thought it'd be helpful to show how these cases were interacting with Emotion, and triggering this issue in slightly different ways. Case 1Normally when you render a mui InputBase (via TextField) inside of a ScopedCssBaseline, Emotion generates CSS classes for those styles and inserts them in render order:
And if you render the ScopedCssBaseline again, Emotion reuses the However, if you set
And since Case 2If you were to render a TextField before ever rendering a ScopedCssBaseline, let's say elsewhere in the app, those styles get inserted first:
Then, later, if you render a ScopedCssBaseline with a TextField inside it, it reuses the class generated for InputBase, and then adds the ScopedCssBaseline styles afterwards, and you end up with.
And since |
Current Behavior 😯
box-sizing: 'inherit'
for all child components. -> souce.MuiInputBase-input
).Expected Behavior 🤔
.MuiInputBase-input
should be used as precedence overbox-sizing: 'inherit'
like CssBaseline.Steps to Reproduce 🕹
https://codesandbox.io/s/the-box-sizing-style-of-the-child-components-is-overwritten-htv0c
Steps:
Context 🔦
Your Environment 🌎
The text was updated successfully, but these errors were encountered: