In material ui using makeStyles, is it possible to write a css rule that applies only if the element has both classes?

11,448

Solution 1

I found the answer. I had to import the react-jss package and follow their documentation. I can now use the jssNested syntax and access nested elements and write rules that only apply if there are two classes attached to the element.

here it is:

import React from 'react'
import { render } from 'react-dom'
// Import React-JSS
import injectSheet from 'react-jss'

// Create your Styles. Remember, since React-JSS uses the default preset,
// most plugins are available without further configuration needed.
const styles = {
  mainNav: {
    zIndex: '3',
    color: 'white',
    textAlign: 'right',
    marginRight: '10%',
    '& ul': {
      zIndex: '2',
      textAlign: 'right',
      listStyleType: 'none',
      margin: '0px',
    }
  },
  li: {
    '& a': {
      color: 'white'
    }
  },
  mainNavWrapper: {
    paddingTop: '2%',
    background: 'rgba(0,0,0,0.8)',
    width: '100%',
    opacity: '1',
    transition: 'width 2s ease',
    padding: '10px',
    '&.sticky': {
      // jss-nested applies this to a child span
      fontWeight: 'bold' // jss-camel-case turns this into 'font-weight'
    },
    '&.scrolling': {
      opacity: '0',
      position: 'absolute',
      transition: 'opacity 1s ease'
    }
  },
  myLabel: {
    fontStyle: 'italic'
  }
}

// Define the component using these styles and pass it the 'classes' prop.
// Use this to assign scoped class names.
const Button = ({ classes, children }) => (
  <div className={classes.mainNavWrapper}>

    <nav className={classes.mainNav}>
      <ul className={classes.ul}>
        <li className={classes.li} ><a href="#" >home</a></li>
        <li className={classes.li}><a href="#">about us</a></li>
        <li className={classes.li}><a href="#">packages</a></li>
        <li className={classes.li}><a href="#">reviews</a></li>
        <li className={classes.li}><a href="#" className={classes.current}>contact us</a></li>
      </ul>
    </nav>
  </div>
)

// Finally, inject the stylesheet into the component.
const Test = injectSheet(styles)(Button)

export default Test;

Solution 2

I think I may have found it (extensive rubberducking)

https://github.com/cssinjs/jss-nested

const styles = {
  container: {
    padding: 20,
    '&:hover': {
      background: 'blue'
    },
    // Add a global .clear class to the container.
    '&.clear': {
      clear: 'both'
    },
    // Reference a global .button scoped to the container.
    '& .button': {
      background: 'red'
    },
    // Use multiple container refs in one selector
    '&.selected, &.active': {
      border: '1px solid red'
    }
  }
}

complies to:

.container-3775999496 {
  padding: 20px;
}
.container-3775999496:hover {
  background: blue;
}
.container-3775999496.clear {
  clear: both;
}
.container-3775999496 .button {
  background: red;
}
.container-3775999496.selected, .container-3775999496.active {
  border: 1px solid red;
}

Some of my other code is broken so it will take some time to verify this.

Share:
11,448

Related videos on Youtube

Sankofa
Author by

Sankofa

First degree in Math Education In pursuit of Computer Science degree Interested in learning from everyone Also passionate about sharing whatever knowledge I possess with whoever wants to know.

Updated on September 15, 2022

Comments

  • Sankofa
    Sankofa over 1 year

    I know that I can do this in CSS.

    .makeStyles-mainNavWrapper-67.sticky{
      position: fixed;
      top: 0px;
      opacity: 1;
      transition: opacity 1s ease;
      padding: 10px;
    }
    

    I want to know if I can do this in Material-UI so that I do not have to have two separate stylesheets so to speak (one for the MaterialUI ReactApp and one that is linked in the HTML tag.

    const Header = (props) => {
      const useStyles = makeStyles(theme => ({
        mainNav: {
          zIndex: '3',
          color: 'white',
          textAlign: 'right',
          marginRight: '10%'
        },
        mainNavWrapper: {
          paddingTop: '2%',
          background: 'rgba(0,0,0,0.8)'
        },
        mainNavWrapper.sticky: {
           I know this does not work. Is it possible?
        },
    

    I tried to just string together two classes in MaterialUI and I get errors.

  • Sankofa
    Sankofa over 4 years
    The only issue with this is that it does not explain well how to use the plugin. Anyone know how to set this up?
  • Ryan
    Ryan almost 3 years
    Nice! The ampersand with the space and then .[classname] to access a nested class was tripping me up!