57

I have been trying to achieve the simple thing. I was trying to show/hide my <TreeMenu/> component in the material UI v1 with pseudo selectors but somehow it does not work. Here is the code : CSS:

      root: {
        backgroundColor: 'white',
        '&:hover': {
          backgroundColor: '#99f',
        },
      },

  hoverEle: {
    visibility: 'hidden',
    '&:hover': {
      visibility: 'inherit',
    },
  },
      rootListItem: {
        backgroundColor: 'white',
        display: 'none',
        '&:hover': {
          display: 'block',
          backgroundColor: '#99f',
        },
      },
      '@global': {
        'li > div.nth-of-type(1)': {
          display: 'block !important',
          backgroundColor: "'yellow',",
        },
      },

The root css class works fine on the list but rootListItem or even the @global li selector does not work. I am not sure what I am doing wrong with selectors.I read the material-ui docs and says that V1 supports the pseudo selectors.

JSX:

<div>
      {props.treeNode.map(node => (
        <ListItem
          key={`${node.Type}|${node.NodeID}`}
          id={`${node.Type}|${node.NodeID}`}
          className={(classes.nested, classes.root)}
          button
          divider
          disableGutters={false}
          dense
          onClick={() => props.onNodeClick(node.Type, node.NodeID, node.NodeName)}
          title={props.adminUser ? node.NodeID : ''}
          onMouseOver={() => props.onMouseOver(node.Type, node.NodeID)}
        >
          <ListItemIcon>{props.listIcon}</ListItemIcon>
          <ListItemText primary={node.NodeName} />
          <ListItemSecondaryAction classes={{ root: classes.rootListItem }}>
            <TreeMenu />
          </ListItemSecondaryAction>
          <div className={classes.hoverEle}>
            <TreeMenu />
          </div>
        </ListItem>
      ))}
    </div>

Please look at the <TreeMenu > component. I have applied 3 different tricks: 1) hoverEle class with '&:hover' selector. 2) Tried to override the default root class of <ListItemSecondaryAction> with my class rootListItem 3) Using other pseudo selectors on li.See 'li > div.nth-of-type(1)':

connect2Coder
  • 1,122
  • 1
  • 13
  • 25
  • You want to hide *even* elements? – kind user Oct 30 '17 at 21:31
  • @Kinduser Thank you for your comment. Please look at the component. I am trying to hide that component with CSS selectors.I have updated my question for more clarification. – connect2Coder Oct 31 '17 at 16:27
  • Hello, it seems that is a bit late for this, but next time you could try to post a codepen. Make things easier to debug and check ;) – SirPeople Mar 28 '18 at 14:15
  • @SirPeople: Sorry for that. I will keep it in mind.I was just wondering do you have a solution to the problem? – connect2Coder Mar 28 '18 at 17:10
  • I just posted a small answer. your approach was correct, but it had some small errors in implementation. @connect2Coder – SirPeople Mar 29 '18 at 09:09
  • Adding this now as I spent some time trying to follow SirPeople's answer. Pseudo-selectors cannot be used with inline styles. There's some more info in the answer to this question. https://stackoverflow.com/questions/43701748/react-pseudo-selector-inline-styling – Rhys Madigan May 12 '19 at 14:14

3 Answers3

50

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.

SirPeople
  • 4,248
  • 26
  • 46
  • 1
    Thank you. Although I would not able to test this code(since my code has progressed a lot), this explains the things that I was doing wrong. So thank you for your efforts. – connect2Coder Mar 29 '18 at 16:25
9

Just adding with Jorge Santos Neil, you don't necessarily need to use props. I am adding one of the example that is tested for a different scenario. A note is that, this needs to be included in "makeStyles" and then used as a "className". Simply putting it inside "styles={{}}" does not work.

Example:

const useStyles = makeStyles((theme) => ({
  paragraphWithWarningDiv: {
    margin: "32px 0px 24px",
    "& :nth-child(1)": {
      marginBottom: "100px"
    }
  }
}));
Saikat halder
  • 548
  • 4
  • 11
  • While I appreciate your answer, I will like you to take a look at the date when the question was initially asked. Hooks were not around at that time. – connect2Coder Jul 24 '20 at 17:08
8

The solution that worked for me is the following

export const useStyles = makeStyles(theme=>({
        header:{
            position: "relative!important",
            background: "linear-gradient(150deg,#7795f8 15%,#6772e5 70%,#555abf 94%)",
            margin: -50,
            padding: -50,
            height: 500,
        },

        span: props => ({
            padding:50,
            background: "rgba(255, 255, 255, .1)",
            borderRadius: "50%",
            position: "absolute",
            "&:nth-child(1)": {
                left: "-4%",
                bottom: "auto",
                background: "rgba(255, 255, 255, .1)"
            },
            "&:nth-child(2)":{
                right: "4%",
                top: "10%",
                background: "rgba(255, 255, 255, .1)"
            },
            "&:nth-child(3)":{
                top: 280,
                right: "5.66666%",
                background: "rgba(255, 255, 255, .3)"
            },
            "&:nth-child(4)":{
                top: 320,
                right: "7%",
                background: "rgba(255, 255, 255, .15)"
            },
            "&:nth-child(5)":{
                top: "38%",
                left: "1%",
                right: "auto",
                background: "rgba(255, 255, 255, .05)"
            },
            "&:nth-child(6)": {
                width: 200,
                height: 200,
                top: "44%",
                left: "10%",
                right: "auto",
                background: "rgba(255, 255, 255, .15)"
            },
            "&:nth-child(7)": {
                bottom: "50%",
                right: "36%",
                background: "rgba(255, 255, 255, .04)"
            },
            "&:nth-child(8)": {
                bottom: 70,
                right: "2%",
                background: "rgba(255, 255, 255, .2)"
            },
            "&:nth-child(9)": {
                bottom: "1%",
                right: "2%",
                background: "rgba(255, 255, 255, .1)"
            },
            "&:nth-child(10)": {
                bottom: "1%",
                left: "1%",
                right: "auto",
                background: "rgba(255, 255, 255, .05)"
            }

        }),
Jorge Santos Neill
  • 1,635
  • 13
  • 6