score:3
From https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity:
When multiple declarations have equal specificity, the last declaration found in the CSS is applied to the element.
So in your case where you are defining CSS classes in your custom component (e.g. TestButton
) and in the code that uses that component, the specificity is determined by the order in which those CSS classes appear within the <head>
element. This order is determined by an index that is set when makeStyles is called, so classes defined by later calls to makeStyles
will appear later in the <head>
element and thus have greater specificity.
There are two issues then in your example:
TestButton
is defined after the code that uses it and therefore after themakeStyles
call that is defining styles intended to override styles inTestButton
. Since themakeStyles
call forgButton
occurs first, the corresponding CSS class will be first in the<head>
element. In real-world usage though,TestButton
(your custom component) would be defined in a separate file and be imported. Since imports have to be at the top, anymakeStyles
calls at the top level of the imported file will be executed before anymakeStyles
calls in the file using the imported component.The
makeStyles
call forTestButton
is not being done at the top level. Instead it is being done inside theTestButton
function which means it will be executed whenTestButton
is rendered instead of whenTestButton
is imported. Calls tomakeStyles
should always be at the top level rather than nested within a component function. One other minor issue is the name of the variable returned frommakeStyles
(i.e.GrangeButtonStyles
in your example). SincemakeStyles
returns a custom hook, you should always have a name that starts with "use" (e.g.useGrangeButtonStyles
). This will ensure that the eslint rules for hooks recognize it as a hook and warn you of any hook misuse.
Related answers and references:
score:-1
<TestButton className={classes.gButton} color={"default"}>
// should be
<TestButton classes={{button:classes.gButton}} color={"default"}>
// and
<TestSelect className={classes.gSelect}
// should be
<TestSelect className={{dropdown:classes.gSelect}}
^ when dealing with material-ui's styling solution, don't pass "className" to components (only put this prop on DOM elements!!!!)
and
function TestButton(props) {
const classes = GrangeButtonStyles();
...
// should be
function TestButton(props) {
const classes = GrangeButtonStyles(props);
...
^ This will cause the prop classes.button (which will look like jss-1233
) to be merged with the button class that comes out of GrangeButtonStyles
so classes will now look like this:
{
button: 'jss-7382 jss-1233' <- jss-1233 is the classname that got generated in the previous component
}
and
<Button
className={clsx(classes.button, color, props.className)}
// should be
<Button
classes={{root:classes.button)}
^ See material-ui docs for button
It's actually unfortunate that material-ui forwards it's refs to the DOM element without checking for className because this allows people to put className on material-ui components and it "kind of" work. They should really add warnings to use
Thanks for a commentor for correcting my mistake, I still like the verbosity of passing classes
instead.classes
instead of className as mixing the two can result in confusion!
EDIT:
I also noticed you're messing up the styles in TestSelect
- always keep this in mind - don't pass className
as props to material-ui components, only pass classes
. If you want to pass styles from a parent component to a child component then you've got to use the same key:
Let's try an example, I know, this stuff is hard to grok but eventually it will "click":
const useParentStyles = makeStyles({
childStyles: { ... some jss }
childStyles2: { ... some jss }
});
const Parent = props => {
const classes = useParentStyles(props);
return <Child classes={{root:classes.childStyles,someOtherKey:classes.childStyles2}}/> <- object with a keys of "root" and "someOtherKey"
}
const useChildStyles = makeStyles({
root: { ... some jss } <- root
someOtherKey: { ... some jss } <- someOtherKey
});
const Child = props => {
const classes = useChildStyles(props); <- classes have been merged together
return <div className={classes.root}>...</div>
}
Source: stackoverflow.com
Related Query
- Styles being overwritten by Material-UI style
- Custom React Component styles being overwritten by Material-UI style
- Material UI 3.9.3 Checkbox Styles not being set in IE
- Material UI How to set external styles for sub-components with one main common style for the entire component
- Material UI button missing styles after being linked
- How to style components using makeStyles and still have lifecycle methods in Material UI?
- How to use useStyle to style Class Component in Material Ui
- react-datepicker styles are not being not applied on deployed build
- Material UI v4 makeStyles exported from a single file doesn't retain the styles on refresh
- Material UI 5 class name styles
- Removing underline style of autocomplete in react material ui component
- Add style from props to existing component styles in React Native
- Material UI: Is it possible to put the makeStyle styles in a separate file?
- CSS class selector styles not being applied in React Project
- Unable to modify some internal styles of Material UI's <Dialog> component
- How do I prevent Material UI Dialog from being dismissed upon clicking the backdrop?
- Higher Order Component redux dispatch being overwritten by wrapped component redux dispatch
- Material ui contained button styling being overidden by MuiButtonBase-root
- How to override style of nested Material UI component from the ancestors?
- How can I style Material UI table header?
- Material UI: Styles flicker in and disappear
- Material UI's Tooltip - Customization Style
- React Material UI condition statement within style property of button
- A component is changing the default value state of an uncontrolled Slider after being initialized. Material UI Slider with Redux State
- How to set Material UI (withStyle) style on an external file in React?
- Material UI - Overide disabled styles for InputBase
- How to change the style of sorting icon in Material UI table?
- Material UI styles not working in component (warning: several instances of `@material-ui/styles`)
- Material UI Overriding styles with increased specificity
- Material UI Table not being responsive while using example Responsive Drawer
More Query from same tag
- how to empty an array of objects in react
- Do I have to save react component files with a jsx extension
- Filtering an array in React
- react - select causing page to scroll down
- Is there a way to spread props over a component without overriding specified attributes?
- Why does my repository change after running npm run deploy?
- how to emit socket io to specific logged in user?
- how do i get placeholder when i click on text box
- Can I deploy react.js web app to a share hosting?
- Selenium's PhantomJS webdriver not loading page in reactjs
- How to import modules during tests using jest?
- Material-UI use default value in conditional 'overrides'
- QRCodeJs and react
- Trouble with react routing
- Unable to copy array using setstate hook
- ReactJS unable to edit the textbox created through state variable
- How to access URL parameter inside the ComponentDidMount method in react correctly
- Issue Install Yarn globally on Mac
- Electron open dialog hangs when using promise without async/await
- GridLines getting removed on y-axis visibility off
- What is the exact behaviour of useRef react hook? Does the object get recreated on each rerender?
- onSubmit not working with react-bootstrap Form
- Enum index signatures in TypeScript/React
- Preact: Typing the props of a component that wraps a native component
- Trying to retrieve data with axios.get() but Promise never seems to return
- Is it possible to pass a React Component to puppeteer?
- problem with format date in react component
- How to make a custom hook with useState which can update multiple elements if state changes?
- Date in javascript isn't correct
- How to type custom widget for Algolia React instant search?