Material-ui: [docs] Overriding with classes is a bit unclear

Created on 8 Nov 2017  路  13Comments  路  Source: mui-org/material-ui

  • [x] I have searched the issues of this repository and believe that this is not a duplicate.

This is just a discussion over documentation of v1.

In this section : https://material-ui-next.com/customization/overrides/#overriding-with-classes it seems in both the text description, and the example, that the classes override replace the default one.This is not very intuitive as classes are string, not objects that can merge, which is why I thought it worked that way in the first place.

An explicitly description of how it works could make things clearer, . ie. the styles objects pointed by both the overriding class name and the default one, are merged together.

What do you think?

docs good first issue v1.x

Most helpful comment

Thanks for the hint.

So to the answer to my question is it was (and will?) never be intended to replace internal classes. We have to stick to overriding solutions.

@pandaiolo can you add this information to the docs as well if you give it a try? :)

All 13 comments

I agree, it would be good to update the documentation to clarify the behavior.

@pandaiolo Do you want to update the documentation?

I'll give it a try, probably this week end or next one

I came across this issue as well because I assumed this is possible or even the _right way to do it_.

@oliviertassinari Looking at your answers to similar issues I can see you recommend using styling with a higher specificity instead, i.e. .foo .bar, inline styles or even !important.

Is this the intended way to customize internal material-ui styles?
I'd rather replace the internal style completely (by copying a modified class) and accept that I have to take care of changes than use one of the above mentioned options.

The reason for this are CSS modules I am using:

  • .foo .bar will not work because I use composes: Baz in the overridden style
  • inline styles will not work because CSS modules export classNames instead of style objects
  • !important ... not going to happen

So can there be an option to modify this behaviour of @withStyles?
https://github.com/callemall/material-ui/blob/2da9988abf239cdabd730c1d0d3ab73deca3231a/src/styles/withStyles.js#L312-L314

@ottosichert One way to increase the specificity is to change the injection order of the CSS. We have one mechanism to do so. Let us know if this fix your issue.

Thanks for the hint.

So to the answer to my question is it was (and will?) never be intended to replace internal classes. We have to stick to overriding solutions.

@pandaiolo can you add this information to the docs as well if you give it a try? :)

I'd rather replace the internal style completely

@ottosichert I have missed this sentence, it's something we have been discussing under #6218. It's a different topic.

Adding a comment here for posterity.

If you're using JSS and you want to override Material-UI styles you can, as @oliviertassinari mentioned, change the injection order to achieve this. _However_ the latest Material UI build is _not_ using the latest react-jss build. It's using a fork of it. So if you're using react-jss in your project the following isn't going to help:

import injectSheet from 'react-jss';
...
export default injectSheet(styles, { index: 99999 })(MyComponent)

instead you're going to need to use the material-ui HOC like so:

import { withStyles } from 'material-ui/styles'
...
export default withStyles(styles)(MyComponent)

If you use withStyles you don't need to specify the index option to increase specifity, your stylesheet should just get inserted after all of the material ui sheets and you should be good to go.

I would put up a PR to add this to the docs but from what I understand this situation is temporary. Material UI is planning on modifying and then incorporating the latest react-jss build into the project and once that happens people should just be able to look at the react-jss docs on stylesheet injection order to solve this issue.

@pandaiolo Does the current wording make things any clearer?

You were faster than me... thank you :)

The component's existing classes will continue to be injected, so it is only necessary to provide the specific styles you wish to add or override.

That sentence is very clear to me and makes the underlying logic more understandable

馃憤

Thanks.

@mbrookes Great :) !

Just in case some one else find this issue later.

I've created a component to simplify the material ui's css over writing process.

override-material-ui-css

You just need to wrap your whole application in this OverrideMaterialUICss component. This library is a wrapper component which only takes the children prop and renders it without any modification but just moving Material-UI's