Reputation: 111
I'm trying to create a menu and I want the dropdowns to be open on click and push the menu content down not like on hover where the menu content is moving while hovering also I want to close menu not only on hamburger click but after clicking on any point of website. Is it possible? The main problems are: 1. Menu content won't open on click only on hover. 2. Menu don't close after click on any point of website. 3. The dropdowns push content up and down.
$(document).ready(function() {
$('.dropdown').click(function() {
$('.subs').slideToggle();
});
});
/* MENU STYLES */
.menu-wrap {
position: fixed;
top: 0;
right: 0;
z-index: 1;
}
.menu-wrap .toggler {
position: absolute;
top: 0;
right: 0;
z-index: 2;
cursor: pointer;
width: 50px;
height: 50px;
opacity: 0;
}
.menu-wrap .hamburger {
position: absolute;
top: 0;
right: 0;
z-index: 1;
width: 60px;
height: 60px;
padding: 1rem;
background: rgba(13,110,139,0.75);
display: flex;
align-items: center;
justify-content: center;
}
/* Hamburger Line */
.menu-wrap .hamburger > div {
position: relative;
flex: none;
width: 100%;
height: 2px;
background: #fff;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.4s ease;
}
/* Hamburger Lines - Top & Bottom */
.menu-wrap .hamburger > div::before,
.menu-wrap .hamburger > div::after {
content: '';
position: absolute;
z-index: 1;
top: -10px;
width: 100%;
height: 2px;
background: inherit;
}
/* Moves Line Down */
.menu-wrap .hamburger > div::after {
top: 10px;
}
/* Toggler Animation */
.menu-wrap .toggler:checked + .hamburger > div {
transform: rotate(135deg);
}
/* Turns Lines Into X */
.menu-wrap .toggler:checked + .hamburger > div:before,
.menu-wrap .toggler:checked + .hamburger > div:after {
top: 0;
transform: rotate(90deg);
}
/* Rotate on hower when checked */
.menu-wrap .toggler:checked:hover + .hamburger > div {
transform: rotate(225deg);
}
/* Show Menu */
.menu-wrap .toggler:checked ~ .menu {
visibility: visible;
}
.menu-wrap .toggler:checked ~ .menu > div {
transform: scale(1);
transition-duration: 0.75s;
}
.menu-wrap .toggler:checked ~ .menu > div > div {
opacity: 1;
transition: opacity 0.4s ease 0.4s;
}
.menu-wrap .menu {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
visibility: hidden;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
.menu-wrap .menu ul {
padding: 0;
}
.menu-wrap .menu > div {
background: rgba(24,39,51,0.85);
border-radius: 50%;
width: 200vw;
height: 200vw;
display: flex;
flex: none;
align-items: center;
justify-content: center;
transform: scale(0);
transition: all 0.4s ease;
}
.menu-wrap .menu > div > div {
text-align: center;
max-width: 90vw;
max-height: 100vh;
opacity: 0;
transition: opacity 0.4s ease;
}
.menu-wrap .menu > div > div > ul > li {
list-style: none;
color: #fff;
font-size: 1.5rem;
padding: 1rem;
}
.menu-wrap .menu > div > div > ul > li > a {
color: inherit;
text-decoration: none;
transition: color 0.4s ease;
}
.subs li {
list-style: none;
}
.subs li a {
color: inherit;
text-decoration: none;
transition: color 0.4s ease;
}
ul li ul {
visibility: hidden;
opacity: 0;
position: absolute;
transition: all 0.5s ease;
margin-top: 1rem;
left: 0;
display: none;
}
/* ul li:hover > ul,
ul li ul:hover {
visibility: visible;
opacity: 1;
display: block;
z-index: 1;
width: 100%;
position: unset;
} */
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<nav>
<div class="menu-wrap">
<input type="checkbox" class="toggler">
<div class="hamburger">
<div class="">
</div>
</div>
<div class="menu">
<div>
<div>
<ul>
<li><a href="#">Home</a></li>
<li class="dropdown"><a href="#">About</a>
<ul class="subs">
<li><a href="#">About me</a></li>
<li><a href="#">Product</a></li>
</ul>
</li>
<li class="dropdown"><a href="#">Product</a>
<ul class="subs">
<li><a href="#">Product1</a></li>
<li><a href="#">Product2</a></li>
<li><a href="#">Product3</a></li>
</ul>
</li>
<li><a href="#">Support</a></li>
<li><a href="#">Contact</a></li>
</ul>
</div>
</div>
</div>
</div>
</nav>
Upvotes: 0
Views: 1577
Reputation: 1578
UPDATE: No code change, only I have added some relevant comments in the HTML/CSS/jQuery code explaining the edits to existing code as well as logic behind new code added.
Here is a complete solution, I had to edit your code a little bit since your toggle mecanism is CSS-based and we need JS or jQuery to manage the stuff you requested. You will also some minor adjustments to make to your CSS & layout but reading your code I am pretty sure you will be able to. Let me know if that works.
$('.page-wrapper').click(function(evt){ //test mouse click if true close menu and also revert the toggler checkbox to unchecked since you are using CSS to manage the toggle of the menu //
if($(evt.target).closest('#menu-to-close-on-click').length)
return;
$('#menu-to-close-on-click').css('display','none');
$( ".toggler" ).prop( "checked", false );
});
$(document).ready(function() {
$('.dropdown1').click(function() { //when .dropdown1 is clicked, show .subs1 and set .subs2 display to none //
$('.subs1').slideToggle();
$('.subs2').css('display','none');
});
$('.dropdown2').click(function() { //same logic, inveretd for .dropdown2
$('.subs1').css('display','none');
$('.subs2').slideToggle();
});
$('.toggler').click(function() { //function to display the menu when clicking on the toggler even if display was set to none via mechanism on line 4 //
$('.menu').css('display','flex');
});
});
/* MENU STYLES */
.menu-wrap {
top: 0; /* removed absolute positioning */
left: 0;
z-index: 1;
}
.menu-wrap .toggler {
position: absolute;
top: 0;
right: 0;
z-index: 2;
cursor: pointer;
width: 50px;
height: 50px;
opacity: 0;
}
.menu-wrap .hamburger {
position: absolute;
top: 0;
right: 0;
z-index: 1;
width: 60px;
height: 60px;
padding: 1rem;
background: rgba(13,110,139,0.75);
display: flex;
align-items: center;
justify-content: center;
}
/* Hamburger Line */
.menu-wrap .hamburger > div {
position: relative;
flex: none;
width: 100%;
height: 2px;
background: #fff;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.4s ease;
}
/* Hamburger Lines - Top & Bottom */
.menu-wrap .hamburger > div::before,
.menu-wrap .hamburger > div::after {
content: '';
position: absolute;
z-index: 1;
top: -10px;
width: 100%;
height: 2px;
background: inherit;
}
/* Moves Line Down */
.menu-wrap .hamburger > div::after {
top: 10px;
}
/* Toggler Animation */
.menu-wrap .toggler:checked + .hamburger > div {
transform: rotate(135deg);
}
/* Turns Lines Into X */
.menu-wrap .toggler:checked + .hamburger > div:before,
.menu-wrap .toggler:checked + .hamburger > div:after {
top: 0;
transform: rotate(90deg);
}
/* Rotate on hower when checked */
.menu-wrap .toggler:checked:hover + .hamburger > div {
transform: rotate(225deg);
}
/* Show Menu */
.menu-wrap .toggler:checked ~ .menu {
display:flex;
}
.menu-wrap .toggler:checked ~ .menu > div {
transform: scale(1);
transition-duration: 0.75s;
}
.menu-wrap .toggler:checked ~ .menu > div > div {
opacity: 1;
transition: opacity 0.4s ease 0.4s;
}
.menu-wrap .menu {
position: absolute; /* changed positioning from 'fixed' to 'absolute' */
top: 0;
left: 0;
width: 100%;
height: 100%;
display:none;
align-items: center;
justify-content: center;
}
.menu-wrap .menu ul {
padding: 0;
}
.menu-wrap .menu > div {
background: rgba(24,39,51,0.85);
width: 100vh;
height: 100vw;
display: flex;
flex: none;
align-items: center;
justify-content: center;
transform: scale(0);
transition: all 0.4s ease;
}
.menu-wrap .menu > div > div {
text-align: center;
max-width: 110vw;
max-height: 100vh;
transition: opacity 0.4s ease;
}
.menu-wrap .menu > div > div > ul > li {
list-style: none;
color: #fff;
font-size: 1.5rem;
padding: 1rem;
}
.menu-wrap .menu > div > div > ul > li > a {
color: inherit;
text-decoration: none;
transition: color 0.4s ease;
}
.subs li {
list-style: none;
}
.subs li a {
color: inherit;
text-decoration: none;
transition: color 0.4s ease;
}
.subs {
transition: all 0.5s ease;
margin-top: 1rem;
display:none; /* now using display:none instead of visibility:hidden */
}
.sometxt {
margin-top:calc(100vh + 150px); /* a top margin equal to one full vertical viewport + 150px to be able to click somwhere else than in the menu (which, clicking in the menu, will NOT trigger the close of the menu) */
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<div class="menu-wrap">
<input type="checkbox" class="toggler">
<div class="hamburger">
<div class=""></div>
</div>
<div id="menu-to-close-on-click" class="menu"> <!-- added an ID to the element to close when clicking anywhere on the page as well as toggle() when the hamburger icon is clicked (open/close menu) -->
<div>
<div>
<ul>
<li>
<a href="#">Home</a>
</li>
<li>
<a class="dropdown1" href="#">About</a> <!-- i found it useful to 1) add a separate class for each dropdown (dropdown1 and dropdown2) to make it easier to manage with our jQuery code and 2) I placed the class on the <a> link element instead of the <ul> element since the <a> element is the one we click on to trigger the dropdown to open and reveal it's content -->
<ul class="subs subs1"> <!-- I kept your '.subs' class for styling/other and I added a "subs1" class to the subs of 'dropdown1' and the same thing for dropdown2 again for easier management in jQuery -->
<li>
<a href="#">About me</a>
</li>
<li>
<a href="#">Product</a>
</li>
</ul>
</li>
<li>
<a class="dropdown2" href="#">Products</a> <!-- added dr opdown2 class to the link -->
<ul class="subs subs2"> <!-- added subs2 class -->
<li>
<a href="#">Product1</a>
</li>
<li>
<a href="#">Product2</a>
</li>
<li>
<a href="#">Product3</a>
</li>
</ul>
</li>
<li>
<a href="#">Support</a>
</li>
<li>
<a href="#">Contact</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</nav>
<div class="page-wrapper"> <!-- I added a new wrapper div to define the space in which a mouseclick (anywhere) will trigger the closure of the menu by seting it's display property to none -->
<div class="sometxt"> <!-- added some text + a top margin to that text div in order to have some room to test the click trigger that we are defining in jQuery -->
Curabitur aliquet quam id dui posuere blandit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla quis lorem ut libero malesuada feugiat. Curabitur arcu erat, accumsan id imperdiet et, porttitor at sem. Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Vestibulum ac diam sit amet quam vehicula elementum sed sit amet dui. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Donec rutrum congue leo eget malesuada.
Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla porttitor accumsan tincidunt. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Curabitur arcu erat, accumsan id imperdiet et, porttitor at sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec velit neque, auctor sit amet aliquam vel, ullamcorper sit amet ligula. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec velit neque, auctor sit amet aliquam vel, ullamcorper sit amet ligula. Vestibulum ac diam sit amet quam vehicula elementum sed sit amet dui. Nulla porttitor accumsan tincidunt. Curabitur arcu erat, accumsan id imperdiet et, porttitor at sem.
Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Proin eget tortor risus. Sed porttitor lectus nibh. Cras ultricies ligula sed magna dictum porta. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum ac diam sit amet quam vehicula elementum sed sit amet dui. Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Cras ultricies ligula sed magna dictum porta. Donec rutrum congue leo eget malesuada. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec velit neque, auctor sit amet aliquam vel, ullamcorper sit amet ligula.
Proin eget tortor risus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec velit neque, auctor sit amet aliquam vel, ullamcorper sit amet ligula. Donec rutrum congue leo eget malesuada. Donec rutrum congue leo eget malesuada. Nulla porttitor accumsan tincidunt. Vivamus suscipit tortor eget felis porttitor volutpat. Nulla porttitor accumsan tincidunt. Pellentesque in ipsum id orci porta dapibus. Donec rutrum congue leo eget malesuada. Curabitur arcu erat, accumsan id imperdiet et, porttitor at sem.
Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec velit neque, auctor sit amet aliquam vel, ullamcorper sit amet ligula. Cras ultricies ligula sed magna dictum porta. Vivamus suscipit tortor eget felis porttitor volutpat. Vivamus suscipit tortor eget felis porttitor volutpat. Vivamus suscipit tortor eget felis porttitor volutpat. Quisque velit nisi, pretium ut lacinia in, elementum id enim. Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Curabitur aliquet quam id dui posuere blandit. Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Cras ultricies ligula sed magna dictum porta.
</div>
</div>
It is live here : https://codepen.io/larrytherabbit/pen/BaKYmJr
Upvotes: 2