Hamburger button doesn't close after initial click - javascript

Navbar Component
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { logout } from '../../redux/actions/auth';
import './Navbar.styles.css';
import ham from './assets/ham.svg';
import exit from './assets/exit.svg';
export const Navbar = ({ auth: { isAuthenticated, loading }, logout }) => {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const authLinks = (
<div className='buttons'>
<Link to='/'>
<button onClick={logout} className='button'>
Logout
</button>
</Link>
</div>
);
const guestLinks = (
<div className='buttons'>
<Link to='/register'>
<button className='button'>Register</button>
</Link>
<Link to='login'>
<button className='button'>Login</button>
</Link>
</div>
);
console.log(isMenuOpen);
return (
<div className='container'>
<header>
<h2>
<Link to='/' className='logo' alt='Escapebe logo'>
<i className='fas fa-microphone'></i> Escapebe
</Link>
</h2>
<nav>
<Link to='#' className='hide-desktop'>
<img
src={ham}
alt='toggle menu'
className='menu'
onClick={() => setIsMenuOpen({ isMenuOpen: !isMenuOpen })}
/>
</Link>
<ul
className={
isMenuOpen
? 'hide-desktop show-mobile'
: 'show-desktop hide-mobile'
}
>
<li className='exit-btn hide-desktop'>
<img
src={exit}
onClick={() =>
setIsMenuOpen({
isMenuOpen: !isMenuOpen
})
}
/>
</li>
<li>
<Link to='/'>News</Link>
</li>
<li>
<Link to='/'>Groups</Link>
</li>
<li>
<Link to='/'>About</Link>
</li>
<li>
<Link to='/'>FAQ</Link>
</li>
{!loading && (
<Fragment>{isAuthenticated ? authLinks : guestLinks}</Fragment>
)}
</ul>
</nav>
</header>
</div>
);
};
Navbar.propTypes = {
logout: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth
});
export default connect(mapStateToProps, { logout })(Navbar);
HeroSection.styles.css
.container {
text-align: center;
padding: 0.8em 1.2em;
color: #d1d0d0;
}
.button {
background-color: #4caf50;
border: none;
width: calc(100% - 1em);
display: block;
color: #d1d0d0;
border-radius: 20px;
padding: 0.5em;
text-decoration: none;
font-size: 1em;
margin: 3% auto 7%;
position: relative;
z-index: 4;
cursor: pointer;
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
.button:hover {
background-color: green;
color: white;
}
.triangle {
margin: 2em auto 2em 45%;
width: 70%;
}
h1,
.subhead {
position: relative;
z-index: 3;
}
.subhead {
font-size: 1.1em;
}
#media only screen and (min-width: 650px) {
.triangle {
width: 50%;
}
.button {
width: 35%;
}
h1 {
font-size: 2em;
margin: 0;
}
.subhead {
font-size: 1.4em;
margin-bottom: 12%;
}
}
#media only screen and (min-width: 1000px) {
.button {
width: 35%;
}
.container {
width: 80%;
margin: 0 auto 13% auto;
}
.hide-desktop {
display: none;
}
.show-desktop {
display: block;
margin: 0 auto 13% auto;
}
nav ul {
position: inherit;
width: auto;
background: none;
height: auto;
display: flex;
padding-top: 0;
}
nav ul li {
float: left;
}
nav ul li a {
color: black;
background-color: inherit;
text-align: right;
padding: 1em 2em;
}
nav ul li a:hover {
background-color: inherit;
}
}
#media only screen and (min-width: 1200px) {
.container {
width: 70%;
}
}
Navbar.styles.css
.container {
text-align: center;
padding: 0.8em 1.2em;
list-style-type: none;
}
.logo {
width: 130px;
}
header {
display: flex;
justify-content: space-between;
}
.hide-mobile {
display: none;
}
.show-mobile {
display: initial;
}
.menu {
width: 25px;
margin-top: 115%;
}
nav ul {
position: fixed;
width: 60%;
top: 0;
right: 0;
text-align: left;
background: rgb(36, 41, 44);
height: 100%;
z-index: 7;
padding-top: 3em;
}
nav ul li a {
color: white;
text-decoration: none;
display: block;
width: 100%;
padding: 1em 2em;
background-color: rgb(52, 59, 63);
}
nav ul li a:hover {
background-color: rgb(65, 73, 78);
}
.exit-btn {
margin-bottom: 1em;
margin-top: -1.3em;
text-align: right;
padding: 0 1.4em;
}
.exit-btn img {
width: 15px;
cursor: pointer;
}
#media only screen and(min-width: 650px) {
.triangle {
width: 50%;
}
}
My hamburger menu isn't working. It works on the initial click but won't close afterwards. If I switch them around, then I can close the menu but not open it. I'm almost 100% sure that it doesn't have to do with the state. I think it may have something to do with my styling. Any ideas?

