How to use pseudo selectors in material-ui?
After a while fighting to have your code up and running I found what is wrong with your code.
Everything seems to be fine, the selector for rootListItem works right out of the box, the problem is that you can not use the pseudo-selector :hover
on an element that has display: none
. Instead you should be using opacity: 0 and opacity: 1
, it will hide your ListItemSecondaryAction but at the same time it will allow you to hover. So, elements with display: none, doesn't technically display and thereby, you cannot hover them.
About your pseudo selector in global, you just wrote it wrongly. Using colon instead of dot after div and changing backgroundColor to 'yellow' instead of "'yellow',"
'li > div:nth-of-type(1)': {
display: 'block !important',
backgroundColor: 'yellow',
},
I didn't know how does your TreeMenu look like as a component, so I just created a list with ul / li / div nodes.
const styles = {
root: {
backgroundColor: 'white',
'&:hover': {
backgroundColor: '#99f',
},
},
hoverEle: {
visibility: 'hidden',
'&:hover': {
visibility: 'inherit',
},
},
rootListItem: {
backgroundColor: 'white',
opacity: 0,
'&:hover': {
opacity: 1,
backgroundColor: '#99f',
},
},
'@global': {
'li > div:nth-of-type(1)': {
display: 'block !important',
backgroundColor: "yellow",
},
},
};
And:
<div>
{treeNode.map(node => (
<ListItem
key={`${node.Type}|${node.NodeID}`}
id={`${node.Type}|${node.NodeID}`}
className={classes.root}
button
divider
disableGutters={false}
dense
onClick={() => {}}
title={''}
onMouseOver={() => {}}
>
<ListItemText primary={node.NodeName} />
<ListItemSecondaryAction classes={{ root: classes.rootListItem }}>
<ul><li><div>Elem 1</div></li><li><div>Elem 2</div></li></ul>
</ListItemSecondaryAction>
<div className={classes.hoverEle}>
<ul><li><div>Elem 1</div></li><li><div>Elem 2</div></li></ul>
</div>
</ListItem>
))}
</div>
*I am using treeNode that is an array for me and I removed the rest of the functions and TreeMenu.
CSS pseudo selectors with MUI
I found out that the content attribute needed to be double quoted like this
const styles = () =>
createStyles({
h: {
'&::before': {
content: '"some content"',
display: 'block',
height: 60,
marginTop: -60
}
}
});
and then everything worked like expected
MUI - How to use pseudo class in specific styled component
Item
is the direct children of Grid
so you can use div > div
selector:
const Grid = styled('div')(({ theme }) => ({
...,
'& > :nth-child(3n-2)': {
backgroundColor: 'lightYellow',
},
'& > :nth-child(3n-1)': {
backgroundColor: 'lightGreen',
},
'& > :nth-child(3n)': {
backgroundColor: 'lightBlue',
},
}));
If you want to target a specific child, you can add a class name to identify it:
const Grid = styled('div')(({ theme }) => ({
...,
'& > .item1': {
backgroundColor: 'lightYellow',
},
'& > .item2': {
backgroundColor: 'lightGreen',
},
'& > .item3': {
backgroundColor: 'lightBlue',
},
}));
<Grid>
<Item className="item1" />
<Item className="item2" />
<Item className="item3" />
<Item className="item1" />
<Item className="item2" />
<Item className="item3" />
<Item className="item1" />
<Item className="item2" />
<Item className="item3" />
</Grid>
Pseudo Selector in Material-UI withStyles not rendering to page
The value for content needs to be wrapped in quotes.
This makes so that it is compiled to the correct CSS representation with the quotes.
content: "'test'",
or
content: '"test"',
How do I use pseudo selectors with material ui's styled api?
I was missing the most important part: the &
.
const ActionButton = styled(Button)({
margin: '0 16px',
'&:first-child': {
marginLeft: 0,
},
'&:last-child': {
marginRight: 0,
},
});
target pseudo selectors in material ui
I have created this sandbox project, you can check, things are working fine or correct me if I am missing something to understand your problem
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Typography from "@material-ui/core/Typography";
const useStyles = makeStyles(theme => ({
root: {
textAlign: "center",
"&::before": {
content: '"-"'
},
"&::after": {
content: '"-"'
}
}
}));
export default function App(props) {
const classes = useStyles();
return (
<Typography className={classes.root} {...props}>
Hello
</Typography>
);
}
I think you are using the className
props in a wrong way, you have to pass the string, not an object.classes
props expect an object, we generally use classes props on the component which have exposed class names to override their inner styles, for example in case of Typography Component you can override root element style like this.
export default function App(props) {
const classes = useStyles();
return (
<Typography classes={{ root: classes.root }} {...props}>
Hello
</Typography>
);
}
so classes
and classNames
are two different things in Material-UI, but sometimes(when you want to apply the style to root element of component) both provide the same solution.
I have created one more Sandbox project with the second solution
Related Topics
Defining Keyframe Animations Inside Media Queries
PHP/HTML/CSS - If Firefox, If Chrome, If Safari
Webpack 4: Mini-CSS-Extract-Plugin + Sass-Loader + Splitchunks
One CSS Declaration for All CSS Font Properties
How to Configure Sourcemaps for Less Using Grunt
Overriding Bootstrap Table-Striped CSS
Keep Bootstrap Columns in Same Row When Changing Size
Less CSS Syntax Useful for Modernizr
Lato' Font Rendering Odd in Safari, Not in Chrome, or Firefox
Fade in Fade Out on Image Hover Using CSS3
Media Queries - CSS Only for iPhone Landscape
Ssl and Mixed Content Due to CSS Background Images
Remove or Add Class in Angular
How to Float a Twitter Bootstrap Navbar Item Right with Either Class=Pull-Right or Float:Right
What's The Difference Between Line-Height:1.5 and Line-Height:150% in CSS