Search code examples
next.jscss-modules

NextJs css modules - variable in className


I have a loop to duplicate elements several times. And I want to assign dynamic className to each element. I tried this method but the className is showing as ClassName='undefined1' ClassName='undefined2' , etc

import Style from './css/Style.module.css'

function component() {
  return (
  <div>
   {[...Array(7)].map((e, i) => {
       const numIn = i + 1
       return (
           <img className={`${Style.logo}${numIn}`} src='/assets/svg/logo.svg' alt="" key={i} />
       )
   })}
</div>
)
}

Desired outcome:

<img className='logo1' />
<img className='logo2' />
<img className='logo3' />
<img className='logo4' />
<img className='logo5' />
<img className='logo6' />

Style.module.css:

.logo1 {
   width: calc(112px * 2);
   margin-top: -2rem;
   margin-left: 38vw;
}

.logo2 {
    width: calc( 5rem * 2);
    margin-top: 4rem;
    margin-left: 60vw;
    transform: rotate(-30deg);
}

.logo3 {
    width: calc( 4rem * 2);
    margin-top: 1rem;
    margin-left: 80vw;
    transform: rotate(-8deg);    
}

//etc

edit: added Style.module.css file


Solution

  • CSS Modules locally scope CSS by automatically creating a unique class name, that means that if your Style.module.css is something like this :

    .logo1{
      // some css rules
    }
    
    .logo2{
      // some css rules
    }
    

    Next will generate for each class name (logo1,logo2 ecc..) a unique classname different from the one provided inside Style.module.css
    Basically Styles is an object with the class names as keys and the unique class names generated by next.js as property. This mean that you have to grab the class name in this way className={Style[`logo${numIn}`]}:

    import Style from './css/Style.module.css'
    
        function component() {
          return (
          <div>
           {[...Array(7)].map((e, i) => {
               const numIn = i + 1
               return (
                   <img className={Style[`logo${numIn}`]} src='/assets/svg/logo.svg' alt="" key={i} />
               )
           })}
        </div>
        )
        }
    

    Note that the rendered html will have different class names but with the right css rules.