setIsMenuOpen({ isMenuOpen: !isMenuOpen })
This is wrong, It should be
setIsMenuOpen(!isMenuOpen)
I think this should fix.

Related

How to style & toggle notifications list?

I made a nav bar using nav and li tags, including a notifications icon, I am trying to make notifications nested list to show notifications, and use JavaScript to toggle/hide the menu, so far no luck. I've been looking for snippets online to support my logic, but I am stuck in the styling part and the JavaScript functionality. code below:
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(e) {
if (!e.target.matches('.dropbtn')) {
var myDropdown = document.getElementById("myDropdown");
if (myDropdown.classList.contains('show')) {
myDropdown.classList.remove('show');
}
}
}
html {
scroll-behavior: smooth;
}
* {
font-family: 'Roboto', sans-serif;
font-style: normal;
padding: 0;
margin: 0;
text-decoration: none;
}
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main {
flex: 1;
}
::-webkit-scrollbar {
width: 1.32vmin;
}
/*
::-webkit-scrollbar-track{
border: 0.53vmin solid rgba(7, 67, 146, 0.17);
box-shadow: inset 0 0 0.33vmin 0.26vmin rgba(7, 67, 146, 0.17);
}
*/
::-webkit-scrollbar-thumb {
background: #074392;
border-radius: 0vmin;
}
::-webkit-scrollbar-button {
height: 7.45vmin;
background: #074392;
}
body {
font-weight: 400;
font-size: 2.12vmin;
background-color: #FFFFFF;
/*overflow: hidden;*/
height: 100%;
}
h1 {
margin-left: 3vmin;
}
h5 {
margin: 2vmin 3vmin;
position: absolute;
width: 14.72vmin;
font-weight: 500;
font-size: 2.65vmin;
letter-spacing: 0.79vmin;
color: #FFFFFF;
display: inline;
}
nav {
background-color: #074392;
height: 7.42vmin;
width: 100%;
/*position: relative;*/
/*overflow: hidden;*/
position: sticky;
top: 0;
}
img.logo {
margin: 1.855vmin 3vmin;
height: 3.5vmin;
width: 7vmin;
}
nav ul {
float: right;
margin: 1.855vmin 2vmin;
}
nav ul li {
display: inline-block;
}
nav ul li::before {
content: " ";
padding: 0vmin 0.5vmin;
}
nav ul li a {
color: white;
/*margin: 0vmin 1vmin;*/
/*border-top-left-radius: 1.326vmin;
border-top-right-radius: 1.326vmin;
border-bottom-left-radius: 1.326vmin;
border-bottom-right-radius: 1.326vmin;*/
}
a.active,
a:hover {
font-variation-settings: 'FILL' 1;
}
.checkbtn {
color: #ffffff;
float: left;
cursor: pointer;
display: none;
margin: 1.855vmin 3vmin;
}
#check {
display: none;
}
#check:checked~ul {
left: 0;
}
.dropdown {}
.dropdown .dropbtn {
cursor: pointer;
border: none;
outline: none;
background-color: #074392;
color: #FFFFFF;
}
.dropdown:hover .dropbtn,
.dropbtn:focus {
color: #FFFFFF;
font-variation-settings: 'FILL' 1;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #0743922B;
width: 37.5vmin;
overflow-wrap: break-word;
transform: translateX(-56%);
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.dropdown-content a {
float: none;
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: justify;
}
.dropdown-content a:hover {
background-color: #0743922B;
}
.show {
display: block;
}
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD#20..48,100..700,0..1,-50..200" />
<div class="container">
<nav>
<input type="checkbox" id="check">
<label for="check" class="checkbtn">
<i class="material-symbols-rounded" style="font-size:3.5vmin;" title="Menu">menu</i>
</label>
<h5>LOGO</h5>
<ul>
<li>
<i class="material-symbols-rounded" style="font-size:3.5vmin;" title="Home">home</i>
</li>
<!-- <li> <i class="material-symbols-rounded" style="font-size:3.5vmin;" title="Notifications">notifications</i> -->
<li class="dropdown"><button class="dropbtn" onclick="myFunction()"><i class="material-symbols-rounded" style="font-size:3.5vmin;" title="Notifications">notifications</i></button>
<div class="dropdown-content" id="myDropdown">
<div>Link 1</div>
<div>Link 2</div>
<div>Link asasdasdasdasdasdsadsadasdasdasdasd asddasdas asd asd asd dasd asd</div>
</div>
</li>
<li>
<i class="material-symbols-rounded" style="font-size:3.5vmin;" title="Tasks">task</i>
</li>
<li>
<i class="material-symbols-rounded" style="font-size:3.5vmin;" title="Profile">person</i>
</li>
</ul>
<script type="text/javascript" src="JS/ActiveTab.js"></script>
<script type="text/javascript" src="JS/ToggleNotifications.js"></script>
</nav>
<main>
<h1>Example Page</h1>
</main>
</div>
By default set a display: none on the dropdown element and set a display: block on the hover pseudo-class of the dropdown element so when a hover event is triggered the dropdown appears.
Also, you can use classList.toggle method to remove if exists or to add if not exist the class.
Remove
Just add the following to the .css:
#myDropdown {
display: none;
}
#myDropdown.show {
display: block;
}
Remove onclick="myFunction()". And replace the .js with:
const myDropdown = document.getElementById('myDropdown')
addEventListener('click', event => {
let dropbtn = event.target.closest('button.dropbtn')
if (!dropbtn) return myDropdown.classList.remove('show')
console.log('hii')
myDropdown.classList.toggle('show')
})

