Material-ui: [Button] className is not the last class applied to a button

Created on 5 Mar 2020  路  5Comments  路  Source: mui-org/material-ui

  • [x] The issue is present in the latest release.
  • [x] I have searched the issues of this repository and believe that this is not a duplicate.

Current Behavior 馃槸

The value of the className property is not the last class name applied to a button.

This seems to be a transpile issue problem because the source code clearly puts the className value last. See: https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/Button/Button.js#L307

Expected Behavior 馃

When passing a className property:

<Button variant="contained" color="primary" className="test-class">Test</Button>

The class test-class should be after all the button classes. However it appears before some of the button classes:

<button class="MuiButtonBase-root MuiButton-root MuiButton-contained test-class MuiButton-containedPrimary" tabindex="0" type="button"><span class="MuiButton-label">Test</span><span class="MuiTouchRipple-root"></span></button>

Steps to Reproduce 馃暪

https://codesandbox.io/s/button-classname-issue-bs6m2

Steps:

  1. Create a Button with contained / color variants
  2. Pass a className attribute
  3. Check the generated HTML

Note that in Material v3 it works as expected. I was able to reproduce the problem in v4.0.0 and v4.9.5 (I didn't check with intermediate versions).

Context 馃敠

This seems to be a bug in transpile. The original code from Button (https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/Button/Button.js#L307https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/Button/Button.js#L307) is transpiled to this:

return React.createElement(ButtonBase, _extends({
    className: clsx(classes.root, classes[variant], className, color === 'inherit' ? classes.colorInherit : color !== 'default' && classes[`${variant}${capitalize(color)}`], size !== 'medium' && [classes[`${variant}Size${capitalize(size)}`], classes[`size${capitalize(size)}`]], disableElevation && classes.disableElevation, disabled && classes.disabled, fullWidth && classes.fullWidth),
    component: component,
    disabled: disabled,
    focusRipple: !disableFocusRipple,
    focusVisibleClassName: clsx(classes.focusVisible, focusVisibleClassName),
    ref: ref,
    type: type
  }, other), React.createElement("span", {
    className: classes.label
  }, startIcon, children, endIcon));

Note the className attribute that appears before color === 'inherit'.
Is this a Babel bug?

Your Environment 馃寧

| Tech | Version |
| ----------- | ------- |
| Material-UI | v4.9.5 |
| React | 16.12.0 |
| Browser | Chrome |

incomplete

Most helpful comment

Ok, my bad the order doesn't matter. I got an instant of craziness due to hours of bug fixing. Probably the issue is caused by a declaration order change between versions. Going to close this, and dig more on why the computed CSS is different in my case. Sorry for the back and forward.

All 5 comments

Isn't the order irrelevant? If two selectors have the same specificity then the first one that appears in the declaration wins. I don't think order in classNames matters ever. Do you have an example that showcases the issue you have?

@eps1lon I don't think that the issue is incomplete. There is an example in the original report: https://codesandbox.io/s/button-classname-issue-bs6m2

I also included the code generated from the babel transform which clearly doesn't respect the order of the original code (it may be an issue with babel-plugin-optimize-clsx).

Even if you have the same specificity the order in the class attribute matters:
https://codepen.io/dfernandez-asapp/pen/mdJBQOX

I just confirmed that this is a bug in babel-plugin-optimize-clsx. Related issue: https://github.com/merceyz/babel-plugin-optimize-clsx/issues/18

@eps1lon About real world use cases:

  • I found this problem while migrating from v3 to v4. I found a slight difference in one of our pages that was caused by the order. I can work around it with some specificity tricks (the usual double class declaration), but the work around shouldn't be necessary.
  • This is also a problem for StyledComponents / Emotion users, because if you do styled(Button) the overrides will come before some MUI classes and you need to resort to specificity tricks too.

I found a slight difference in one of our pages that was caused by the order

The order of the classes in the class attribute has no effect on styling. Only specificity and order of the declarations has an effect. Could you share an example where the order affects styles?

Ok, my bad the order doesn't matter. I got an instant of craziness due to hours of bug fixing. Probably the issue is caused by a declaration order change between versions. Going to close this, and dig more on why the computed CSS is different in my case. Sorry for the back and forward.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

finaiized picture finaiized  路  3Comments

pola88 picture pola88  路  3Comments

rbozan picture rbozan  路  3Comments

FranBran picture FranBran  路  3Comments

revskill10 picture revskill10  路  3Comments