I built a hamburger menu with a small animation but for the life of me I cannot figure out why it disappears after it is triggered as "active". Everything works perfectly after much trouble shooting but the fact that the hamburger menu disappears after the side menu opens up does not give the user the ability to close the menu and continue navigating the site. I posted all relevant code below please let me know what I overlooked.
window.onload = function () {
window.addEventListener('scroll', function (e) {
if (window.pageYOffset > 100) {
document.querySelector("header").classList.add('is-scrolling');
} else {
document.querySelector("header").classList.remove('is-scrolling');
}
});
const menu_btn = document.querySelector('.hamburger');
const mobile_menu = document.querySelector('.mobile-nav');
menu_btn.addEventListener('click', function () {
menu_btn.classList.toggle('is-active');
mobile_menu.classList.toggle('is-active');
});
}
.hamburger {
grid-row-start: A;
grid-column-start: A;
grid-row-end: A;
grid-column-end: A;
align-self: center;
justify-self: center;
position: relative;
display: block;
width: 35px;
cursor: pointer;
appearance: none;
background: none;
outline: none;
border: none;
}
.hamburger .bar, .hamburger:after, .hamburger:before {
content: '';
display: block;
width: 100%;
height: 5px;
background-color: #000;
margin: 6px 0px;
transition: 0.4s;
}
.hamburger.is-active:before {
transform: rotate(-45deg) translate(-8px, 6px);
}
.hamburger.is-active:after {
transform: rotate(45deg) translate(-9px, -8px);
}
.hamburger.is-active .bar {
opacity: 0;
}
.mobile-nav {
position: fixed;
top: 0;
left: 100%;
width: 100%;
min-height: 100vh;
display: block;
z-index: 98;
background-color: #12002F;
padding-top: 120px;
transition: 0.4s;
}
.mobile-nav.is-active {
left: 0;
}
.mobile-nav a {
display: block;
width: 100%;
max-width: 200px;
margin: 0 auto 16px;
text-align: center;
padding: 12px 16px;
background-color: #1f103F;
color: #FFF;
text-decoration: none;
}
.mobile-nav a:hover {
background-color: #24104f;
}
<button class="hamburger">
<div class="bar"></div>
</button>
<nav class="mobile-nav">
Home
Home
Home
Home
Home
</nav>
It's being hidden behind mobile-nav, one solution is to increase it's z-index to continue to have it show
.mobile-nav {
position: fixed;
top: 0;
left: 100%;
width: 100%;
min-height: 100vh;
display: block;
z-index: 98; /* Has to be greater than this z-index */
background-color: #12002F;
padding-top: 120px;
transition: 0.4s;
}
Related
This question may seem similar to other questions but my hamburger menu uses checkbox to function and shows up at 768px width and below and I've been running into issues trying to close the open hamburger menu when the window/document is clicked.
I successfully got it to work using several ways but it still doesn't work as intended. The hamburger menu closes on document click alright, but the hamburger menu no longer closes on hamburger menu click as it originally should.
I have very little knowledge of Javascript/Jquery but I understand the bits I used to make other parts of the code work, but I just can't figure out how to make this particular one work.
Below is the code required to recreate the problem:
$(document).ready(function() {
// Script to push the section down on menu click
$(".menu-btn").click(function(e) {
e.stopPropagation();
$(".main-content").toggleClass("open");
});
// Script to collapse menu on link click
$(".nav-link").click(function(e) {
e.stopPropagation();
$(".menu-btn").click();
});
//Script to close the menu on window/document click
//With Jquery
$(document).click(function(e) {
if (!$('.menu-btn').is(e.target) // if the target of the click isn't the button...
&&
($(('.menu-btn')).is(":checked"))) {
$('.menu-btn').click();
}
});
});
//With vanilla JS
/* window.onclick = function(event) {
if (document.getElementById('menu-btn').checked) {
document.getElementById('menu-btn').click();
}
} */
*,
*::before,
*::after {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
min-width: fit-content;
}
body {
font-family: "Montserrat", sans-serif;
background-color: #eeeeee;
}
header {
width: 100%;
background-color: #eeeeee;
padding: 0 20px;
height: 65px;
position: fixed;
top: 0;
}
.logo {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
margin-top: 15px;
}
#header-img {
width: 100%;
height: 100%;
max-width: 300px;
}
/* Navigation */
nav {
width: 100%;
text-align: center;
}
/* Hamburger menu button */
.menu-btn {
display: none;
}
.menu-icon {
display: inline-block;
position: relative;
top: -42px;
left: -25px;
cursor: pointer;
padding: 24px 14px;
z-index: 1;
}
.navicon {
background-color: #222222;
display: block;
height: 3px;
width: 26px;
position: relative;
transition: 0.3192s ease-in-out;
}
.navicon:before,
.navicon:after {
content: "";
display: block;
height: 100%;
width: 100%;
position: absolute;
background-color: #222222;
transition: 0.3192s ease-in-out;
}
.navicon:before {
top: 9px;
}
.navicon:after {
bottom: 9px;
}
/* Hamburger Menu Animation Start */
.menu-btn:checked~.menu-icon .navicon:before {
transform: rotate(-45deg);
top: 0;
}
.menu-btn:checked~.menu-icon .navicon:after {
transform: rotate(45deg);
bottom: 0;
}
.menu-btn:checked~.menu-icon .navicon {
background: transparent;
transition: 0.3192s ease-in-out;
}
/* Hide blue background on hamburger menu tap on some mobile devices */
.menu-icon,
.menu-btn,
.navicon {
-webkit-tap-highlight-color: transparent;
}
/* Nav items */
.menu {
background-color: #eeeeee;
width: 100%;
height: auto;
list-style-type: none;
position: absolute;
top: 0;
left: 0;
right: 0;
margin-top: 65px;
padding: 0;
visibility: hidden;
opacity: 0;
transition: visibility 0.3192s ease-in-out, opacity 0.3192s ease-in-out;
}
.menu-btn:checked~nav .menu {
visibility: visible;
opacity: 1;
transition: visibility 0.3192s ease-in-out, opacity 0.3192s ease-in-out;
}
.menu li {
border-top: 1px solid #c7c7c7;
padding: 10px 0;
opacity: 0;
transition: 0.5s;
}
.menu a {
color: #222222;
text-decoration: none;
font-weight: 500;
font-size: 0.9rem;
opacity: 0;
transition: 0.5s;
}
.menu-btn:checked~nav .menu a,
.menu-btn:checked~nav .menu li {
opacity: 1;
transition: 0.3192s ease-in-out;
}
/* MAIN CONTENT */
.main-content {
margin-top: 100px;
margin-left: 30px;
margin-right: 30px;
transition: 0.3192s ease-in-out;
}
/* For jquery */
.main-content.open {
margin-top: 195px;
transition: 0.3192s ease-in-out;
}
/* First section */
section.hero {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
}
h2 {
margin: 0;
margin-bottom: 15px;
font-weight: 600;
font-size: 1.5rem;
}
#form input[type="email"] {
width: 100%;
max-width: 300px;
padding: 6px;
font-family: inherit;
font-size: 0.9rem;
border: 1px solid #c7c7c7;
border-radius: 5px;
}
#form input[type="submit"] {
width: 100%;
max-width: 150px;
height: 30px;
margin: 15px 0;
border: 0;
border-radius: 5px;
background-color: #f1c40f;
font-family: inherit;
font-size: 1rem;
font-weight: 500;
}
/* Medium devices (landscape tablets, 768px and up) */
#media only screen and (min-width: 768px) {
header {
display: flex;
align-items: center;
justify-content: space-around;
}
.logo {
width: 60vw;
margin-top: 0;
justify-content: flex-start;
}
.menu-icon {
display: none;
}
nav {
width: 40vw;
margin-top: 0;
}
.menu {
width: 100%;
transform: none;
transition: none;
position: static;
margin: 0;
visibility: visible;
opacity: 1;
display: flex;
justify-content: space-around;
align-items: center;
}
.menu li {
border: none;
padding: 0;
opacity: 1;
transition: none;
}
.menu a {
opacity: 1;
transition: none;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<main id="main">
<header id="header">
<div class="logo">
<img id="header-img" src="https://s3.amazonaws.com/freecodecamp/original_trombones.png" alt="original trombones logo">
</div>
<input type="checkbox" class="menu-btn" id="menu-btn">
<label for="menu-btn" class="menu-icon"><span class="navicon"></span></label>
<nav id="nav-bar">
<ul class="menu">
<li>Feautures</li>
<li>How it Works</li>
<li>Pricing</li>
</ul>
</nav>
</header>
<div class="main-content">
<section class="hero">
<h2>Handcrafted, home-made masterpieces</h2>
<form action="" id="form">
<input type="email" name="email" id="email" placeholder="Enter your email address" required>
<input type="submit" value="GET STARTED" id="submit">
</form>
</section>
</div>
</main>
Here is also a fiddle of the code.
Your issue is in this line:
$('.menu-btn').click();
It's enough you changed it to this:
e.preventDefault();
$('.menu-btn').click();
With the first line you prevent the default action while with the second you initiated the click event for the correct element.
$(document).ready(function() {
// Script to push the section down on menu click
$(".menu-btn").click(function(e) {
e.stopPropagation();
$(".main-content").toggleClass("open");
});
// Script to collapse menu on link click
$(".nav-link").click(function(e) {
e.stopPropagation();
$(".menu-btn").click();
});
//Script to close the menu on window/document click
//With Jquery
$(document).click(function(e) {
if (!$('.menu-btn').is(e.target) // if the target of the click isn't the button...
&&
($(('.menu-btn')).is(":checked"))) {
e.preventDefault();
$('.menu-btn').click();
}
});
});
*,
*::before,
*::after {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
min-width: fit-content;
}
body {
font-family: "Montserrat", sans-serif;
background-color: #eeeeee;
}
header {
width: 100%;
background-color: #eeeeee;
padding: 0 20px;
height: 65px;
position: fixed;
top: 0;
}
.logo {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
margin-top: 15px;
}
#header-img {
width: 100%;
height: 100%;
max-width: 300px;
}
/* Navigation */
nav {
width: 100%;
text-align: center;
}
/* Hamburger menu button */
.menu-btn {
display: none;
}
.menu-icon {
display: inline-block;
position: relative;
top: -42px;
left: -25px;
cursor: pointer;
padding: 24px 14px;
z-index: 1;
}
.navicon {
background-color: #222222;
display: block;
height: 3px;
width: 26px;
position: relative;
transition: 0.3192s ease-in-out;
}
.navicon:before,
.navicon:after {
content: "";
display: block;
height: 100%;
width: 100%;
position: absolute;
background-color: #222222;
transition: 0.3192s ease-in-out;
}
.navicon:before {
top: 9px;
}
.navicon:after {
bottom: 9px;
}
/* Hamburger Menu Animation Start */
.menu-btn:checked~.menu-icon .navicon:before {
transform: rotate(-45deg);
top: 0;
}
.menu-btn:checked~.menu-icon .navicon:after {
transform: rotate(45deg);
bottom: 0;
}
.menu-btn:checked~.menu-icon .navicon {
background: transparent;
transition: 0.3192s ease-in-out;
}
/* Hide blue background on hamburger menu tap on some mobile devices */
.menu-icon,
.menu-btn,
.navicon {
-webkit-tap-highlight-color: transparent;
}
/* Nav items */
.menu {
background-color: #eeeeee;
width: 100%;
height: auto;
list-style-type: none;
position: absolute;
top: 0;
left: 0;
right: 0;
margin-top: 65px;
padding: 0;
visibility: hidden;
opacity: 0;
transition: visibility 0.3192s ease-in-out, opacity 0.3192s ease-in-out;
}
.menu-btn:checked~nav .menu {
visibility: visible;
opacity: 1;
transition: visibility 0.3192s ease-in-out, opacity 0.3192s ease-in-out;
}
.menu li {
border-top: 1px solid #c7c7c7;
padding: 10px 0;
opacity: 0;
transition: 0.5s;
}
.menu a {
color: #222222;
text-decoration: none;
font-weight: 500;
font-size: 0.9rem;
opacity: 0;
transition: 0.5s;
}
.menu-btn:checked~nav .menu a,
.menu-btn:checked~nav .menu li {
opacity: 1;
transition: 0.3192s ease-in-out;
}
/* MAIN CONTENT */
.main-content {
margin-top: 100px;
margin-left: 30px;
margin-right: 30px;
transition: 0.3192s ease-in-out;
}
/* For jquery */
.main-content.open {
margin-top: 195px;
transition: 0.3192s ease-in-out;
}
/* First section */
section.hero {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
}
h2 {
margin: 0;
margin-bottom: 15px;
font-weight: 600;
font-size: 1.5rem;
}
#form input[type="email"] {
width: 100%;
max-width: 300px;
padding: 6px;
font-family: inherit;
font-size: 0.9rem;
border: 1px solid #c7c7c7;
border-radius: 5px;
}
#form input[type="submit"] {
width: 100%;
max-width: 150px;
height: 30px;
margin: 15px 0;
border: 0;
border-radius: 5px;
background-color: #f1c40f;
font-family: inherit;
font-size: 1rem;
font-weight: 500;
}
/* Medium devices (landscape tablets, 768px and up) */
#media only screen and (min-width: 768px) {
header {
display: flex;
align-items: center;
justify-content: space-around;
}
.logo {
width: 60vw;
margin-top: 0;
justify-content: flex-start;
}
.menu-icon {
display: none;
}
nav {
width: 40vw;
margin-top: 0;
}
.menu {
width: 100%;
transform: none;
transition: none;
position: static;
margin: 0;
visibility: visible;
opacity: 1;
display: flex;
justify-content: space-around;
align-items: center;
}
.menu li {
border: none;
padding: 0;
opacity: 1;
transition: none;
}
.menu a {
opacity: 1;
transition: none;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<main id="main">
<header id="header">
<div class="logo">
<img id="header-img" src="https://s3.amazonaws.com/freecodecamp/original_trombones.png" alt="original trombones logo">
</div>
<input type="checkbox" class="menu-btn" id="menu-btn">
<label for="menu-btn" class="menu-icon"><span class="navicon"></span></label>
<nav id="nav-bar">
<ul class="menu">
<li>Feautures</li>
<li>How it Works</li>
<li>Pricing</li>
</ul>
</nav>
</header>
<div class="main-content">
<section class="hero">
<h2>Handcrafted, home-made masterpieces</h2>
<form action="" id="form">
<input type="email" name="email" id="email" placeholder="Enter your email address" required>
<input type="submit" value="GET STARTED" id="submit">
</form>
</section>
</div>
</main>
In my website I want to be able to allow the user to hover over an image and have the image zoomed in by a transition. I've been able to succeed with the implementation of the transition, however, when the image is being zoomed in, it constantly overlaps the other elements. My current layout is ordered in a grid and the container has been given the attribute overflow:hidden.
I tried to assign each element a z-index value of -1 when its being hovered, but the there is a continuous change between the layers which looks horrible. How do I allow each image to be zoomed in without overlapping into any of the other elements?
Here's my jsfiddle: https://jsfiddle.net/Syed213shah/4u0vh5Lb/
body {
background-color: #800020;
}
body, html {
height: 100%;
margin: 0;
}
#box-container {
display: flex;
height: 600px;
width: 75%;
}
.container {
min-height: 500px;
width: 100%;
display: grid;
grid-template-columns: 50% 2fr;
grid-template-rows: 50% 2fr;
overflow: hidden;
position: static;
}
.item1 {
background-image: url('https://pbs.twimg.com/media/D5gQCxCW0AE0skl.jpg');
width: 100%;
height: 200%;
transition: all 0.5s ease-in-out;
position: relative;
}
.item1:hover {
transform: scale(1.1);
z-index: -1;
}
.item2 {
background-image: url('https://media-public.fcbarcelona.com/20157/0/document_thumbnail/20197/172/175/246/32944044/1.0-10/32944044.jpg?t=1475841685000');
grid-column: 2;
grid-row: 2;
width: 100%;
height: 400px;
transition: all 0.5s ease-in-out;
position: relative;
}
.item2:hover {
transform: scale(1.1);
z-index: -1;
}
.item3 {
background-image: url('https://e00-marca.uecdn.es/assets/multimedia/imagenes/2019/10/26/15721062687641.jpg');
grid-column: 2;
grid-row: 1;
width: 100%;
height: 400px;
transition: all 0.5s ease-in-out;
position: relative;
}
.item3:hover {
transform: scale(1.1);
z-index: -1;
}
I think it is more simple to use a pseudo-element or a inner tag (as you want) and scale this element setting its parent (our <a>) with overflow:hidden; to prevent your bug.
In my example I used a pseudoelement. I added these line of code to your CSS (I also commented some lines):
.container a {
overflow: hidden;
}
.container a::after {
height:100%;
width:100%;
content: "";
position: absolute;
transition: all 0.5s ease-in-out;
z-index:-1;
}
.item1::after{
background-image: url('https://pbs.twimg.com/media/D5gQCxCW0AE0skl.jpg');
}
.item2::after{
background-image: url('https://media-public.fcbarcelona.com/20157/0/document_thumbnail/20197/172/175/246/32944044/1.0-10/32944044.jpg?t=1475841685000');
}
.item3::after{
background-image: url('https://e00-marca.uecdn.es/assets/multimedia/imagenes/2019/10/26/15721062687641.jpg');
}
.container a:hover::after{
transform: scale(1.1);
}
I didn't touch your HTML.
body {
background-color: #800020;
}
body, html {
height: 100%;
margin: 0;
}
#box-container {
display: flex;
height: 600px;
width: 75%;
}
/* https://pbs.twimg.com/media/D5gQCxCW0AE0skl.jpg */
/* https://media-public.fcbarcelona.com/20157/0/document_thumbnail/20197/172/175/246/32944044/1.0-10/32944044.jpg?t=1475841685000 */
/* https://e00-marca.uecdn.es/assets/multimedia/imagenes/2019/10/26/15721062687641.jpg */
.container {
min-height: 500px;
width: 100%;
display: grid;
grid-template-columns: 50% 2fr;
grid-template-rows: 50% 2fr;
overflow: hidden;
position: static;
}
.item1 {
/*background-image: url('https://pbs.twimg.com/media/D5gQCxCW0AE0skl.jpg');*/
width: 100%;
height: 200%;
/*transition: all 0.5s ease-in-out;*/
position: relative;
}
/*.item1:hover {
transform: scale(1.1);
z-index: -1;
}*/
.item2 {
/*background-image: url('https://media-public.fcbarcelona.com/20157/0/document_thumbnail/20197/172/175/246/32944044/1.0-10/32944044.jpg?t=1475841685000');*/
grid-column: 2;
grid-row: 2;
width: 100%;
height: 400px;
/*transition: all 0.5s ease-in-out; */
position: relative;
}
/*.item2:hover {
transform: scale(1.1);
z-index: -1;
}*/
.item3 {
/*background-image: url('https://e00-marca.uecdn.es/assets/multimedia/imagenes/2019/10/26/15721062687641.jpg');*/
grid-column: 2;
grid-row: 1;
width: 100%;
height: 400px;
/*transition: all 0.5s ease-in-out; */
position: relative;
}
/* -------------------------- */
/* I added these lines of code */
/* -------------------------- */
.container a {
overflow: hidden;
}
.container a::after {
height:100%;
width:100%;
content: "";
position: absolute;
transition: all 0.5s ease-in-out;
z-index:-1;
}
.item1::after{
background-image: url('https://pbs.twimg.com/media/D5gQCxCW0AE0skl.jpg');
/*to set a background without repetition and always horizontally center you could use also this syntaxt:
background: url('https://pbs.twimg.com/media/D5gQCxCW0AE0skl.jpg') 50% top no-repeat transparent;
*/
}
.item2::after{
background-image: url('https://media-public.fcbarcelona.com/20157/0/document_thumbnail/20197/172/175/246/32944044/1.0-10/32944044.jpg?t=1475841685000');
}
.item3::after{
background-image: url('https://e00-marca.uecdn.es/assets/multimedia/imagenes/2019/10/26/15721062687641.jpg');
}
.container a:hover::after{
transform: scale(1.1);
}
/* -------------------------- */
/* I added these line of code */
/* -------------------------- */
.item1 h2 {
font-size: 50px;
position: absolute;
font-family: Staatliches;
text-align: center;
color: white;
text-decoration: none;
padding: 500px 70px;
}
.item2 h2 {
font-size: 50px;
position: absolute;
font-family: Staatliches;
text-align: center;
color: white;
text-decoration: none;
padding: 200px 200px;
}
.item3 h2 {
font-size: 50px;
position: absolute;
font-family: Staatliches;
text-align: center;
color: white;
text-decoration: none;
padding: 185px 200px;
}
.full-height {
height: 100%;
}
.bottom-height {
height: 100%;
}
h1 {
font-size: 50px;
font-family: Staatliches;
text-align: center;
color: #002a58;
}
#navbar {
background-color: #800020;
position: fixed;
top: -30px;
width: 100%;
transition: top 0.3s;
}
#navbar ul {
height: -30px;
padding: 10px 0 10px 40px;
width: 100%;
}
#navbar li{
float: left;
line-height: 20px;
margin-right: 30px;
padding: 10px 3px;
position: relative;
list-style-type: none;
}
#navbar li a {
font-family: Staatliches;
text-decoration: none;
color: rgb(13, 11, 134);
}
#navbar li a:hover {
background-color: #ddd;
color: black;
}
<body>
<div class="full-height">
<script src="script.js"></script>
<div class="container">
<a class="item1" href="https://www.bbc.co.uk/sport/football" style="text-decoration: none;" >
<h2> Europe's biggest stadium </h2>
</a>
<a class="item2" href="https://www.fcbarcelona.com/en/" style="text-decoration: none;" >
<h2>European Success</h2>
</a>
<a class="item3" href="https://www.fcbarcelona.com/en/football/first-team/news" style="text-decoration: none;" >
<h2>Current Squad</h2>
</a>
</div>
<div id="navbar">
<ul>
<li>Home</li>
<li>Squad</li>
<li>Contact</li>
<li>About</li>
<a2><a>Created by Awais</a></a2>
</ul>
</div>
<h1>FC Barcelona</h1>
</div>
<div class="bottom-height">
</div>
</body>
instead of transform: scale on your images, perhaps using the background-size and background position might give the result you seek with a bit more control of the actual cropping you are already using.
the jsfiddle attached modifies your code with such an example. I did leave the transform scale in place for the text overlay. also note the image containers need a overflow:hidden in order to prevent hover interaction between cells.
here is your css modified accordingly;
body {
background-color: #800020;
}
body, html {
height: 100%;
margin: 0;
}
#box-container {
display: flex;
height: 600px;
width: 75%;
}
.container {
min-height: 500px;
width: 100%;
display: grid;
grid-template-columns: 50% 2fr;
grid-template-rows: 50% 2fr;
overflow: hidden;
position: static;
}
.item1 {
background-image: url('https://pbs.twimg.com/media/D5gQCxCW0AE0skl.jpg');
background-position: 0% 50%;
background-size:200%;
width: 100%;
height: 200%;
transition: all 0.5s ease-in-out;
position: relative;
overflow: hidden;
}
.item1:hover {
background-size:220%;
background-position: 5% 50%;
}
.item2 {
background-image: url('https://media-public.fcbarcelona.com/20157/0/document_thumbnail/20197/172/175/246/32944044/1.0-10/32944044.jpg?t=1475841685000');
background-position: 0% 50%;
background-size:165%;
grid-column: 2;
grid-row: 2;
width: 100%;
height: 400px;
transition: all 0.5s ease-in-out;
position: relative;
overflow: hidden;
}
.item2:hover {
background-position: 5% 50%;
background-size:180%;
}
.item3 {
background-image: url('https://e00-marca.uecdn.es/assets/multimedia/imagenes/2019/10/26/15721062687641.jpg');
background-position: 0% 15%;
background-size:175%;
grid-column: 2;
grid-row: 1;
width: 100%;
height: 400px;
transition: all 0.5s ease-in-out;
position: relative;
overflow: hidden;
}
.item3:hover {
background-position: 5% 15%;
background-size:195%;
}
.item1 h2 {
font-size: 50px;
position: absolute;
font-family: Staatliches;
text-align: center;
color: white;
text-decoration: none;
padding: 500px 70px;
transform: scale(1);
transition: all 0.5s ease-in-out;
}
.item2 h2 {
font-size: 50px;
position: absolute;
font-family: Staatliches;
text-align: center;
color: white;
text-decoration: none;
padding: 200px 200px;
transform: scale(1);
transition: all 0.5s ease-in-out;
}
.item3 h2 {
font-size: 50px;
position: absolute;
font-family: Staatliches;
text-align: center;
color: white;
text-decoration: none;
padding: 185px 200px;
transform: scale(1);
transition: all 0.5s ease-in-out;
}
.item1:hover h2,
.item2:hover h2,
.item3:hover h2 {
transform: scale(1.1);
}
.full-height {
height: 100%;
}
.bottom-height {
height: 100%;
}
h1 {
font-size: 50px;
font-family: Staatliches;
text-align: center;
color: #002a58;
}
#navbar {
background-color: #800020;
position: fixed;
top: -30px;
width: 100%;
transition: top 0.3s;
}
#navbar ul {
height: -30px;
padding: 10px 0 10px 40px;
width: 100%;
}
#navbar li{
float: left;
line-height: 20px;
margin-right: 30px;
padding: 10px 3px;
position: relative;
list-style-type: none;
}
#navbar li a {
font-family: Staatliches;
text-decoration: none;
color: rgb(13, 11, 134);
}
#navbar li a:hover {
background-color: #ddd;
color: black;
}
#navbar .a2{
float: right;
line-height: 20px;
margin-right: 50px;
padding: 10px 3px;
position: relative;
list-style-type: none;
}
#navbar .a2 a {
font-family: Staatliches;
text-decoration: none;
color: rgb(13, 11, 134);
}
https://jsfiddle.net/w9n6ajq1/
This question already has answers here:
How do I detect a click outside an element?
(91 answers)
Closed 6 years ago.
I am writing menu for responsive website, but I am stunned in one moment - hide menu when outclick...
I would really appreciate any help with my bugged jQuery :) - link to jsfiddle
function hamburgerClick()
{
$('#hamburgerMenu').click(function(e) // (hide || show) menu by clicking "hamburgerMenu" icon
{
e.preventDefault();
if( $('#hamburgerMenu').hasClass('is-active') )
{
$('#hamburgerMenu').removeClass('is-active');
$('#menu').removeClass('is-active');
}
else
{
$('#hamburgerMenu').addClass('is-active');
$('#menu').addClass('is-active');
}
});
}
function hideMenuOutclick() /* does not work */
{
if( $('#hamburgerMenu').hasClass('is-active') )
{
$(document).click(function(e)
{
if( ($(e.target).closest('#menu').length!==0) ||
($(e.target).closest('#hamburgerMenu').length!==0) )
{
$('#hamburgerMenu').removeClass('is-active');
$('#menu').removeClass('is-active');
}
});
}
}
function beginJS()
{
hamburgerClick();
hideMenuOutclick();
/* few more scripts */
}
window.onload = beginJS;
.bg-red
{
background-color: #e32624;
}
/********** pure header **********/
#header
{
width: 100%;
height: 56px;
display: block;
position: fixed;
}
/********** fixing Comission **********/
.fixingComission
{
display: block;
float: right;
position: relative;
width: auto;
height: 56px;
appearance: none;
box-shadow: none;
border-radius: none;
background-color: #e32624;
transition: background 0.3s;
}
.fixingComission a
{
font-size: 26px;
color: #ffffff;
padding: 10px 12px;
}
/********** hamburger button **********/
#hamburgerMenu
{
display: block;
float: left;
position: relative;
overflow: hidden;
width: 56px;
height: 56px;
font-size: 0;
text-indent: -9999px;
appearance: none;
box-shadow: none;
border-radius: none;
cursor: pointer;
background-color: #e32624;
transition: background 0.3s;
}
#hamburgerMenu:focus
{
outline: none;
}
/********** hamburger button span **********/
#hamburgerMenu span
{
display: block;
position: absolute;
top: 25px;
left: 12px;
right: 12px;
height: 5px;
background: white;
transition: transform 0.3s;
}
#hamburgerMenu span::before,
#hamburgerMenu span::after
{
position: absolute;
display: block;
left: 0;
width: 100%;
height: 5px;
background-color: #fff;
content: "";
}
#hamburgerMenu span::before
{
top: -14px;
transform-origin: top right;
transition: transform 0.3s, width 0.3s, top 0.3s;
}
#hamburgerMenu span::after
{
bottom: -14px;
transform-origin: bottom right;
transition: transform 0.3s, width 0.3s, bottom 0.3s;
}
#hamburgerMenu span:focus
{
outline: none;
}
/********** hamburger button active - class added onclick by JS **********/
#hamburgerMenu.is-active
{
background-color: #bc1a18;
}
/********** hamburger button span active **********/
#hamburgerMenu.is-active span
{
transform: rotate(180deg);
}
#hamburgerMenu.is-active span::before,
#hamburgerMenu.is-active span::after
{
width: 50%;
}
#hamburgerMenu.is-active span::before
{
top: 0;
transform: translateX(22px) translateY(2px) rotate(45deg);
}
#hamburgerMenu.is-active span::after
{
bottom: 0;
transform: translateX(22px) translateY(-2px) rotate(-45deg);
}
/********** navigation **********/
#menu
{
display: block;
position: fixed;
z-index: 1000;
background-color: #003e78;
overflow: hidden;
-webknit-overflow-scroll: touch; /* for mobile safari */
top: 56px;
width: 65%;
height: 100%;
left: -65%;
transition-property: opacity, left;
transition-duration: 0.3s, 0.5s;
}
#menu.is-active
{
left: 0;
}
#menu ul
{
overflow: auto;
width: 100%;
height: 100%;
padding-right: 0; /* exact value is given by JS to hide scrollbar */
}
#menu ul::-webkit-scrollbar
{
display: none;
}
#menu ul li
{
display: inline-block;
width: 100%;
height: 52px;
}
#menu ul li.current,
#menu ul li:hover,
#menu ul li:active
{
background-color: #0066c5;
}
#menu ul li a
{
display: block;
height: 30px;
width: 100%;
color: #ffffff;
font-size: 1em;
padding: 12px 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<header id="header" class="bg-red">
<button class="fixingComission">
Zleć naprawę
</button>
<button id="hamburgerMenu"><span>toggle menu</span></button>
<nav id="menu">
<ul>
<li class="current">Start</li>
<li>O nas</li>
<li>Serwis</li>
<li>W sumie to nie wiem</li>
<li>Kontakt</li>
<li>Zleć naprawę</li>
</ul>
</nav>
</header>
//hamburgerClick is working, but hideMenuOutclick is not.
I know, that on jsfiddle project isn't working, but it works on localhost and srv with implemented jQuery v1.10.2
I would be really grateful to tip about scrolling in CSS3:
Why despite "overflow: auto" '$("#menu").onMouseOver' is still scrolling whole page? Is it possible to force scrolling some element (even if it is full-viewed in computer screen), not whole page?
EDIT: Hiding menu is done with click event (which will be matched for invalids and it won't be click - really thanks to point this out!) Now only thing is this scrolling :)
For the jsfiddle bug the problem is in this line:
if( $('#hamburgerMenu').hasClass('is-active') ) {
If the menu is not active on document load the event handler never be attached.
The updated jsfiddle: the errors here are: jquery missing, load type: wrap in the head.
I assume you want to close the menu when clicking outside the menu.
For the second part of your question I figured out the problem is related to the height of the #menu: change it from 100% to 50%.
The snippet:
function hamburgerClick()
{
$('#hamburgerMenu').click(function(e) // (hide || show) menu by clicking "hamburgerMenu" icon
{
e.preventDefault();
if( $('#hamburgerMenu').hasClass('is-active') )
{
$('#hamburgerMenu').removeClass('is-active');
$('#menu').removeClass('is-active');
}
else
{
$('#hamburgerMenu').addClass('is-active');
$('#menu').addClass('is-active');
}
});
}
function hideMenuOutclick() /* does not work */
{
$(document).click(function(e)
{
if( ($(e.target).closest('#menu').length==0) &&
($(e.target).closest('#hamburgerMenu').length==0) )
{
if( $('#hamburgerMenu').hasClass('is-active') ) {
$('#hamburgerMenu').removeClass('is-active');
$('#menu').removeClass('is-active');
}
}
});
}
function beginJS()
{
hamburgerClick();
hideMenuOutclick();
/* few more scripts */
}
window.onload = beginJS;
.bg-red
{
background-color: #e32624;
}
/********** pure header **********/
#header
{
width: 100%;
height: 56px;
display: block;
position: fixed;
}
/********** fixing Comission **********/
.fixingComission
{
display: block;
float: right;
position: relative;
width: auto;
height: 56px;
appearance: none;
box-shadow: none;
border-radius: none;
background-color: #e32624;
transition: background 0.3s;
}
.fixingComission a
{
font-size: 26px;
color: #ffffff;
padding: 10px 12px;
}
/********** hamburger button **********/
#hamburgerMenu
{
display: block;
float: left;
position: relative;
overflow: hidden;
width: 56px;
height: 56px;
font-size: 0;
text-indent: -9999px;
appearance: none;
box-shadow: none;
border-radius: none;
cursor: pointer;
background-color: #e32624;
transition: background 0.3s;
}
#hamburgerMenu:focus
{
outline: none;
}
/********** hamburger button span **********/
#hamburgerMenu span
{
display: block;
position: absolute;
top: 25px;
left: 12px;
right: 12px;
height: 5px;
background: white;
transition: transform 0.3s;
}
#hamburgerMenu span::before,
#hamburgerMenu span::after
{
position: absolute;
display: block;
left: 0;
width: 100%;
height: 5px;
background-color: #fff;
content: "";
}
#hamburgerMenu span::before
{
top: -14px;
transform-origin: top right;
transition: transform 0.3s, width 0.3s, top 0.3s;
}
#hamburgerMenu span::after
{
bottom: -14px;
transform-origin: bottom right;
transition: transform 0.3s, width 0.3s, bottom 0.3s;
}
#hamburgerMenu span:focus
{
outline: none;
}
/********** hamburger button active - class added onclick by JS **********/
#hamburgerMenu.is-active
{
background-color: #bc1a18;
}
/********** hamburger button span active **********/
#hamburgerMenu.is-active span
{
transform: rotate(180deg);
}
#hamburgerMenu.is-active span::before,
#hamburgerMenu.is-active span::after
{
width: 50%;
}
#hamburgerMenu.is-active span::before
{
top: 0;
transform: translateX(22px) translateY(2px) rotate(45deg);
}
#hamburgerMenu.is-active span::after
{
bottom: 0;
transform: translateX(22px) translateY(-2px) rotate(-45deg);
}
/********** navigation **********/
#menu
{
display: block;
position: fixed;
z-index: 1000;
background-color: #003e78;
overflow: hidden;
-webknit-overflow-scroll: touch; /* for mobile safari */
top: 56px;
width: 65%;
height: 50%;
left: -65%;
transition-property: opacity, left;
transition-duration: 0.3s, 0.5s;
}
#menu.is-active
{
left: 0;
}
#menu ul
{
overflow: auto;
width: 100%;
height: 100%;
padding-right: 0; /* exact value is given by JS to hide scrollbar */
}
#menu ul::-webkit-scrollbar
{
display: none;
}
#menu ul li
{
display: inline-block;
width: 100%;
height: 52px;
}
#menu ul li.current,
#menu ul li:hover,
#menu ul li:active
{
background-color: #0066c5;
}
#menu ul li a
{
display: block;
height: 30px;
width: 100%;
color: #ffffff;
font-size: 1em;
padding: 12px 0;
}
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<header id="header" class="bg-red">
<button class="fixingComission">
Zleć naprawę
</button>
<button id="hamburgerMenu"><span>toggle menu</span></button>
<nav id="menu">
<ul>
<li class="current">Start</li>
<li>O nas</li>
<li>Serwis</li>
<li>W sumie to nie wiem</li>
<li>Kontakt</li>
<li>Zleć naprawę</li>
</ul>
</nav>
</header>
I have a CSS animation effect that's difficult to implement due to layering problems. See the snippet below:
var toggle = document.getElementById('toggle');
function toggleF() {
'use strict';
document.querySelector('nav').classList.add('fuzzyState');
}
toggle.addEventListener('click', toggleF);
body {
height: 90%;
color: #222;
text-align: center overflow:hidden;
}
button {
outline: 0;
cursor: pointer
}
#toggle {
float: left;
width: 38px;
height: 38px;
padding: 5px;
margin: auto;
background: #fff;
color: #666;
border: 0;
font-size: 150%
}
#toggle:hover {
background: #222;
color: #eee;
user-select: none;
-webkit-user-select: none
}
#toggle:active {
background: #022;
color: #fff
}
nav ul:after {
content"";
display: block;
clear: both
}
nav ul {
height: 150px;
margin: 0;
padding: 0;
font-size: 150%
}
nav li {
width: 140px;
height: 140px;
margin: 5px;
float: left;
list-style: none;
user-select: none;
-webkit-user-select: none
}
nav button {
display: block;
position: relative;
top: 50%;
width: 100%;
height: 100%;
background: transparent;
border: 0;
text-transform: uppercase;
transform: translateY(-50%)
}
nav button:hover {
background: #022;
color: #eee
}
nav button:active {
background: #033;
color: #fff
}
ul hr {
position: relative;
top: 50%;
width: 1px;
height: 90px;
margin: 10px;
background: #eee;
border: 0;
float: left;
transform: translateY(-50%);
z-index: 2
}
nav.fuzzyState #dos {
transform: translateX(230px)
}
nav.fuzzyState #uno {
transform: translateX(400px);
-webkit-filter: blur(1px)
}
nav.fuzzyState #tres {
/*transform:translateX(-230px)*/
}
nav #tres {
position: relative;
z-index: 1
}
#leftNavMask {
background: #fff;
position: absolute;
top: 15%;
right: 0;
left: 356px;
width: 200px;
height: 190px;
text-align: justify;
transform: translateY(-50%);
}
#rightNavMask {
background: #fff;
position: absolute;
top: 15%;
right: 0;
left: 156px;
width: 200px;
height: 190px;
text-align: justify;
transform: translateY(-50%);
z-index: -1
}
#dos,
#tres {
transition: transform 0.7s ease-in-out
}
#uno {
transition: transform 1s ease-in-out, -webkit-filter 1s ease-in-out;
}
<button id="toggle">+</button>
<nav>
<ul>
<li id="uno"><button>uno</button></li>
<li id="dos"><button>dos</button></li>
<hr>
<li id="tres"><button>tres</button></li>
<div id="leftNavMask"></div>
<div id="rightNavMask"></div>
</ul>
</nav>
After the + button is clicked my goal is to make the tres button slide to the left while being masked just like the uno and dos buttons, except in the opposite direction. It seems impossible to pull off because whatever z-index I give any elements there's no way to have the left mask on top of the correct elements while simultaneously having the right mask do its job. Are there any simple ways to do this without jQuery? Thanks.
To clarify: The uno and dos buttons are currently going under a div that is colored to match the background. I need the tres button to slide left under a second div that is somehow on top of the tres button to mask it but also below the uno and dos buttons so they aren't blocked at the beginning.
Long time since this question was asked, therefore, most probably you have found a solution already. But just in case, here you have a possible approach to what you wanted to achieve.
Instead of using absolute positioned divs with the same color of the background to cover the animated li elements, why don't use an overflow hidden property in the ul container? If you do this, the ul will act as a "mask" and when the li elements get animated outside the ul, they will be automatically "hidden". Take a look at your snippet already modified using this approach (I have used two ul elements to animate the li elements separately):
I saw that you placed an hr (and two div) inside the ul element and a ul should only contain li elements. For this solution, I used a pseudo-element to mimic the vertical line.
var toggle = document.getElementById('toggle');
function toggleF() {
document.querySelector('nav').classList.toggle('fuzzyState');
}
toggle.addEventListener('click', toggleF);
body {
color: #222;
}
button {
cursor: pointer;
outline: 0;
}
#toggle {
background: #fff;
border: 0;
color: #666;
float: left;
font-size: 150%;
height: 38px;
margin: auto;
padding: 5px;
width: 38px;
}
#toggle:hover {
background: #222;
color: #eee;
user-select: none;
}
#toggle:active {
background: #022;
color: #fff
}
nav ul {
display: inline-block;
font-size: 150%;
margin: 0;
overflow: hidden;
padding: 0;
position: relative;
}
nav ul.left::after {
content: "";
display: block;
border-right: 1px solid #eee;
height: 90px;
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
}
nav li {
display: inline-block;
height: 140px;
list-style: none;
margin: 5px;
user-select: none;
transition: transform 0.7s ease-in-out;
width: 140px;
}
nav button {
background: transparent;
border: 0;
display: block;
height: 100%;
position: relative;
text-transform: uppercase;
top: 50%;
transform: translateY(-50%);
width: 100%;
}
nav button:hover {
background: #022;
color: #eee;
}
nav button:active {
background: #033;
color: #fff;
}
nav.fuzzyState ul > li {
pointer-events: none;
}
nav.fuzzyState ul.left > li {
transform: translateX(200%);
}
nav.fuzzyState ul.right > li {
transform: translateX(-100%);
}
<button id="toggle">+</button>
<nav>
<ul class="left">
<li><button>uno</button></li>
<li><button>dos</button></li>
</ul>
<ul class="right">
<li><button>tres</button></li>
</ul>
</nav>
I've been messing around with this mobile friendly navigation menu, and for some reason my menu will open (JS IF statement), but not close (JS ELSE statement. So I'm stuck as to why it is opening but not closing?
P.S. I'm new to JavaScript, so it might be something simple that I over looked, thanks!
Here's the code I'm working with:
function myFunction(x) {
x.classList.toggle("change");
}
function navChange() {
var x = document.getElementById("myNav").style.height
if (x = "0%"){
document.getElementById("myNav").style.height = "100%";
} else {
document.getElementById("myNav").style.height = "0%";
}
}
.overlay {
height: 0%;
width: 100%;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0, 0.9);
overflow-y: hidden;
transition: 0.5s;
}
.overlay-content {
position: relative;
top: 25%;
width: 100%;
text-align: center;
margin-top: 30px;
}
.overlay a {
padding: 8px;
text-decoration: none;
font-size: 36px;
color: #818181;
display: block;
transition: 0.3s;
}
#media screen and (max-height: 450px) {
.overlay {overflow-y: auto;}
.overlay a {font-size: 20px}
.closebtn {
font-size: 40px !important;
top: 15px;
right: 35px;
}
}
.container {
position: absolute;
top: 25px;
left: 25px;
display: inline-block;
cursor: pointer;
margin: 20px;
z-index: 12;
}
.bar1, .bar2 {
width: 35px;
height: 4px;
background-color: #333;
margin: 6px 0;
transition: 0.4s;
}
.change .bar1 {
transform: rotate(-45deg) translate(0px, 0px) ;
background-color: gray;
}
.change .bar2 {
transform: translate(1px, -10px) rotate(45deg);
background-color: gray;
}
<div id="myNav" class="overlay">
<div class="overlay-content">
About
Services
Clients
Contact
</div>
</div>
<div class="container" onclick="myFunction(this), navChange()">
<div class="bar1"></div>
<div class="bar2"></div>
</div>
Thanks for your time and energy!
The reasoning for the errors that I see is for one you are doing assignment in your conditions.
a = 15;
b = 10;
if(a = b) alert("hello world");
a now is now 10, because we used assignment instead of testing for equality which would look like.
if( a == b)
Also you are testing the style property which looks like you are setting through CSS and style.height will not return what you are looking for. You will need to test PX or what have you.
var height = window.getComputedStyle(document.getElementById("element")).height;
var height = parseInt(height,10);
if( height > 1510 ) {
//do whatever
}
Everything EasyBB said was true, but here's an example on how it can be done cleanly:
function myFunction(x) {
x.classList.toggle("change");
}
function navChange() {
var x = document.getElementById("myNav").clientHeight; // Use clientHeight to get the actual height, ignoring style rules. //.style.height
if (x == "0"){ // == to compare, = here would set the value, so x would always equal 0.
document.getElementById("myNav").style.height = "100%";
} else {
document.getElementById("myNav").style.height = "0"; //No reason to use percentage here, as 0% =0px.
}
}
.overlay {
height: 0%;
width: 100%;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0, 0.9);
overflow-y: hidden;
transition: 0.5s;
}
.overlay-content {
position: relative;
top: 25%;
width: 100%;
text-align: center;
margin-top: 30px;
}
.overlay a {
padding: 8px;
text-decoration: none;
font-size: 36px;
color: #818181;
display: block;
transition: 0.3s;
}
#media screen and (max-height: 450px) {
.overlay {overflow-y: auto;}
.overlay a {font-size: 20px}
.closebtn {
font-size: 40px !important;
top: 15px;
right: 35px;
}
}
.container {
position: absolute;
top: 25px;
left: 25px;
display: inline-block;
cursor: pointer;
margin: 20px;
z-index: 12;
}
.bar1, .bar2 {
width: 35px;
height: 4px;
background-color: #333;
margin: 6px 0;
transition: 0.4s;
}
.change .bar1 {
transform: rotate(-45deg) translate(0px, 0px) ;
background-color: gray;
}
.change .bar2 {
transform: translate(1px, -10px) rotate(45deg);
background-color: gray;
}
<div id="myNav" class="overlay">
<div class="overlay-content">
About
Services
Clients
Contact
</div>
</div>
<div class="container" onclick="myFunction(this), navChange()">
<div class="bar1"></div>
<div class="bar2"></div>
</div>