Hello! Recently i've been building a website portfolio and have made a burger menu!
In the time so building the burger menu i've had troubles with positioning the logo and the social icons, above and below the href links.
Here is some images to understand what it looks like -
NavBar (full) :
NavBar (burger before) :
NavBar (burger after) :
NavBar (burger after EXAMPLE) :
I understand that this is happening because they are all located inside nav.
How can I modify it to have the logo above the text, and the icons below the text. I tried going around trying JS to add style to logo and icons but it seems to not work. Also changing the css in the media query (to when the burger pops up) can mess up the look "before" the burger is pressed.
html code -
<div class="logo"><img src="src/assets/TWINLOGO.png" style="width: 100px;height: 100px;"></div>
<div class="openMenu"><i class="fa fa-bars" style="color:black;"></i></div>
<ul class="mainMenu">
<!-- Center-aligned links -->
<div class="nav-center">
<div class="navLogo"><img src="src/assets/TWINLOGO.png" style="width: 100px;height: 100px;"></div>
</div>
<!-- Left-aligned links -->
<li>Contact</li>
<li>About</li>
<li>Store</li>
<div class="closeMenu"><i class="fa fa-times"></i></div>
<!-- Right-aligned links -->
<div class="nav-right">
<span class="icons">
<i class="fab fa-youtube"></i>
<i class="fab fa-instagram"></i>
<i class="fab fa-twitter"></i>
<i class="fab fa-github"></i>
</span>
</div>
</ul>
</nav>
css code -
/* Fourth Media Querie */
#media(max-width: 805px){
nav .logo{
margin: 6px;
font-size: 25px;
cursor: pointer;
display:inherit;
}
nav .mainMenu {
height: 100vh;
position: fixed;
top: -100%;
right: 0;
left: 0;
z-index: 10;
flex-direction: column;
justify-content: center;
align-items: center;
background: white;
transition: top 1s ease;
display: flex;
}
nav .mainMenu .closeMenu {
display: block;
position: absolute;
top: 20px;
right: 20px;
color:black;
}
nav .openMenu {
display: block;
}
nav .mainMenu li a {
background: none;
font-size: 2rem;
}
nav .mainMenu li a:hover {
background: none;
color: rgb(0, 110, 255);
font-size: 2.5rem;
transition: ease all .5s;
}
.icons i {
display: inline-block;
padding: 12px;
color:rgb(0, 0, 0);
}
footer .contact .holder .info{
font-size:0.8rem;
}
}
js code -
const mainMenu = document.querySelector('.mainMenu');
const closeMenu = document.querySelector('.closeMenu');
const openMenu = document.querySelector('.openMenu');
openMenu.addEventListener('click',show);
closeMenu.addEventListener('click',close);
function show(){
mainMenu.style.display = 'flex';
mainMenu.style.top = '0';
}
function close(){
mainMenu.style.top = '-100%';
}
Related
const menuBtn = document.querySelector('#menuBtn')
const exitBtn = document.querySelector('#exitBtn');
const menu = document.getElementsByClassName('menu');
menuBtn.addEventListener('click' , () => {
menu.style.display = 'block'
})
.fa.fa-bars.menuBtn {
color: #fff;
font-size: 35px;
cursor: pointer;
display: none;
}
.fa.fa-times-circle.exit {
color: white;
font-size: 35px;
cursor: pointer;
}
#media (max-width: 934px) {
.max-width {
padding: 0 50px;
}
.fa.fa-bars.menuBtn {
display: block;
}
.navbar .menu {
position: fixed;
height: 100vh;
width: 100%;
left: 0;
top: 0;
background-color: #111;
text-align: center;
padding-top: 110px;
display: none;
}
.menu{
display: none
}
.exit {
z-index: 999;
display: none;
margin: 1.8rem;
}
.navbar .menu li {
display: block;
}
.navbar .menu li a {
display: inline-block;
margin: 20px 0;
font-size: 35px;
}
}
<nav class="navbar" id="nav">
<div class="max-width">
<div class="logo"><a id="headSpan" href="index.html">Port<span>folio.</span></a></div>
<ul class="menu">
<li>Home</li>
<li>About</li>
<li>Skills</li>
<li>Projects</li>
<li>CV</li>
<li>Contact</li>
</ul>
<div>
<i class="fa fa-bars menuBtn" id="menuBtn" aria-hidden="true"></i>
</div>
<div class="exit">
<i class="fa fa-times-circle exit" id="exitBtn" aria-hidden="true"></i>
</div>
</div>
</nav>
How do I make it work ? I tested to see if the add event listener was working and it was working but when it comes to displaying the menu when clicked it does not work. Any idea what the issue may be ? I am not that good at using Javascript so any help would be appreciated . Thank you
document.getElementsByClassName('menu'); doesn't return a single element. It returns an HTMLCollection. So menu isn't an element and menu.style.display = 'block doesn't do what you're trying to do.
document.getElementsByClassName('menu') gets multiple elements, all of which have the class 'menu'. The function returns an HTMLCollection, but you can treat it like a list. If you want to use classes, I would recommend using:
var list = document.getElementsByClassName('menu')
for (var item of list) {
// Do Stuff Here
}
If you have multiple menus, consider using JQuery with the .each(function) method for functions.
I'm currently trying to create a navigation bar that sticks when you scroll past. I've gotten to the point where the bar will stick when I scroll past, but when I scroll back to the top the navbar is still sticking. I've been able to troubleshoot to realize that the navbar.offsetTop is being set to 0 when scrolling past, which causes the class "sticky" to never be removed. How can I fix this so that the navbar retains its original offset while being "stuck" to the top of the page?
HTML
<div style="height: 40px">
<ul class="navbar" id="navbar">
<a class="navbutton left" href="about.html"><b>About</b></a>
<a class="navbutton left" href="Games.html"><b>Games</b></a>
<a class="navbutton left" href="#"><b>Btn 1</b></a>
<a class="navbutton left" href="#"><b>Btn 2</b></a>
<a class="navbutton left" href="#"><b>Btn 3</b></a>
<a class="navbutton left" href="#"><b>Btn 4</b></a>
<a class="navbutton" href="#" style="float: right"><b>Btn 5</b></a>
</ul>
</div>
CSS
body {
font-family: Monaco;
background-color: white;
color: #f0dcca;
transition-duration: 0.4s;
}
.navbar {
list-style-type: none;
margin: 0 auto;
padding: 0;
overflow: hidden;
background-color: #333;
}
.navbutton {
display: inline-block;
color: white;
text-align: center;
text-decoration: none;
/* padding: length|initial|inherit; */
padding: 10px 12px;
transition-duration: 0.4s;
}
.navbutton:hover {
background-color: #f0dcca;
color: black;
}
.sticky {
position: fixed;
top:0;
width: 100%;
}
.content {
padding: 16px;
}
.sticky + .content {
padding-top: 60px;
}
Javascript
function stickyNav() {
var navbar = document.getElementById("navbar");
var navTop = navbar.offsetTop;
console.log('navTop = ' + navTop);
console.log('scrollY = ' + window.scrollY);
if (window.scrollY >= navTop) {
navbar.classList.add("sticky");
}
else {
navbar.classList.remove("sticky");
}
}
window.addEventListener('scroll', stickyNav);
The problem is in the function definition of stickyNav.
What I'm seeing is stickyNav function is registered as a callback for the scroll event. But the variables navbar and navTop are inside the function which is assigning values to them every time you scroll. And navTop is getting assigned 0 every time. And the sticky class is never removed.
Try avoiding reassigning values. This worked for me.
<!DOCTYPE html>
<html>
<head>
<style>
body {
font-family: Monaco;
background-color: white;
color: #f0dcca;
transition-duration: 0.4s;
height: 1000px;
}
.navbar {
list-style-type: none;
margin: 0 auto;
padding: 0;
overflow: hidden;
background-color: #333;
}
.navbutton {
display: inline-block;
color: white;
text-align: center;
text-decoration: none;
/* padding: length|initial|inherit; */
padding: 10px 12px;
transition-duration: 0.4s;
}
.navbutton:hover {
background-color: #f0dcca;
color: black;
}
.sticky {
position: fixed;
top: 0;
width: 100%;
}
.content {
padding: 16px;
}
.sticky+.content {
padding-top: 60px;
}
</style>
<script>
function stickyNav() {
var navbar = document.getElementById("navbar");
var navTop = navbar.offsetTop;
window.addEventListener('scroll', function() {
console.log('navTop = ' + navTop);
console.log('scrollY = ' + window.scrollY);
if (window.scrollY >= navTop) {
navbar.classList.add("sticky");
} else {
navbar.classList.remove("sticky");
}
});
}
</script>
</head>
<body onload="stickyNav()">
<h1>dummy content</h1>
<h1>dummy content</h1>
<h1>dummy content</h1>
<div style="height: 40px">
<ul class="navbar" id="navbar">
<a class="navbutton left" href="about.html"><b>About</b></a>
<a class="navbutton left" href="Games.html"><b>Games</b></a>
<a class="navbutton left" href="#"><b>Btn 1</b></a>
<a class="navbutton left" href="#"><b>Btn 2</b></a>
<a class="navbutton left" href="#"><b>Btn 3</b></a>
<a class="navbutton left" href="#"><b>Btn 4</b></a>
<a class="navbutton" href="#" style="float: right"><b>Btn 5</b></a>
</ul>
</div>
</body>
</html>
I have a navbar that contains three elements. Horizontally, from left-to-right, they are: socialMediaIcons, logoArea, and navBarOptionsList.
I wrote javascript and CSS such that, when the user begins to scroll down the page, the socialMediaIcons and navBarOptionsList's visibility change to hidden.
The problem is, the socialMediaIcons element lags by about half a second to become hidden after the user scrolls down. The navBarOptionsList hides immediately after even slightly scrolling down the page (this is the expected behaviour -- and it is what I'd like the socialMediaIcons to do too).
Below is the CSS (which is where I suspect the problem is), as well as the Javascript (detailing the logic for hiding the two elements) and HTML:
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS, and stupid fontawesome shyt -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/>
<!-- Required CDNs: jQuery, Popper.js, Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<!--Favicon-->
<link rel="shortcut icon" type="image/x-icon" href="../resources/codigoinitiativefavi.ico"/>
<!--Custom CSS Stylesheet-->
<link rel="stylesheet" href="../styles.css"/>
<title>Codigo Initiative</title>
</head>
<body>
<nav class="navBar">
<div class="socialMediaNavBarArea">
<ul class="socialMediaIconList">
<li class="socialMediaIcon"><i class="fab fa-facebook-f"></i></li>
<li class="socialMediaIcon"><i class="fab fa-twitter"></i></li>
<li class="socialMediaIcon"><i class="fab fa-youtube"></i></li>
<li class="socialMediaIcon"><i class="fab fa-github"></i></li>
<li class="socialMediaIcon"><i class="fab fa-linkedin-in"></i></li>
</ul>
</div>
<div class="logoArea">
<img id="navBarLogocaster" src="../resources/codigoinitiativewhite.png" alt="Codigo Initiative">
</div>
<!--TODO: Nav bar options list font style should match the Codigo Initiative logo font style-->
<div class="navBarOptionsAreaFullScreen">
<ul class="navbarOptionsList">
<li class="navItem">
<a class="navLink" href="">Home</a>
</li>
<li class="navItem">
<a class="navLink" href="">Resources</a>
</li>
<li class="navItem">
<a class="navLink" href="">Curriculums</a>
</li>
<li class="navItem">
<a class="navLink" href="">Contact</a>
</li>
</ul>
</div>
<div class="hamIconNavOptions">
<ul class="hamIconNavOptionsList">
<li class="hamburgerIconNavOptions">☰
<ul id="hamburgerIconNavOptionsNestedList">
<li class="hamburgerIconNavOptionsNestedListItem"><a class="navOptionAnchorItem" href="">Home</a></li>
<li class="hamburgerIconNavOptionsNestedListItem"><a class="navOptionAnchorItem" href="">Resources</a></li>
<li class="hamburgerIconNavOptionsNestedListItem"><a class="navOptionAnchorItem" href="">Curriculums</a></li>
<li class="hamburgerIconNavOptionsNestedListItem"><a class="navOptionAnchorItem" href="">Contact</a></li>
</ul>
</li>
</ul>
</div>
</nav>
<div class="placeholder"></div>
</body>
<footer>
<script src="../index.js"></script>
</footer>
</html>
CSS:
/*Hamburger Icon styling*/
.hamburgerIconNavOptions{
color: white;
padding-top: 20px;
}
/*Styling for the hamburger icon (which is really a list)*/
.hamIconNavOptionsList{
margin: 0;
padding: 0;
list-style: none; /*removing the bullet point*/
}
/*styling the nested list in the hamburger icon*/
#hamburgerIconNavOptionsNestedList{
margin: 0;
padding: 0;
list-style: none; /*Removiing the bullet points*/
background-color: #13204f;
opacity: .5; /*Making this bad boy transparent. (0 is completely transperent, 9 is solid black)*/
}
/*Removing the default underlining provided by the anchor tag's default styling*/
.navOptionAnchorItem{
text-decoration: none; /*Removing the default styling from the anchor element*/
color: white;
}
/*Removing the underlining of links provided by the anchor tag's default styling*/
.navOptionAnchorItem:link {
text-decoration: none;
}
/*Removing the underlining that occurs by default on anchor tags when hovering over them.*/
.navOptionAnchorItem:hover {
text-decoration: none;
}
/*Styling each list item within the hamburger icon's nested list*/
.hamburgerIconNavOptions{
float: left;
width: 200px;
height: 40px;
}
#media(max-width: 1200px) {
/*This logic will execute when the screen's width becomes too small to display everything*/
.socialMediaIconList{
display: none; /*Will hide the list items when the screen's width is too small to display them*/
}
.socialMediaIconList.toggleCls{
display: none; /*will remove the social media icon list if the screen isn't wide enough to display it*/
}
.hamburgerIconSocialMedia {
display: none; /*TODO: Don't really need a hamburger bar to begin with. Need to come back and remove this.*/
}
/*Same stuff as above, except for the navBar options list*/
.navbarOptionsList{
display: none;
}
#hamburgerIconNavOptionsNestedList.toggleCls{
display: block;
}
/*The screen is too small. But hide the nested list that belons to the hamburger icon. Will be displayed when the hamburger icon is clicked.*/
#hamburgerIconNavOptionsNestedList{
display: none;
}
}
/*Make the hamburger icon disappear when the screen is large enough to display all list view items*/
#media(min-width: 1199px) {
.hamIconNavOptions{
display: none; /*Hides the hamburger icon when the screen is large enough to display everything*/
}
.socialMediaIconList{
display: initial; /*Shows the social media links*/
}
.navbarOptionsList{
display: initial;
}
}
.navBar {
display: flex;
flex-direction: row; /*Aligns items horizontally*/
flex-wrap: nowrap; /*Prevents overflow wrapping. We'd rather everything get packed on a single row.*/
padding: 10px;
background-color: #13204f;
height: 125px;
position: fixed;
width: 100%;
}
.socialMediaNavBarArea {
position: relative;
width: 25%;
padding: 30px 0;
text-align: center;
}
.logoArea {
position: relative;
width: 50%;
text-align: center;
}
.navBarOptionsAreaFullScreen {
position: relative;
width: 30%;
padding: 30px 0;
text-align: center;
font-size: 15px;
padding-right: 30px;
}
/*Social Media area*/
.socialMediaIcon {
list-style: none;
margin: auto;
display: inline-block;
font-size: 10px;
padding: 10px 10px;
color: white;
border: 1px solid white;
border-radius: 50%;
transition: .5s;
}
.socialMediaIconList {
padding-left: 0px;
padding-right: 90px;
}
.socialMediaNavBarIcons {
top: 40%;
left: 50%;
transform: translate(-53%, -50%);
position: absolute;
}
.socialMediaIcon:hover {
color: #565759;
border: 1px solid #565759;
transition: .75s;
}
/*Navigation Bar logo area*/
#navBarLogocaster {
max-width: 100%;
max-height: 75%;
/*Aligns the image center horizontal and vertical*/
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
/*Navigation Bar options area*/
.navItem {
display: inline;
}
.placeholder {
height: 5000px;
}
.navLink {
padding: 5px;
color: white;
}
.navLink:hover {
text-decoration: none;
color: #565759;
transition: .75s;
}
Javascript:
/**
* The following logic controls what will happen when the user scrolls down on the screen.
* The navbar will decrease in heigh slightly.
*/
window.onscroll = function() {configureNavBar()};
function configureNavBar() {
if (document.body.scrollTop > 80 || document.documentElement.scrollTop > 80) {
//The user is scrolling down, so minimize the nav bar, and hide all corollary navbar items to reduce clutter.
document.querySelector(".navBar").style.height = "90px";
hideSocialMediaIcons();
hideNavBarOptions();
} else {
//The user has scrolled back up to the top. Display all corollary navbar options/details.
document.querySelector(".navBar").style.height = "120px";
unhideSocialMediaIcons();
unhideNavBarOptions();
}
}
/**
* Will hide the social media icons (if it is even being displayed at all)
*/
function hideSocialMediaIcons() {
let socialMediaIconList = document.querySelector(".socialMediaIconList");
//If the social media icons are being displayed, hide them.
if(socialMediaIconList.style.visibility != "hidden") {
socialMediaIconList.style.visibility = "hidden";
} else {
//no further action needed, as the social media icons are already hidden.
}
}
/**
* Will hide the navbar's (full-screen) options when scrolling down.
*/
function hideNavBarOptions(){
let navBarOptions = document.querySelector(".navbarOptionsList");
//If the social media icons are being displayed, hide them.
if(navBarOptions.style.visibility != "hidden") {
navBarOptions.style.visibility = "hidden";
} else {
//no further action needed, as the social media icons are already hidden.
}
}
Because there is transition duration set for socialMediaIcon class but for .navBarOptionsList no duration set.
I'm new to web applications, so I don't know HTML, CSS and JS good enough to handle problems by myself yet. I followed some YT tutorial to create collapsible sidebar, but I don't know why it is collapsed as default and i can't make it opened. I think that the problem is that i don't know what exactly is going on in my code. Can you tell me what I'm doing wrong and help me understand how this should work?
HTML:
<div id="wrapper">
<div id="sidebar-wrapper">
<ul class="sidebar-nav">
<li>
<a href="#selectGameSubmenu" data-toggle="collapse" aria-expanded="true" class="dropdown-toggle">
<i class="fa fa-fw fa-gamepad"></i> Select something</a>
<ul class="collapse list-unstyled">
<li>
Link1
</li>
<li>
Link2
</li>
<li>
Link3
</li>
</ul>
</li>
<li>
<i class="fa fa-fw fa-home"></i> Home
</li>
<li>
<i class="fa fa-fw fa-user"></i> My profile
</li>
<li>
<i class="fa fa-fw fa-question-circle"></i> FAQ
</li>
<li>
<i class="fa fa-fw fa-phone"></i> Contact
</li>
<li>
<i class="fa fa-fw fa-sign-out-alt"></i> Logout
</li>
</ul>
</div>
<!-- Page content -->
<div id="page-content-wrapper">
<!-- some code -->
</div>
</div>
CSS:
#sidebar-wrapper{
z-index: 1;
position: fixed;
width: 0;
height: 100%;
overflow-y: hidden;
transition: 0.15s;
background-color: var(--black) ;
font-size: 1em;
}
#sidebar-wrapper .sidebar-header {
padding: 20px;
background: var(--black);
}
#page-content-wrapper{
width: 100%;
position: absolute;
padding: 15px;
transition: 0.15s;
color: black;
}
#wrapper.menuDisplayed #sidebar-wrapper{
width: 250px;
}
#wrapper.menuDisplayed #page-content-wrapper {
padding-left: 250px;
}
.sidebar-nav{
padding: 0;
list-style: none;
}
.sidebar-nav li{
text-indent: 20px;
line-height: 40px;
}
.sidebar-nav li a{
display: block;
text-decoration: none;
color: var(--gray);
}
.sidebar-nav ul li a {
font-size: 0.9em;
display: block;
color: var(--lightGray)
}
.sidebar-nav li a:hover{
color: #fff;
background: var(--gray);
}
.sidebar-nav ul li.active > a, a[aria-expanded="true"] {
color: #fff;
background: var(--deepBlue);
}
JS:
$("#menu-toggle").click(function(e){
e.preventDefault();
$("#wrapper").toggleClass("menuDisplayed");
});
Ok, I'll tell you how to achieve what you want (2 methods) and then I’ll explain how your code works.
method 1
in your first div (#wrapper), add the class menuDisplayed:
<div id="wrapper" class="menuDisplayed">
method 2
you can also change your CSS to do what you want and make the "menu displayed" the default style:
replace "menuDisplayed" with "menuHidden" throughout your code, so that it continues to make sense semantically
update styles for #sidebar-wrapper giving it a value other than 0 for width.
#sidebar-wrapper{
z-index: 1;
position: fixed;
width: 250px;
height: 100%;
overflow-y: hidden;
transition: 0.15s;
background-color: var(--black) ;
font-size: 1em;
}
now change styles for #page-content-wrapper too, so that it leaves room for your sidebar:
#page-content-wrapper{
width: 100%;
position: absolute;
padding: 15px;
padding-left: 250px; /* leaving 250px of space on the left */
transition: 0.15s;
color: black;
}
the next step is to make the closed sidebar have the right styles:
#wrapper.menuHidden #sidebar-wrapper{
width: 0; /* the element of id 'wrapper' and class 'menuHidden' must have width 0 */
}
#wrapper.menuHidden #page-content-wrapper {
padding-left: unset; /* clears the attribute that gave space to the sidebar */
}
now I'll explain how your code works (before you change the sidebar behavior):
your CSS tells the browser that the element with the sidebar-wrapper id should have null width (so it does not appear as soon as you load the page), but it also says that the element with id sidebar-wrapper should be 250px wide when inside another element that has the wrapper id and the menuDisplayed class.
the magic is in your javascript: it tells the browser to toggle the menuDisplay class of the element with id wrapper, which activates the CSS style that makes your sidebar 250px wide, and so it appears. when toggled again, the menuDisplayed class is deleted from the element with id wrapper and your sidebar returns to having width equal to 0.
the $("#menu-toggle").click adds an event listener for the 'click' event using jQuery. when this event is fired (someone clicks in the element with the menu-toggle id), the callback function is executed:
function(e){
e.preventDefault(); // prevents the default behavior of the element (if it is an anchor (<a></a>), it loses the ability to change pages, etc.)
$("#wrapper").toggleClass("menuDisplayed"); // toggles the class 'menuDisplayed' of the element with id 'wrapper'
}
You can add the class menuDisplayed to the navbar (with id #wrapper) initially, so on page load, it will be displayed.
<div id="wrapper" class="menuDisplayed">
you should add the class menuDisplayed to your #wrapper. then it can show by default.
<div id="wrapper" class="menuDisplayed">
full example can be found here :http://jsfiddle.net/9ojvnutc/
MATERIAL COMPONENTS FOR THE WEB (MENUS)
This question is in relation to the Menu Component:
I've modified the code so that the menu opens when hovered instead of clicked. I'm now trying to make the menu stay open or closed when certain elements inside the menu are clicked on..But I'm having trouble getting it to work.
Can anyone help?
Codepen Link:
https://codepen.io/oneezy/pen/prejpw
Example:
When <li class="wont-close"> is clicked, the menu won't close. menu.show();
When <li class="will-close"> is clicked, the menu will close. menu.hide();
Here's my attempts:
HTML
<section class="demo">
<div class="mdc-tab-bar">
<!-- Hover Toggle (Wrapper) -->
<div class="mdc-tab-wrapper hover-toggle">
<!-- Button (For Looks) -->
<a class="mdc-button mdc-button--raised mdc-button--primary mdc-tab mdc-ripple-upgraded" role="tab">
Hover Menu
</a>
<!-- Hover Menu (Toggles Show/Hide)-->
<nav class="mdc-simple-menu mdc-tab-items-wrapper" tabindex="-1">
<ul class="mdc-simple-menu__items mdc-list" role="menu" aria-hidden="true">
<!-- Won't Close (When Clicked) -->
<li class="mdc-list-item wont-close clone-me" role="menuitem" tabindex="0">
<a class="category-items flex-horizontal between-stretch" href="#">
<i class="material-icons margin-r-5">keyboard_arrow_right</i>
<span>Won't Close</span>
</a>
</li>
<!-- Will Close (When Clicked) -->
<li class="mdc-list-item will-close" role="menuitem" tabindex="0">
<a class="category-items flex-horizontal between-stretch" href="#">
<i class="material-icons margin-r-5">close</i>
<span>Will Close</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
JS
/* Hover Tabs
*********************************/
function hoverTabs() {
var menuEls = document.querySelectorAll('.mdc-simple-menu');
menuEls.forEach((el, i) => {
var menu = new mdc.menu.MDCSimpleMenu(el);
var toggle = $(el).closest('.hover-toggle')[0];
var wontClose = $(el).closest('.wont-close'); // Not working...
var willClose = $(el).closest('.will-close'); // Not working...
toggle.addEventListener('mouseover', function() {
menu.show();
});
toggle.addEventListener('mouseleave', function() {
menu.hide();
});
/* Attempt #1 (Not working...)
*******************************************************/
// wontClose.addEventListener('click', function() {
// menu.show();
// });
// willClose.addEventListener('click', function() {
// menu.hide();
// });
/* Attempt #2 (Not working...)
*******************************************************/
// $('.wont-close').on('click', function(e) {
// e.preventDefault();
// menu.show();
// });
//
// $('.will-close').on('click', function(e) {
// e.preventDefault();
// menu.hide();
// });
});
}
$(document).ready(function() {
hoverTabs();
});
When in doubt, create a pure CSS solution...
I'm not accepting my answer as THE ANSWER because this is a hack.
I just want to include this here to show my quick fix that does the exact same thing (right on down to the cubic-bezier animation).
NOTE: I'm still using the Material Design Styles it ships with... Just not any of the JS.
Codepen: https://codepen.io/oneezy/pen/PKpJXV
HTML
<!-- Hover Toggle (Wrapper) -->
<div class="mdc-tab-wrapper hover-toggle clone-menu">
<!-- Button (For Looks) -->
<a class="mdc-button mdc-button--raised mdc-button--primary">Hover Menu</a>
<!-- Hover Menu (Toggles Show/Hide)-->
<nav class="mdc-simple-menu mdc-simple-menu--open" tabindex="-1">
<ul class="mdc-simple-menu__items mdc-list" role="menu" aria-hidden="true">
<!-- Won't Close (When Clicked) -->
<li class="mdc-list-item clone-me" role="menuitem" tabindex="0">
<a class="category-items flex-horizontal between-stretch" href="#">
<i class="material-icons margin-r-5">keyboard_arrow_right</i>
<span>Menu Item</span>
</a>
</li>
</ul>
</nav>
</div>
CSS
/* Reset
========================================================================= */
* { box-sizing: border-box; margin: 0; padding: 0; text-decoration: none; }
html,
body,
main { display: flex; flex-direction: column; height: 100%; }
section { padding: 5%; }
a { color: var(--mdc-theme-primary); }
h1 { background: black; color: white; padding: .25rem 1rem; position: relative; }
h1 span { font-weight: normal; font-size: 16px; position: absolute; right: 24px; top: 14px; display: inline-block; text-transform: uppercase; }
/* Material Design Menu
========================================================================= */
/* Menu Styles */
.wrapper { position: relative; display: flex; justify-content: space-between; }
.wrapper .hover-toggle { display: inline-block; position: relative; }
.wrapper .hover-toggle .mdc-button { z-index: 2; position: relative; color: white; min-width: auto; }
.wrapper .hover-toggle .mdc-simple-menu { width: 100%; top: 100% !important; position: absolute; right: 0 !important; left: 0 !important; z-index: 1; padding: 0; }
.mdc-simple-menu .mdc-list,
.mdc-simple-menu .mdc-list-group { padding: 0; }
/* Hover Effects */
.hover-toggle .mdc-simple-menu--open { opacity: 0; transform: scale(0, 0) translateY(-40px); transition: .2s cubic-bezier(0, 0, 0.2, 1); position: absolute; transform-origin: left top 0px; left: 0px; top: 0px; }
.hover-toggle:hover .mdc-simple-menu--open { opacity: 1; transform: scale(1,1) translateY(0); }
.mdc-simple-menu .mdc-list-item:before { opacity: 0; position: absolute; top: 0; left: 0; width: 100%; height: 100%; -webkit-transition: opacity .12s cubic-bezier(0,0,.2,1); transition: opacity .12s cubic-bezier(0,0,.2,1); border-radius: inherit; background: var(--mdc-theme-primary); content: ""; }
.mdc-simple-menu .mdc-list-item:hover:before { opacity: .1; }
.mdc-simple-menu .mdc-list-item:active:before { opacity: .2; }