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.