Why does pressing the button only work 2 times? when the screen is narrowed to less than 768px

why does pressing the button only work 2 times? when the screen is narrowed to less than 768px
I need to make it infinite
CODEPEN - https://codepen.io/dxxxxxxfly/pen/LYmgwGo
let overleft = 0;
const burger = document.querySelector('.burger');
const overlay = document.querySelector('.overlay');
const nav = document.querySelector('.main_nav > ul').cloneNode(1);
burger.addEventListener('click', function(e) {
e.preventDefault();
if (overlay.style.left < 500) {
overlay.style.left = overleft + 'px';
render();
} else {
overlay.style.left = -500 + 'px';
}
function render() {
overlay.appendChild(nav);
}
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
overflow-x: hidden;
}
p {
font-family: 'Inter';
}
.content {
width: 100vw;
margin: 0 auto;
}
.learn_more {
background-color: #111131;
}
.learn_more>p {
text-align: center;
color: #ABABFA;
padding: 8px 0px;
font-size: 0.8125em;
}
nav {
justify-content: space-between;
display: flex;
}
.nav {
padding: 22px 36px;
box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.3);
}
.main_nav {
display: flex;
}
ul {
flex-wrap: wrap;
padding-left: 36px;
display: flex;
align-items: center;
}
li {
list-style-type: none;
}
ul>li {
padding-left: 24px;
}
ul>li>a {
font-family: 'Inter';
font-weight: 400;
text-decoration: none;
font-size: 0.875em;
color: #413E52;
}
.other_nav {
display: flex;
}
.burger {
cursor: pointer;
width: 50px;
height: 50px;
background: #5b64fb;
display: none;
border-radius: 50px;
}
.overlay {
height: 50vh;
width: 50vw;
background: #a1a1cb;
display: none;
left: -500px;
position: relative;
transition: 0.9s;
}
#media (max-width: 768px) {
.other_nav,
.main_nav>ul {
display: none;
}
.burger {
display: block;
}
.overlay {
display: flex;
/*left: 0px;*/
transition: 0.9s;
}
.main_nav {
display: none;
}
.nav {
padding-left: 0px;
}
}
<header class="header">
<div class="content">
<div class="learn_more">
<p>Слушайте музыку в высоком качестве и без рекламы</p>
</div>
<nav class="nav">
<div class="main_nav">
<div class="logo"><img src="assets/img/logosvg.svg" alt="Logo"></div>
<ul>
<li>Главная</li>
<li>Дискография</li>
<li>Альбомы</li>
</ul>
</div>
<div class="other_nav">
<div class="searth">
<img src="assets/img/search.svg" alt="">
<button class="subscribe">Поиск</button>
</div>
</div>
<div class="overlay"></div>
<div class="burger">
</div>
</nav>
</div>
</header>
You are using overlay.style.left that return a string, at first there is no style for left so it will return null. but next times it has value that its make the if always false. So you better to use overlay.offsetLeft instead of overlay.style.left for the if.
The code:
if (overlay.offsetLeft < 0) {
overlay.style.left = overleft + 'px';
render();
} else {
overlay.style.left = -500 + 'px';
}
It works only two times because overlay.style.left returns string like that -500px and it's not < 500. You have to cut out px and convert it to number. It also doesn't work on first click because overlay.style.left for first time returns empty string (use getComputedStyle). Change burger function onclick to it.
burger.addEventListener('click', function(e) {
const cssObj = window.getComputedStyle(overlay, null);
let left = cssObj.getPropertyValue("left");
left = Number(left.slice(0,-2));
if (left !== 0) {
overlay.style.left = "0px";
render();
} else {
overlay.style.left = "-500px";
}
function render() {
overlay.appendChild(nav);
}
});
let overleft = 0;
const burger = document.querySelector('.burger');
const overlay = document.querySelector('.overlay');
const nav = document.querySelector('.main_nav > ul').cloneNode(1);
burger.addEventListener('click', function(e) {
const cssObj = window.getComputedStyle(overlay, null);
let left = cssObj.getPropertyValue("left");
left = Number(left.slice(0,-2));
if (left !== 0) {
overlay.style.left = "0px";
render();
} else {
overlay.style.left = "-500px";
}
function render() {
overlay.appendChild(nav);
}
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
overflow-x: hidden;
}
p {
font-family: 'Inter';
}
.content {
width: 100vw;
margin: 0 auto;
}
.learn_more {
background-color: #111131;
}
.learn_more > p {
text-align: center;
color: #ABABFA;
padding: 8px 0px;
font-size: 0.8125em;
}
nav {
justify-content: space-between;
display: flex;
}
.nav {
padding: 22px 36px;
box-shadow: 0px 0px 15px 0px rgba(0,0,0,0.3);
}
.main_nav {
display: flex;
}
ul {
flex-wrap: wrap;
padding-left: 36px;
display: flex;
align-items: center;
}
li {
list-style-type: none;
}
ul > li {
padding-left: 24px;
}
ul>li>a {
font-family: 'Inter';
font-weight: 400;
text-decoration: none;
font-size: 0.875em;
color: #413E52;
}
.other_nav {
display: flex;
}
.burger {
cursor: pointer;
width: 50px;
height: 50px;
background: #5b64fb;
display: none;
border-radius: 50px;
}
.overlay {
height: 50vh;
width: 50vw;
background: #a1a1cb;
display: none;
left: -500px;
position: relative;
transition: 0.9s;
}
#media (max-width: 768px) {
.other_nav, .main_nav > ul {
display: none;
}
.burger {
display: block;
}
.overlay {
display: flex;
/*left: 0px;*/
transition: 0.9s;
}
.main_nav {
display: none;
}
.nav {
padding-left: 0px;
}
}
<header class="header">
<div class="content">
<div class="learn_more">
<p>Слушайте музыку в высоком качестве и без рекламы</p>
</div>
<nav class="nav">
<div class="main_nav">
<div class="logo"><img src="assets/img/logosvg.svg" alt="Logo"></div>
<ul>
<li>Главная</li>
<li>Дискография</li>
<li>Альбомы</li>
</ul>
</div>
<div class="other_nav">
<div class="searth">
<img src="assets/img/search.svg" alt="">
<button class="subscribe">Поиск</button>
</div>
</div>
<div class="overlay"></div>
<div class="burger">
</div>
</nav>
</div>
</header>

