简体   繁体   中英

How do i refer the className when having a nested scss ? nextjs reactjs

I have a navbar with a hamburger button and i want to change the style (the bar color and the hamburger button style) on tap. I mention that i've tried using &:active, &.activeBar on the scss file. For some reason the background color doesn t change and the hamburger button doesn't turn into an X

This is my SCSS file:

 .topbar { width: 100%; background-color: $secondaryColor; color: $mainColor; height: 70px; position: fixed; top: 0; z-index: 3; transition: all 1s ease; overflow: hidden; .wrapper { padding: 10px 30px; display: flex; align-items: center; justify-content: space-between; } .left { display: flex; align-items: center; margin: 10; .itemContainer { display: flex; align-items: center; .icon { font-size: 36px; margin-right: 5px; &:hover { color: blue; } } span { font-size: 15px; font-weight: 700; } } .logo { font-size: 40px; font-weight: 700; text-decoration: none; color: inherit; margin-right: 40px; } } .right { .hamburger { width: 32px; height: 25px; display: flex; flex-direction: column; justify-content: space-between; span { width: 100%; height: 3px; background-color: $mainColor; transform-origin: left; transition: all 0.5s ease; } } } &.activeBar { background-color: $mainColor; color: $secondaryColor; .hamburger span { &:first-child { background-color: $secondaryColor; transform: rotate(45deg); } &:nth-child(2) { opacity: 0; } &:last-child { background-color: $secondaryColor; transform: rotate(-45deg); } } } }

And this is where i try to change the classname in my js file:

 import React from 'react'; import styles from './topbar.module.scss'; import { Facebook } from '@material-ui/icons'; const Topbar = ({ open, toggle }) => { function menuToggled() { toggle(!open); console.log('menuToggled', open); } return ( <div className={`${styles.topbar} ${open ? 'active' : ''}`}> <div className={styles.wrapper}> <div className={styles.left}> <a href='#slider' className={styles.logo}> Muntenia cu gust </a> <div className={styles.itemContainer}> <Facebook className={styles.icon} onClick={() => window.open('https://stackoverflow.com/')} /> </div> </div> <div className={styles.right}> <div className={styles.hamburger} onClick={menuToggled}> <span className={styles.line1}></span> <span className={styles.line2}></span> <span className={styles.line3}></span> </div> </div> </div> </div> ); }; export default Topbar;

In your code, you're adding active as a class in the "global" scope. By default with css-modules , all classes are output in "local" scope. So your .topbar class, after compilation, would look something like: .Topbar_topbar__abc12 ("abc12" would be a hash).

So, the .active class is also being compiled to local scope, looking something like: .Topbar_active_def34

In your markup, you're toggling the .active class as a string rather than as styles.active . So, on output, you're expecting your "active" class to be .Topbar_topbar__abc12.active when in actuality, your stylesheet is declaring .Topbar_topbar_abc12.Topbar_active_def32 as the "active" class.

By declaring .active as being in the global scope, the output would then be as expected. Try adding the :global flag to your stylesheet:

...
  &:global(.active) {
    background-color: $mainColor;
    color: $secondaryColor;
    .hamburger span {
      &:first-child {
        background-color: $secondaryColor;
        transform: rotate(45deg);
      }
      &:nth-child(2) {
        opacity: 0;
      }
      &:last-child {
        background-color: $secondaryColor;
        transform: rotate(-45deg);
      }
    }
  }
...

使用classnames包( https://www.npmjs.com/package/classnames )来组合相同元素上的类,其余的处理方式与 vanilla html/css/js 中的相同 在您的代码中,您也使用active它应该来自样式并使用以下方式组合:

classnames('styles.ElementClassName', active && styles.active)

Adding the active selector on the regular .hamburger class should trigger on touch. Also the classname in you scss is activeBar but in your react app is only active .

&.clicked {
background-color: $mainColor;
color: $secondaryColor;
.hamburger span {
  &:first-child {
    background-color: $secondaryColor;
    transform: rotate(45deg);
  }
  &:nth-child(2) {
    opacity: 0;
  }
  &:last-child {
    background-color: $secondaryColor;
    transform: rotate(-45deg);
  }

 }
   }

If you want to change the topBar also then you'll need to change your TopBar component a bit

import React, { useState } from 'react';
import styles from './topbar.module.scss';
import { Facebook } from '@material-ui/icons';

const Topbar = ({ open, toggle }) => {
    const [isClicked, setIsClicked] = useState(false);
  function menuToggled() {
    toggle(!open);
    console.log('menuToggled', open);
  }
  return (
    <div className={`${styles.topbar} ${open ? 'active' : ''} ${ isClicked && ' clicked'}`}>
      <div className={styles.wrapper}>
        <div className={styles.left}>
          <a href='#slider' className={styles.logo}>
            Muntenia cu gust
          </a>
          <div className={styles.itemContainer}>
            <Facebook
              className={styles.icon}
              onClick={() => window.open('https://stackoverflow.com/')}
            />
          </div>
        </div>
        <div className={styles.right}>
          <div className={styles.hamburger} onClick={menuToggled} onTouchStart={(e) => setIsClicked(true)}>
            <span className={styles.line1}></span>
            <span className={styles.line2}></span>
            <span className={styles.line3}></span>
          </div>
        </div>
      </div>
    </div>
  );
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM