How to Use Pseudo Selectors in Material-Ui

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>

Codesandbox Demo

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



Leave a reply



Submit