visibility style does not change second time click in javascript and css

I'm trying to create a responsive navbar.
When screen size is reduced I'm using media query to style visibility of #nav-items to hidden and display a menu icon.
I have written a javascript code to handle on click on menu icon style #nav-itmes to visible and hidden (trying to toggle by if condition to check style value)
Problem: on first click result is ok. #nav-items are visible but again when i click #nav-items style does not change to hidden (while i can console click event is there on every click)
Can anyone guide me ?
There are several approach to have this result to toggle an element but I want to only know what is issue in below code. (only javascript please).
let nav_icon = document.getElementById("nav-icon");
nav_icon.addEventListener("click", () => {
console.log('clicked');
let nav_items = document.getElementById("nav-items");
nav_items.style.visibility = nav_items.style.visibility = "hidden" ? "visible" : "hidden";
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: Arial, sans-serif;
}
a,
ul,
h3 {
text-decoration: none;
color: white;
list-style-type: none;
font-weight: bold;
}
body {
background-image: url("/img/bg.jpg");
}
img {
display: none;
height: 30px;
width: 30px;
margin-right: 10px;
position: fixed;
top: .4em;
right: .2em;
}
.navbar {
display: flex;
height: 40px;
width: 100%;
align-items: center;
justify-content: space-between;
background-color: #ABA9A966;
gap: 10px;
}
nav a,
header h3 {
margin: 0px 10px 0px 10px;
}
nav a:hover {
background-color: grey;
}
#media screen and (max-width: 800px) {
nav a,
header h3 {
margin: 0px 5px 0px 5px;
font-size: 15px;
}
}
#media screen and (max-width: 600px) {
.navbar {
flex-flow: column;
}
header {
display: none;
}
nav {
width: auto;
text-align: center;
background-color: #ABA9A966;
position: fixed;
visibility: hidden;
top: 2.5em;
right: 0;
}
nav a {
margin: 0;
height: 22px;
padding-top: 3px;
display: block;
width: 8rem;
font-size: 14px;
}
img {
display: block;
}
}
<meta name="viewport" content="width=device-width, initial-scale=1">
<div class="navbar">
<header>
<h3>Hello Guest</h3>
</header>
<nav id="nav-items">
Home
Dispatch
Account
Report
Control
</nav>
</div>
<img src="/img/menu.png" id="nav-icon">
Often you cannot see the style of an element in JS if the style was applied in a stylesheet
You can toggle a class instead
For example
nav { visibility: hidden; }
nav.show { visibility: visible; }
and js
const nav_icon = document.getElementById("nav-icon");
const nav_items = document.getElementById("nav-items");
nav_icon.addEventListener("click", () => {
console.log('clicked');
nav_items.classList.toggle("show")
});
const nav_icon = document.getElementById("nav-icon");
const nav_items = document.getElementById("nav-items");
nav_icon.addEventListener("click", () => {
console.log('clicked');
nav_items.classList.toggle("show")
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: Arial, sans-serif;
}
a,
ul,
h3 {
text-decoration: none;
color: white;
list-style-type: none;
font-weight: bold;
}
body {
background-image: url("/img/bg.jpg");
}
img {
height: 30px;
width: 30px;
margin-right: 10px;
position: fixed;
top: .4em;
right: .2em;
}
.navbar {
display: flex;
height: 40px;
width: 100%;
align-items: center;
justify-content: space-between;
background-color: #ABA9A966;
gap: 10px;
}
nav { visibility: hidden; }
nav a,
header h3 {
margin: 0px 10px 0px 10px;
}
nav a:hover {
background-color: grey;
}
#media screen and (max-width: 800px) {
nav a,
header h3 {
margin: 0px 5px 0px 5px;
font-size: 15px;
}
}
#media screen and (max-width: 600px) {
.navbar {
flex-flow: column;
}
header {
display: none;
}
nav {
width: auto;
text-align: center;
background-color: #ABA9A966;
position: fixed;
visibility: hidden;
top: 2.5em;
right: 0;
}
nav a {
margin: 0;
height: 22px;
padding-top: 3px;
display: block;
width: 8rem;
font-size: 14px;
}
img {
display: block;
}
}
nav.show {
visibility: visible;
}
<meta name="viewport" content="width=device-width, initial-scale=1">
<div class="navbar">
<header>
<h3>Hello Guest</h3>
</header>
<nav id="nav-items">
Home
Dispatch
Account
Report
Control
</nav>
</div>
<img src="/img/menu.png" id="nav-icon" title="ICON" alt="ICON">
Think this line is incorrect:
nav_items.style.visibility = nav_items.style.visibility = "hidden" ? "visible" : "hidden";
The equality check should be:
nav_items.style.visibility === "hidden"
so this may work:
nav_items.style.visibility = (nav_items.style.visibility === "hidden" ? "visible" : "hidden");
Try the css property for media-query: display:none !important;

CSS Issue with a button placement in a container

I am currently making a practise eCommerce website and I have encountered a problem with my styling, I can't figure out how to attach the button to the very bottom of the product container so that other items don't overstretch.
I would ideally like the containers to stretch and balance out the content to the length of the longest item.
Here is a picture of the issue
CSS:
.card-container {
max-width: 80%;
width: 80%;
margin: auto;
display: flex;
justify-content: center;
flex-wrap: wrap;
height: 500px;
}
.product-name {
font-size: 130%;
font-weight: bold;
color: black;
}
.image-container {
width: 80%;
height: 250px;
}
.description {
padding: 0 20px;
}
.link {
text-decoration: none;
}
.item-info {
line-height: 200%;
}
.card {
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
max-width: 300px;
margin: 2em auto;
text-align: center;
font-family: arial;
width: 100%;
min-width: 300px;
}
.card img {
max-width: 250px;
max-height: 200px;
}
.price {
font-size: 22px;
}
.card button {
border: none;
outline: 0;
padding: 12px;
color: white;
background-color: #000;
text-align: center;
cursor: pointer;
width: 100%;
font-size: 18px;
}
.card button:hover {
opacity: 0.7;
}
JSX:
import './Home.css'
import { Link } from 'react-router-dom';
import { useState, useEffect } from 'react';
import fetchItems from '../../utils/fetchItems';
export const Home = () => {
const [ products, setProducts ]= useState([]);
useEffect(() => {
(async () => {
const response = await fetchItems('/products');
setProducts(response);
})()
}, []);
return(
<div>
<h1>Welcome to Sahara</h1>
<div className='card-container'>
{products.map(product => {
return(
<div className="card">
<img src={product.image} alt='product' />
<div className='item-info'>
<Link to={`/products/${product.id}`} className='link'><h4 className='product-name'>{product.name}</h4></Link>
<p className='seller'>{product.seller}</p>
<p className='price'>${product.price}</p>
<Link to='/cart'><button>Add to Cart</button></Link>
</div>
</div>
)
})}
</div>
</div>
)
}
Any help would be greatly appreciated.
Thank you.
An easy way to do this would be to have the the .card position: relative; and the .card button be set to position: absolute; Something similar to the below:
.card {
position: relative;
}
.card button {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
}
You could use position: absolute; to align the button to the bottom. Add these values to the stylesheet:
.card {
position: relative;
}
.card button {
position: absolute;
bottom: 0;
right: 0;
}
See this question for more information.
.card {
position: relative;
}
.card button {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
}

Navigation bar displayed incorrectly when scrolling and in mobile view

I have a problem with the navigation bar. When it is at the top it should be transparent and the font color in white as soon as the user scrolls a bit the background of the navigation bar should change to white and the font color to black. This also works except for the mobile view.
The icon for the menu is not displayed in black and also if I am at the top (navigation bar is in transparent color) then the mobile menu is also displayed correctly, but if I scroll down a bit and the mobile navigation bar is displayed in white, the mobile navigation bar is displayed in black font which should not be so. How can I solve this problem?
Navigation bar at the top and transparent
Naivgations bar scrolled and in white
MOBILE-VIEW
Mobile navigation bar at the top and transparent
Mobile navigation bar at the top and transparent and when you open the menu
Naivgations bar scrolled and in white
Naivgations bar scrolled and in white and you open the menu
The menu bar should be exactly like the one in the image above and the icon should be in black like picture 4
CODE
Navbar.js
import React, { useState, useEffect } from "react";
import { Button } from "../buttons/Button";
import { Link } from "react-router-dom";
import "./Navbar.css";
function Navbar() {
const [click, setClick] = useState(false);
const [button, setButton] = useState(true);
const [navbar, setNavbar ] = useState(false);
const handleClick = () => setClick(!click);
const closeMobileMenu = () => setClick(false);
const showButton = () => {
if (window.innerWidth <= 960) {
setButton(false);
} else {
setButton(true);
}
};
useEffect(() => {
showButton();
}, []);
window.addEventListener("resize", showButton);
const changeBackground = () => {
if(window.scrollY >= 80) {
setNavbar(true);
}
else {
setNavbar(false);
}
};
window.addEventListener('scroll', changeBackground);
return (
<>
<nav className={navbar ? 'navbar active' : 'navbar'}>
<div className="navbar-container">
<Link to="/" className={navbar ? 'navbar-logo active' : 'navbar-logo'} onClick={closeMobileMenu}>
NAME
<i class="fab fa-typo3" />
</Link>
<div className="menu-icon" onClick={handleClick}>
<i className={click ? "fas fa-times" : "fas fa-bars"} />
</div>
<ul className={click ? "nav-menu active" : "nav-menu"}>
<li className="nav-item">
<Link to="/" className={navbar ? 'nav-links active' : 'nav-links'} onClick={closeMobileMenu}>
Text 1
</Link>
</li>
<li className="nav-item">
<Link
to="/"
className={navbar ? 'nav-links active' : 'nav-links'}
onClick={closeMobileMenu}
>
Text 2
</Link>
</li>
<li className="nav-item">
<Link
to="/"
className={navbar ? 'nav-links active' : 'nav-links'}
onClick={closeMobileMenu}
>
Text 3
</Link>
</li>
<li>
<Link
to="/"
className="nav-links-mobile"
onClick={closeMobileMenu}
>
BUTTON
</Link>
</li>
</ul>
{button && <Button buttonStyle="btn--primary">BUTTON</Button>}
</div>
</nav>
</>
);
}
export default Navbar;
Navbar.css
.navbar {
/*background: #2b41cb;*/
background: transparent;
height: 80px;
display: flex;
justify-content: center;
align-items: center;
font-size: 1.2rem;
position: sticky;
top: 0;
z-index: 999;
margin-bottom: -80px;
}
.navbar-container {
display: flex;
justify-content: center;
align-items: center;
height: 80px;
max-width: 1500px;
}
.navbar-logo {
color: #fff;
justify-self: start;
margin-left: 20px;
cursor: pointer;
text-decoration: none;
font-size: 2rem;
display: flex;
align-items: center;
}
.fa-typo3 {
margin-left: 0.5rem;
font-size: 1.8rem;
}
.nav-menu {
display: grid;
grid-template-columns: repeat(4, auto);
grid-gap: 10px;
list-style: none;
text-align: center;
width: 60vw;
justify-content: end;
margin-right: 2rem;
}
.nav-item {
height: 80px;
}
.nav-links {
color: #fff;
display: flex;
align-items: center;
text-decoration: none;
padding: 0.5rem 1rem;
height: 100%;
}
.nav-links:hover {
border-bottom: 4px solid #fff;
transition: all 0.2s ease-out;
}
.fa-bars {
color: #fff;
}
.nav-links-mobile {
display: none;
}
.menu-icon {
display: none;
}
#media screen and (max-width: 960px) {
.NavbarItems {
position: relative;
}
.nav-menu {
display: flex;
flex-direction: column;
width: 100%;
height: 90vh;
position: absolute;
top: 80px;
left: -100%;
opacity: 1;
transition: all 0.5s ease;
}
.nav-menu.active {
background: #242222;
left: 0;
opacity: 1;
transition: all 0.5s ease;
z-index: 1;
}
.nav-links {
text-align: center;
padding: 2rem;
width: 100%;
display: table;
}
.nav-links:hover {
background-color: #fff;
color: #242424;
border-radius: 0;
}
.navbar-logo {
position: absolute;
top: 0;
left: 0;
transform: translate(25%, 50%);
}
.menu-icon {
display: block;
position: absolute;
top: 0;
right: 0;
transform: translate(-100%, 60%);
font-size: 1.8rem;
cursor: pointer;
}
.fa-times {
color: #fff;
font-size: 2rem;
}
.nav-links-mobile {
display: block;
text-align: center;
margin: 2rem auto;
border-radius: 4px;
width: 80%;
text-decoration: none;
font-size: 1.5rem;
background-color: goldenrod;
color: #fff;
padding: 14px 20px;
border: 1px solid goldenrod;
transition: all 0.3s ease-out;
border-radius: 25px;
}
.nav-links-mobile:hover {
background: goldenrod;
transition: 250ms;
}
}
/* NAVBAR ACTIVE */
.navbar.active {
/*background: linear-gradient(90deg, rgb(66, 2, 194) 0%, rgb(0, 78, 194) 100%)*/
background: #fff;
border-bottom: 2px solid #e8e8e8;
}
.navbar-logo.active {
color: #000;
}
.nav-links.active {
color: #000;
}
.nav-links.active:hover {
border-bottom: 4px solid #000;
transition: all 0.2s ease-out;
}
Is not necessary, but for it to run
HeroSection.js
import React from 'react';
import '../../App.css';
import { Button } from '../buttons/Button';
import './HeroSection.css';
function HeroSection() {
return (
<div className='hero-container'>
<h1>Heading One</h1>
<p>Some Text!</p>
<div className='hero-btns'>
<Button
className='btns'
buttonStyle='btn--outline'
buttonSize='btn--large'
>
BUTTON 1
</Button>
<Button
className='btns'
buttonStyle='btn--primary'
buttonSize='btn--large'
>
BUTTON 2 <i className='far fa-arrow-alt-circle-right' />
</Button>
</div>
</div>
);
}
export default HeroSection;
HeroSection.css
video {
object-fit: cover;
width: 100%;
height: 100%;
position: fixed;
z-index: -1;
}
.hero-container {
background: rgba(102, 232, 255, 0.849);
height: 100vh;
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
/*box-shadow: inset 0 0 0 1000px rgba(0, 0, 0, 0.2);*/
object-fit: contain;
}
.hero-container > h1 {
color: #fff;
font-size: 100px;
margin-top: -100px;
}
.hero-container > p {
margin-top: 8px;
color: #fff;
font-size: 32px;
font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande',
'Lucida Sans', Arial, sans-serif;
}
.hero-btns {
margin-top: 32px;
}
.hero-btns .btn {
margin: 6px;
}
.fa-play-circle {
margin-left: 4px;
}
#media screen and (max-width: 960px) {
.hero-container > h1 {
font-size: 70px;
margin-top: -150px;
}
}
#media screen and (max-width: 768px) {
.hero-container > h1 {
font-size: 50px;
margin-top: -100px;
}
.hero-container > p {
font-size: 30px;
}
.btn-mobile {
display: block;
text-decoration: none;
}
.btn {
width: 100%;
}
}
Home.js
import React from 'react';
import '../../App.css';
import Cards from '../cards/Cards';
import Footer from '../footer/Footer';
import HeroSection from '../Hero/HeroSection';
import Box from '../box/Box';
function Home() {
return (
<>
<HeroSection></HeroSection>
</>
)
}
export default Home;
App.js
import React from 'react'
import Navbar from './components/navbar/Navbar'
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import Home from './components/pages/Home';
import './App.css'
function App() {
return (
<>
<Router>
<Navbar/>
<Switch>
<Route path='/' exact component={Home} />
</Switch>
</Router>
</>
);
}
export default App;
may you need different class for you different Navigation button in different situation added it dynamically:)
window.addEventListener("resize", showButton);
const changeBackground = () => {
let scrollClass = '';
if(window.scrollY >= 80) {
setNavbar(true);
scrollClass = 'black';
}
else {
setNavbar(false);
scrollClass = '';
}
this.setState({ scrollClass });
<div className="menu-icon" onClick={handleClick}>
<i className={`click ? "fas fa-times" : "fas fa-bars" ${this.state.scrollClass }`} />
</div>

Categories