Hiding submenus in an animated sidebar - javascript

I'm trying to create an animated sidebar using CSS and JS, and I'm having an issue with hiding submenus (green in the demo). So, the submenus should fly out slowly like it is now, but only when parent <li> is hovered. Currently, they are always present. Also, list items below the hovered <li> should move down appropriately. In this scenario, when 'Transactions' is hovered, transactions submenu should appear slowly and take up space so 'Budgets' moves down accordingly. I have tried something with display: none; and display: block; but I've read that animations don't work on display property and couldn't get it to work, and I would really like to keep the animation. I have also tried something with visibility but failed, not worth mentioning.
document.addEventListener('DOMContentLoaded', () => {
let listItems = document.querySelectorAll('nav > ul > li');
function onListItemClick() {
for (let listItem of listItems) {
listItem.classList.remove('active');
listItem.children[0].classList.remove('dot');
if (listItem.children.length > 2) {
listItem.children[2].style.display = 'none';
}
}
this.classList.add('active');
this.children[0].classList.add('dot');
if (this.children.length > 2) {
this.children[2].style.display = 'block';
}
}
listItems.forEach(function(listItem) {
listItem.addEventListener('click', onListItemClick);
});
});
.sidebar {
background-color: #F2F2F2;
width: 300px;
height: 100%;
position: fixed;
font-family: sans-serif;
}
.sidebar>nav>ul {
list-style: none;
line-height: 2em;
padding: 0;
margin: 10em 0 0 0;
}
.sidebar>nav>ul>li {
display: grid;
grid-template-columns: 25px 1fr;
color: #959595;
font-size: 18px;
}
.sidebar>nav>ul>li>span:nth-child(1) {
margin-left: 3em;
}
.sidebar>nav>ul>li>span:nth-child(2) {
padding: 0.5em 0 0.5em 3em;
}
.sidebar>nav>ul>li:hover {
color: #757575;
font-weight: bold;
cursor: pointer;
}
.sidebar>nav>ul>li>ul {
z-index: 9;
position: absolute;
list-style: none;
padding: 0;
margin: 0;
width: 300px;
transform: translateY(0);
transition: all 0.5 ease;
}
.sidebar>nav>ul>li:hover>ul {
transform: translateY(30%);
transition: all 0.5s ease;
}
.sidebar>nav>ul>li>ul>li {
display: block;
box-sizing: border-box;
background-color: #33ad93;
font-size: 14px;
width: 100%;
font-weight: normal;
padding: 0 0 0 5.5em;
}
.sidebar>nav>ul>li>ul>li:first-child {
padding: 0.5em 0 0 5.5em;
}
.sidebar>nav>ul>li>ul>li:last-child {
padding: 0 0 0.5em 5.5em;
}
.sidebar>nav>ul>li>ul>li:not(:first-child):not(:last-child) {
padding: 0.15em 0 0.15em 5.5em;
}
.sidebar>nav>ul>li>ul>li>a {
color: white;
}
.sidebar>nav>ul>li>span>a {
color: #959595;
text-decoration: none;
}
.dot {
border-radius: 50%;
background-color: #33ad93;
width: 10px;
height: 10px;
display: inline-block;
margin: auto;
}
.active {
color: black !important;
font-weight: bold;
}
<div class="sidebar">
<nav>
<ul>
<li class=" active ">
<span class=" dot "></span>
<span>Dashboard</span>
</li>
<li class="">
<span class=""></span>
<span>Transactions</span>
<ul>
<li>New Transaction</li>
<li>View Transactions</li>
</ul>
</li>
<li class="">
<span class=""></span>
<span>Budgets</span>
</li>
</ul>
</nav>
</div>
How can I overcome the issue?

I made a few small changes which seems to accomplish what you want:
.sidebar > nav > ul > li > ul {
z-index: 9;
/*position: absolute; *removed*/
height: 0; /*added*/
list-style: none;
padding: 0;
margin: 0;
width: 300px;
/*transform: translateY(0); *removed*/
/*transition: all 0.5 ease; *removed*/
overflow-y: hidden; /*added*/
}
.sidebar > nav > ul > li:hover > ul {
/*transform: translateY(30%); *removed*/
height: 80px; /*added*/
transition: height 0.5s ease; /*modified*/
}
.sidebar > nav > ul > li > ul > li {
height: 40px; /*added*/
display: block;
box-sizing: border-box;
background-color: #33ad93;
font-size: 14px;
width: 100%;
font-weight: normal;
padding: 0 0 0 5.5em;
}
So I added a static height to each of the new dropdown's list items to 40px, then set the container to 80px. Then we transition the height rather than the Y position. If you want it to be dynamic relative to the number of elements, unfortunately it's not as easy as using height: 100% instead of height: 80px (you'll need to use some javascript to dynamically set the height relative to the number of list items; it will still work, but the transition will be slightly broken).
Hopefully this should give you an idea though

You have just missed unit for transition on default ul.
Here is updated code
document.addEventListener('DOMContentLoaded', () => {
let listItems = document.querySelectorAll('nav > ul > li');
function onListItemClick() {
for (let listItem of listItems) {
listItem.classList.remove('active');
listItem.children[0].classList.remove('dot');
if (listItem.children.length > 2) {
listItem.children[2].style.display = 'none';
}
}
this.classList.add('active');
this.children[0].classList.add('dot');
if (this.children.length > 2) {
this.children[2].style.display = 'block';
}
}
listItems.forEach(function(listItem) {
listItem.addEventListener('click', onListItemClick);
});
});
.sidebar {
background-color: #F2F2F2;
width: 300px;
height: 100%;
position: fixed;
font-family: sans-serif;
}
.sidebar > nav > ul {
list-style: none;
line-height: 2em;
padding: 0;
margin: 10em 0 0 0;
}
.sidebar > nav > ul > li {
display: grid;
grid-template-columns: 25px 1fr;
color: #959595;
font-size: 18px;
}
.sidebar > nav > ul > li > span:nth-child(1) {
margin-left: 3em;
}
.sidebar > nav > ul > li > span:nth-child(2) {
padding: 0.5em 0 0.5em 3em;
}
.sidebar > nav > ul > li:hover {
color: #757575;
font-weight: bold;
cursor: pointer;
}
.sidebar > nav > ul > li > ul {
z-index: 0;
height: 0px;
overflow-y: hidden;
list-style: none;
padding: 0;
margin: 0;
width: 300px;
transform: translateY(0);
transition: all 0.5s linear;
}
.sidebar > nav > ul > li:hover > ul {
height: 100%;
transform: translateY(0);
}
.sidebar > nav > ul > li > ul > li {
display: block;
box-sizing: border-box;
background-color: #33ad93;
font-size: 14px;
width: 100%;
font-weight: normal;
padding: 0 0 0 5.5em;
}
.sidebar > nav > ul > li > ul > li:first-child {
padding: 0.5em 0 0 5.5em;
}
.sidebar > nav > ul > li > ul > li:last-child {
padding: 0 0 0.5em 5.5em;
}
.sidebar > nav > ul > li > ul > li:not(:first-child):not(:last-child) {
padding: 0.15em 0 0.15em 5.5em;
}
.sidebar > nav > ul > li > ul > li > a {
color: white;
text-decoration: none;
}
.sidebar > nav > ul > li > ul > li > a:hover {
text-decoration: underline;
}
.sidebar > nav > ul > li > span > a {
color: inherit;
text-decoration: none;
}
.dot {
border-radius: 50%;
background-color: #33ad93;
width: 10px;
height: 10px;
display: inline-block;
margin: auto;
}
.active {
color: black !important;
font-weight: bold;
}
<div class="sidebar">
<nav>
<ul>
<li class=" active ">
<span class=" dot "></span>
<span>Dashboard</span>
</li>
<li class="">
<span class=""></span>
<span>Transactions</span>
<ul>
<li>New Transaction</li>
<li>View Transactions</li>
</ul>
</li>
<li class="">
<span class=""></span>
<span>Budgets</span>
</li>
</ul>
</nav>
</div>

You might want to check out the w3schools W3.CSS Framework page on CSS Sidebars.
The snippet below is an example using that framework. You can then tweak it to your style from there.
<link href="https://www.w3schools.com/w3css/4/w3.css" rel="stylesheet"/>
<div class="w3-sidebar w3-bar-block w3-light-grey w3-card">
Dashboard
<div class="w3-dropdown-hover">
<button class="w3-button">Transactions
<span style="font-size:12px;padding-bottom:2px">▼</span>
</button>
<div class="w3-dropdown-content w3-bar-block" style="box-shadow: 0 0.25em 0.5em #00000040;">
New Transaction
View Transactions
</div>
</div>
Budgets
</div>

Related

How do I get navigation bar's dropdown to stay when hovering over the dropdown?

I have a simple website with a simple navigation bar, but it seems like a very daunting task after much research.
When hovering over any of the buttons, it will display a dropdown to show more options.
I have got that working fine, but how would I go about making the dropdown stay when I hover over the contents of the dropdown?
Basically when the cursor leaves the navigation's bar button and onto the dropdown menu, it doesn't disappear.
I read that it's possible with jQuery, but I want to do it in JavaScript alone if it's possible, even if it's lengthy.
The navbar's hover itself works, but whatever I tried to keep the dropdown there when hovering on it, keeps bugging everything out.
This is the code I have, and that I have tried:
document.getElementById("server").onmouseover = function() {
serverMouseOver()
};
document.getElementById("server").onmouseout = function() {
serverMouseOut()
};
function serverMouseOver() {
document.getElementById("serverdropdownbox").className += "animated fadeIn";
};
function serverMouseOut() {
document.getElementById("serverdropdownbox").className += "animated fadeOut";
};
document.getElementById("serverdropdownbox").onmouseover = function() {
serverDropdownMouseOver()
};
document.getElementById("serverdropdownbox").onmouseout = function() {
serverDropdownMouseOut()
};
function serverDropdownMouseOver() {
document.getElementById("serverdropdownbox").style.opacity = "1";
};
function serverDropdownMouseOut() {
document.getElementById("serverdropdownbox").style.opacity = "0";
};
#navbarbox
{
clear: both;
display: block;
width: 100vw;
height: 3.5vw;
padding: 0vw 0 0 0;
margin: 0;
}
#navbar, #navbar ul
{
width: 100vw;
height: 3.5vw;
display: flex;
padding: 0 0 0 0;
margin: 0;
}
#navbar span
{
height: 3.5vw;
display: block;
transform: skewX(15deg);
}
#navbar li
{
color: white;
list-style: none;
display: inline-block;
padding: 1vw 3.95vw 1vw 3.95vw;
margin: auto;
text-align: center;
color: red;
font-size: 2.3vw;
font-family: Jura;
height: 2.5vw;
transform: skewX(-15deg);
}
#serverdropdownbox
{
display: block;
opacity: 0;
float: left;
color: white;
background-color: darkblue;
width: 0;
}
#serverdropdowncontent
{
list-style-type: none;
width: 16vw;
margin: 1vw 0 0 10.1vw;
}
#serverdropdowncontent li
{
border: 1px solid white;
font-size: 25px;
text-align: center;
padding: 1vw 0 1vw 0;
background-color: white;
}
#server
{
background-color: blue;
}
#communitydropdownbox
{
display: block;
float: left;
color: white;
background-color: darkblue;
width: 0;
}
#communitydropdowncontent
{
list-style-type: none;
width: 19.7vw;
margin: 1vw 0 0 26vw;
}
#communitydropdowncontent li
{
border: 1px solid white;
font-size: 25px;
text-align: center;
padding: 1vw 0 1vw 0;
}
#community
{
background-color: brown;
}
#storedropdownbox
{
display: block;
float: left;
color: white;
background-color: darkblue;
width: 0;
}
#storedropdowncontent
{
list-style-type: none;
width: 13.6vw;
margin: 1vw 0 0 45.65vw;
}
#storedropdowncontent li
{
border: 1px solid white;
font-size: 25px;
text-align: center;
padding: 1vw 0 1vw 0;
}
#store
{
background-color: blue;
}
#downloadsdropdownbox
{
display: block;
float: left;
color: white;
background-color: darkblue;
width: 0;
}
#downloadsdropdowncontent
{
list-style-type: none;
width: 19.8vw;
margin: 1vw 0 0 59.2vw;
}
#downloadsdropdowncontent li
{
border: 1px solid white;
font-size: 25px;
text-align: center;
padding: 1vw 0 1vw 0;
}
#downloads
{
background-color: brown;
}
#contactdropdownbox
{
display: block;
float: left;
color: white;
background-color: darkblue;
width: 0;
}
#contactdropdowncontent
{
list-style-type: none;
width: 16vw;
margin: 1vw 0 0 78.9vw;
}
#contactdropdowncontent li
{
border: 1px solid white;
font-size: 25px;
text-align: center;
padding: 1vw 0 1vw 0;
}
#contact
{
background-color: blue;
}
.animated
{
animation-duration: 1s;
animation-fill-mode: both;
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.fadeIn {
animation-name: fadeIn;
}
#keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.fadeOut {
animation-name: fadeOut;
}
<head>
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Jura" />
<body>
<!--Giga logo, top left-->
<img id="gigalogo" src="images/gigalogo.png">
<!--Steam logo, top right-->
<div id="steamlogomainbox">
<img id="steamlogo" src="images/steamlogo.png">
</div>
<!--navigation barrrrrr-->
<div id="navbarbox">
<ul id="navbar">
<li style="background-color: purple;"><span>Home</span></li>
<li id="server"><span>Servers</span></li>
<li id="community"><span>Community</span></li>
<li id="store"><span>Store</span></li>
<li id="downloads"><span>Downloads</span></li>
<li id="contact"><span>Contact</span></li>
</ul>
</div>
<div id="serverdropdownbox">
<ul id="serverdropdowncontent">
<li id="serverdropdownli">Server List</li>
<li id="serverdropdownli">GigaDB</li>
<li id="serverdropdownli">CS:GO</li>
</ul>
</div>
<div id="communitydropdownbox">
<ul id="communitydropdowncontent">
<li>Events</li>
<li></li>
</ul>
</div>
<div id="storedropdownbox">
<ul id="storedropdowncontent">
<li>Credits</li>
<li>Items</li>
<li>VIP</li>
</ul>
</div>
<div id="downloadsdropdownbox">
<ul id="downloadsdropdowncontent">
<li>TF2</li>
<li>CS:GO</li>
<li>Minecraft</li>
</ul>
</div>
<div id="contactdropdownbox">
<ul id="contactdropdowncontent">
<li>Contact Us</li>
<li>Staff</li>
<li>Steam Group</li>
<li>Appeal Ban</li>
<li>Links</li>
</ul>
</div>
First of all - your HTML structure is invalid. ul tag can have only li as direct child, not a. So ul > a > li must be replaced to ul > li > a.
Second - you don't need JS for such simple menu. Have ul > li > ul as sub-menu and use :hover on ul > li to show your sub-menu.
ul {
padding: 0;
}
li {
white-space: nowrap;
list-style: none;
}
#menu > li {
position: relative;
display: inline-block;
}
#menu > li > ul {
position: absolute;
left: 0;
top: 100%;
min-width: 100%;
opacity: 0;
transition: opacity 200ms ease-in-out;
}
#menu > li:hover > ul {
opacity: 1;
}
<ul id="menu">
<li>Home</li>
<li>
<span>Servers</span>
<ul>
<li>Server 1</li>
<li>Server 2</li>
<li>Server 3</li>
</ul>
</li>
</ul>

Expanding lists push other relative positioned elements up - they should stay still

Let me start off with this fiddle: https://jsfiddle.net/Lwhpgmma/
Basically I have some list items like this:
<ul class="specifics">
<li>
<ul>
<li>Filter by Hosting</li>
<li data-value="ghost" class="active">Ghost Host</li>
<li data-value="they">They Host</li>
<li data-value="you">You Host</li>
<li data-value="server">Server</li>
</ul>
</li>
<li>
<ul>
<li>Filter by Game Mode</li>
<li data-value="1" class="active">Soccar</li>
<li data-value="2">Snowday</li>
<li data-value="3">Hoops</li>
</ul>
</li>
</ul>
The inner <ul> is hidden via line-height: 0; on the parent <li> element. However, when an <li> element is clicked, the .active class is added and it gets set to line-height: normal;
This all works fine, except that it causes some ugly results when these first-tier <li> elements are stacked on-top of each other, like they are in the fiddle demo.
You'll notice when you click Manfield or $100 list elements, that the list elements above them (Server and Soccar) get pushed up. They should stay in the same place they currently are, and the menu from the active <li> should simply flow over the other inactive <li> elements.
I tried changing the first-tier elements from <li> to <span> which solved the issue of the top options bringing their horizontal siblings along for the ride, but doesn't solve the issue of the bottom elements pushing their upper siblings when they expand.
I hope this makes sense.
Use CSS Positioning for this and instead of overflow use flexbox, like:
.dot-overflow {
position: relative;
}
.dot-overflow.active ul {
position: absolute;
bottom: 0;
background: #0F1316;
}
/* Make it a flex container */
ul.specifics {
display: flex;
flex-wrap: wrap;
}
Have a look at the working snippet below (use full screen to see it properly):
// handle the specifics dropdowns
var allSpecifics = $('ul.specifics > li');
$(document).on('click', 'ul.specifics > li', function(event) {
var openThis = ($(this).hasClass('active')) ? false : true;
allSpecifics.removeClass('active');
if (openThis)
$(this).addClass('active');
else {
// selected an option
$(event.target).closest('li[data-value]').addClass('active').siblings().removeClass('active');
}
}).click(function(event) {
if (!$(event.target).closest('ul.specifics > li').length || $(event.target).closest('ul.specifics > li.active > ul > li:first-of-type').length) {
allSpecifics.removeClass('active');
}
});
.specifics-container {
position: absolute;
z-index: 2;
bottom: 50px;
left: 0;
right: 0;
max-width: 100%;
}
ul.specifics {
display: flex;
flex-wrap: wrap;
position: relative;
list-style: none;
padding: 0;
}
ul.specifics > li {
display: inline-block;
position: relative;
box-shadow: 0 0 32px 1px #010;
/*border-right: 1px ridge rgba(225, 255, 225, 0.165);*/
padding: 9px 0;
margin: 0;
width: 24.5%;
text-align: center;
cursor: pointer;
background: #13141c;
transition: all 0.40s ease;
-o-transition: all 0.40s ease;
-moz-transition: all 0.40s ease;
-webkit-transition: all 0.40s ease;
}
ul.specifics > li > i {
display: block;
position: absolute;
left: 12px;
top: 11px;
font-size: 20px;
color: rgba(225, 225, 225, 0.3);
}
ul.specifics > li > ul {
list-style: none;
margin: 0;
padding: 0;
display: block;
width: 100%;
max-height: 420px;
background: none;
text-align: center;
}
ul.specifics > li.active > ul {
overflow-y: scroll;
}
ul.specifics > li > ul::-webkit-scrollbar {
/* this is added to the remodal open() function */
width: 0;
/* remove scrollbar space */
background: transparent;
/* optional: just make scrollbar invisible */
}
ul.specifics > li > ul > li {
background: none;
width: 100%;
margin: 0;
padding: 0;
display: block;
line-height: 0;
opacity: 0;
color: #777;
font-family: 'Play', sans-serif;
font-size: 22px;
transition: all 0.40s ease;
-o-transition: all 0.40s ease;
-moz-transition: all 0.40s ease;
-webkit-transition: all 0.40s ease;
}
ul.specifics > li > ul > li:first-of-type {
font-size: 16px;
color: #ccc;
}
ul.specifics > li > ul > li.active {
line-height: normal;
opacity: 1;
color: #ddd;
}
ul.specifics > li.active > ul > li {
line-height: normal;
opacity: 1;
padding: 16px 0;
}
ul.specifics > li.active > ul > li:first-of-type {
padding: 6px 0;
margin: 0 0 12px 0;
}
ul.specifics > li.active > ul > li.active {
background: rgba(0, 91, 36, 0.15);
}
ul.specifics > li.active > ul > li:hover {
color: #ddd;
background: rgba(0, 31, 96, 0.1);
}
ul.specifics > li.active > ul > li:first-of-type:hover {
background: none;
}
ul.specifics > li.active > i {
opacity: 0;
}
ul.specifics > li:last-of-type {
/*border-right: none;*/
}
ul.specifics > li:hover {
background: #1b1d24;
}
ul.specifics > li.active > ul > li:first-of-type:before {
font-family: Arial, "Helvetica CY", "Nimbus Sans L", sans-serif !important;
font-size: 24px;
position: absolute;
top: 6px;
right: 0;
display: block;
width: 35px;
content: "\00d7";
text-align: center;
transition: all 0.40s ease;
-o-transition: all 0.40s ease;
-moz-transition: all 0.40s ease;
-webkit-transition: all 0.40s ease;
}
ul.specifics > li.active > ul > li:first-of-type:hover:before {
color: red;
}
#media (max-width: 991px) {
ul.specifics {
background: #13141c;
}
ul.specifics > li {
width: 49.5%;
}
}
.dot-overflow {
position: relative;
}
.dot-overflow.active ul {
position: absolute;
bottom: 0;
background: #0F1316;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<div class="specifics-container">
<ul class="specifics">
<li class="dot-overflow">
<i class="fa fa-wifi"></i>
<ul>
<li>Filter by Hosting</li>
<li data-value="ghost" class="active">Ghost Host</li>
<li data-value="they">They Host</li>
<li data-value="you">You Host</li>
<li data-value="server">Server</li>
</ul>
</li>
<li class="dot-overflow">
<i class="fa fa-gear"></i>
<ul>
<li>Filter by Game Mode</li>
<li data-value="1" class="active">Soccar</li>
<li data-value="2">Snowday</li>
<li data-value="3">Hoops</li>
</ul>
</li>
<li class="dot-overflow">
<i class="fa fa-map"></i>
<ul>
<li>Filter by Map</li>
<li data-value="248" class="active">Manfield</li>
<li data-value="1337" i>Wasteland</li>
<li data-value="421">Utopia</li>
<li data-value="121">Stadium</li>
</ul>
</li>
<li class="dot-overflow">
<i class="fa fa-ticket"></i>
<ul>
<li>Filter by League</li>
<li data-value="100" class="active">$100</li>
<li data-value="50">$50</li>
<li data-value="20">$20</li>
<li data-value="5">$5</li>
<li data-value="1">$1</li>
<li data-value=".5">50¢</li>
<li data-value="0">Free</li>
</ul>
</li>
</ul>
</div>
Hope this helps!

responsive horizontal menu with dropdown menus

I have a horizontal responsive menu that works great, here is link to the page with it
I tried to make a new one with dropdown menus but can't get it to work. Instead of having a dropdown appear on hover, it shows the menus automatically in the line below. Here is link to codepen showing the errors http://codepen.io/mlegg10/pen/akLaVA
$(document).ready(function() {
$('nav').prepend('<div id="responsive-nav" style="display:none">Menu</div>');
$('#responsive-nav').on('click', function() {
$('nav ul').slideToggle()
});
$(window).resize(function() {
if ($(window).innerWidth() < 768) {
$('nav ul li').css('display', 'block');
$('nav ul').hide()
$('#responsive-nav').show()
} else {
$('nav ul li').css('display', 'inline-block');
$('nav ul').show()
$('#responsive-nav').hide()
}
});
$(window).resize();
});
$(document).on('scroll', function() {
if ($(document).scrollTop() > 100) {
$('#nav').addClass('fixed')
} else {
$('#nav').removeClass('fixed')
}
});
body {
margin: 0;
font-family: Georgia;
}
#menu-bar {
width: 100%;
height: auto;
margin: 50px auto 0;
background-color: #ff4500;
text-align: center;
}
#header h1 {
padding: 15px 0;
margin: 0;
}
#nav {
background-color: #036;
text-align: center;
}
#nav ul {
list-style: none;
padding: 0;
margin: 0
}
#nav ul li {
display: inline-block;
padding: 5px 0;
margin: 0;
}
#nav.fixed {
width: 100%;
position: fixed;
top: 0;
left: 0;
}
nav ul li a {
padding: 0 5px;
text-decoration: none;
color: #fff;
}
nav ul li:hover {
background-color: #ff0000;
}
#responsive-nav {
cursor: pointer;
color: #fff;
font-family: Georgia;
font-weight: bold;
padding: 5px 0;
}
#content {
width: 90%;
margin: 0 auto 20px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
border: 1px solid #ddd;
padding: 5px;
}
#drop-nav li ul li {
border-top: 0px;
#drop-nav li ul li {
border-top: 0px;
}
ul li a {
display: block;
background: #036;
padding: 5px 10px 5px 10px;
text-decoration: none;
white-space: nowrap;
color: #fff;
}
ul li a:hover {
background: #f00;
}
**this part is in the head tags:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://responsive-nav.com/demo/responsive-nav.js"></script>**
<header id="menu-bar">
<nav id="nav">
<ul>
<li>Home
</li>
<li>Accomodations
</li>
<li>Amenities
</li>
<li>Rates
</li>
<li>Links
<ul>
<li>Dropwdown 1
</li>
<li>Dropdown 2
</li>
</ul>
</li>
<li>Contact
</li>
</ul>
</nav>
</header>
Your javascript code has lots of unclosed line endings - you are missing the semicolons quiet often.
Additionally, jQuery will apply nav ul to all elements it finds. Meaning if there is a second occurrence, which is the case in your case, it will be applied to that too.
Instead: you should give your level 0 menu a clean, identifiable class, which you can preciesly target:
<!-- Your new HTML Markup -->
<nav class="mother-of-all-dropdown-lists">
and then in your jQuery:
$('.mother-of-all-dropdown-lists').slideToggle();
Sorry, that I keep writing, there are jQuery selectors wrong as well:
The id / hashtag is missing, so..:
$('nav ul li').css('display','inline-block');
$('nav ul').show()
should be:
$('#nav ul li').css('display','inline-block');
$('#nav ul').show();

Mobile Sub Navigation not expanding out half of the time

I have been following this and I have very minimal knowledge of JavaScript or of jQuery as of yet. I have run into a problem when developing a website with the use of the above tutorial to make a responsive mob navigation.
The Problem: Depending on what size the browser was when launching my html document the sub navigation toggle doesn't (It goes straight to the link instead of opening the sub navigation menu) work if the browser was launched in the range of around 600px's, but works when launched at a smaller screen sized or shrunked down (sometimes). I have been trying to figure out how to fix this problem
My code (Tried keeping it minamil, sorry):
$(document).ready(function() {
//Creating the show/hide function with jQuery Toggle
$("#navToggle a").on ('click', function(event){
event.preventDefault();
$("header > nav").slideToggle("medium");
$("#logo").toggleClass("menuUp menuDown");
});
//Tidying up the Navigation Menu
$(window).resize(function() {
if($( window ).width() >= "600") {
$("header > nav").css("display", "block");
$("header > nav > ul > li > a").siblings().removeAttr("style");
if($("#logo").attr('class') == "menuDown") {
$("#logo").toggleClass("menuUp menuDown");
}
}
else {
$("header > nav").css("display", "none");
//document.getElementById("categories").href = "categories/index.html";
}
});
//Creating the Drop Down Menu for Mobile Devices
$("header > nav > ul > li > a").click(function(e) {
if($( window ).width() <= "600") {
if($(this).siblings().size() > 0 ) {
event.preventDefault();
$(this).siblings().slideToggle("fast")
$(this).children(".toggle").html($(this).children(".toggle").html() == 'close' ? 'expand' : 'close');
}
}
});
});
.clearfix:before,
.clearfix:after {
content: " ";
display: table;
}
.clearfix:after {
clear: both;
visibility: hidden;
}
.clearfix {
*zoom: 1;
}
/* Navigation */
/* Mobile */
header > div#logo {
line-height: 70px;
position: relative;
}
header > .menuDown {
box-shadow: 0 3px 5px rgba(0,0,0,.15);
}
header > .menuUp {
box-shadow: none;
}
header > div#logo > h1 {
font-size: 48px; font-size: 3rem; /* 48px fallback */
font-weight: bold;
text-rendering: optimizeLegibility;
}
header > div#logo > div#navToggle {
background-color: rgba(0,0,0,.15);
position: absolute;
right: 0;
top: 0;
transition: 300ms all ease;
}
header > div#logo > div#navToggle:hover {
background-color: rgba(0,0,0,.1);
}
header > div#logo > div#navToggle > a {
color: rgba(255,255,255,.85);
display: block;
font-size: 0.85em;
font-weight: 600;
padding: 0 2.5rem;
text-decoration: none;
transition: 300ms all ease;
}
header > div#logo > div#navToggle:hover > a {
color: rgba(255,255,255,1);
}
header > nav {
background-color: rgba(0,0,0,0.20);
display: none;
flex: 1;
transform: 300ms all ease;
}
header nav > ul {
list-style-type: none;
}
header nav > ul > li {
border-bottom: 1px dotted rgba(0,0,0,.1);
position: relative;
}
header nav > ul > li:last-of-type {
border-bottom: none;
}
header nav > ul > li > a {
display: block;
color: rgba(0,0,0,.65);
font-weight: 700;
padding: 1.5rem 0;
text-decoration: none;
transition: 250ms all ease;
}
header nav > ul > li > a:visited {
color: rgba(0,0,0,.65);
}
header nav > ul > li > a span.toggle {
background-color: rgba(0,0,0,.05);
border-radius: 3rem;
color: rgba(0,0,0,.25);
font-size: 0.75em;
font-weight: 500;
padding: 2px 8px;
text-transform: lowercase;
}
header nav > ul > li > a span.caret {
display: none;
}
header > nav > ul > li:hover > a {
color: rgb(140, 193, 193);
}
header > nav > ul > li > nav {
background-color: rgb(51,51,51);
border-radius: 1.5em;
box-shadow: 0 2px 8px rgba(0,0,0,.6);
display: none;
overflow: hidden;
position: absolute;
right: 5%;
width: 90%;
z-index: 100;
text-align: left;
}
header > nav > ul > li > nav > ul > li > a {
color: rgba(255,255,255,.85);
transition: 300ms all ease;
font-size: 14px; /* Modify till find correct size */
}
header > nav > ul > li > nav > ul > li > a:visited {
color: rgba(255,255,255,.85);
}
header > nav > ul > li > nav > ul > li:hover > a {
background-color: rgba(0,0,0,.6);
color: rgba(255,255,255,1);
}
#media only screen and (min-width: 48rem) {
/* For tablets #768px: */
header > div#logo > div#navToggle {
display: none;
}
header {
background-color: white;
flex-direction: row;
line-height: 90px;
padding: 0 3rem;
position: fixed;
width: 100%;
display:inline;
}
header > div#logo {
background-color: transparent;
line-height: 90px;
}
header > div#logo > h1 {
color: rgb(140, 193, 193);
}
header > nav {
background-color: transparent;
display: block;
}
header > nav > ul {
display: flex;
flex-flow: row wrap;
justify-content:space-around;
}
header nav > ul > li {
border-bottom: none;
}
header nav > ul > li > a {
padding: 0 1.25rem;
}
header nav > ul > li > a span.toggle {
display: none;
}
header nav > ul > li > a span.caret {
border-bottom: 4px solid transparent;
border-top: 4px solid rgba(0,0,0,.65);
border-right: 4px solid transparent;
border-left: 4px solid transparent;
border-radius: 1px;
content: "";
display: inline-block;
height: 0;
margin: 0 0 0 .25rem;
transition: 250ms all ease;
width: 0;
vertical-align: middle;
}
header nav > ul > li:hover > a span.caret {
border-top-color: rgb(140, 193, 193);
transform: rotate(270deg);
}
header > nav > ul > li:hover > nav {
background-color: rgb(51,51,51);
border-radius: .25em;
box-shadow: 0 2px 8px rgba(0,0,0,.6);
display: block;
line-height: 3em;
right: -50%;
width: 12.25rem; /* 196px */
}
}
#media screen and (min-width: 95.625rem) {
header {
display:flex
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<body>
<head>
<meta charset="utf-8">
<meta name="description" content="Daily technology walkthroughs for everyones needs ">
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>The Daily Tech Walkthroughs</title>
</head>
<header class="clearfix">
<div id="logo" class="menuUp">
<h1> The Daily Tech <br> Walkthroughs </h1>
<div id="navToggle">Menu</div>
</div>
<nav class="clearfix primary-nav">
<ul>
<li>Home</li>
<li>Walkthroughs</li>
<li id="mobile-version-click">
Categories <span class="toggle">Expand</span><span class="caret"></span>
<nav>
<ul>
<li>All Categories</li>
<li>Computers</li>
<li>Consoles</li>
<li>Phones and Tablets</li>
<li>Gadgets</li>
<li>Other Technology</li>
</ul>
</nav>
</li>
<li>Create a Walkthrough</li>
<li>Help</li>
<li>About</li>
<li id="mobile-version-click">
User <span class="toggle">Expand</span><span class="caret"></span>
<nav>
<ul>
<li>Profile</li>
<li>Settings</li>
<li>Logout</li>
</ul>
</nav>
</li>
<li><div class="search"><input type="search" placeholder="search..." /></div></li>
</ul>
</nav>
</header>
</body>
</html>
The Problem was a stupid oversight on my part, I had forgot to change my screen size values in my javascript, after I had change my breakpoints in my css. The valuse had to change from 600px to 767px for the javascript to work.
Changes to the javascript below.
$(document).ready(function() {
//Creating the show/hide function with jQuery Toggle
$("#navToggle a").on ('click', function(event){
event.preventDefault();
$("header > nav").slideToggle("medium");
$("#logo").toggleClass("menuUp menuDown");
});
//Tidying up the Navigation Menu
$(window).resize(function() {
if($( window ).width() >= "767") {
$("header > nav").css("display", "block");
$("header > nav > ul > li > a").siblings().removeAttr("style");
if($("#logo").attr('class') == "menuDown") {
$("#logo").toggleClass("menuUp menuDown");
}
}
else {
$("header > nav").css("display", "none");
//document.getElementById("categories").href = "categories/index.html";
}
});
//Creating the Drop Down Menu for Mobile Devices
$("header > nav > ul > li > a").click(function(e) {
if($( window ).width() <= "767") {
if($(this).siblings().size() > 0 ) {
event.preventDefault();
$(this).siblings().slideToggle("fast")
$(this).children(".toggle").html($(this).children(".toggle").html() == 'close' ? 'expand' : 'close');
}
}
});
});

Why is the sub-menu in this accordion menu not staying open?

I adapted a menu from CSS MenuMaker, and I've been hunting for why it behaves differently. It is here. When you click on the menu item, the sub-menu opens, but if the mouse remains over the clicked menu item, the rest doesn't move down to make room, and the sub-menu doesn't use the styling it is supposed to. Instead it uses the styling of a top-level menu item.
HTML
<div class="col-2 col-m-2 accordian darkYellow roundLeft">
<p class="title">Melt-in-Place Station (MIP)
</p>
<ul>
<li class="has-sub"><a><span>Reference Docs</span></a>
<ul>
<li><a href="http://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20150000305.pdf">
<span>Melted regolith construction</span></a></li>
</ul>
</li>
<li class="has-sub"><a><span>Forum Threads</span></a></li>
<li class="has-sub"><a><span>Models</span></a></li>
</ul>
</div>
CSS
.accordian,
.accordian ul,
.accordian li,
.accordian a {
margin: 0;
padding: 0;
border: 0;
list-style: none;
text-decoration: none;
line-height: 1;
font-size: 1em;
position: relative;
color: yellow;
}
p.title {
font-weight: 600;
padding: 16px 6px;
}
.accordian a {
line-height: 1.3;
cursor: pointer;
}
.accordian {
font-weight: 400;
color: rgba(255, 255, 0, 1);
text-align: right;
}
.accordian > ul > li {
margin: 0 0 2px 0;
}
.accordian > ul > li:last-child {
margin: 0;
}
.accordian > ul > li > a {
font-size: 1.1em;
display: block;
background: rgba(50, 50, 50, 0.6);
}
.accordian > ul > li > a > span {
display: block;
padding: 6px 10px;
}
.accordian > ul > li > a:hover {
text-decoration: none;
}
.accordian > ul > li.active {
border-bottom: none;
}
.accordian > ul > li.active > a {
background: #333;
}
.accordian > ul > li.has-sub > a span {
background: url(http://www.moonwards.com/img/iconPlus.png) no-repeat left center;
}
.accordian > ul > li.has-sub.active > a span {
background: url(http://www.moonwards.com/img/iconMinus.png) no-repeat left center;
}
/* Sub menu */
.accordian ul ul {
padding: 5px 12px;
display: none;
}
.accordian ul ul li {
padding: 3px 0;
}
.accordian ul ul a {
display: block;
font-size: 0.9em;
font-weight: 400italic;
}
jQuery
( function( $ ) {
$( document ).ready(function() {
$('.accordian > ul > li > a').click(function() {
$('.accordian li').removeClass('active');
$(this).closest('li').addClass('active');
var checkElement = $(this).next();
if((checkElement.is('ul')) && (checkElement.is(':visible'))) {
$(this).closest('li').removeClass('active');
checkElement.slideUp('normal');
}
if((checkElement.is('ul')) && (!checkElement.is(':visible'))) {
$('.accordian ul ul:visible').slideUp('normal');
checkElement.slideDown('normal');
}
if($(this).closest('li').find('ul').children().length == 0) {
return true;
} else {
return false;
}
});
});
} )( jQuery );
I assume this is some dumb thing, but any help appreciated.
After inspecting I think I found the culprit. Try edit your CSS like this:
li:hover ul {
display: block;
position: relative; /* relative, not absolute */
top: 100%;
left: -10px;
background-color: rgba(50, 50, 0, 1);
font-size: 13px;
}
Your problem is not entirely CSS. I just figured out that the LI's height is covering the dropdown. However, if you reduce the height of the LI, the next LI doesn't open the amount it needs to. A quick patch would be to apply this CSS below however, I would much rather get the JQuery guys here to help you out.
.accordian ul ul {
padding: 5px 12px;
display: none;
margin-top: 0px;
z-index: 99999;
position: relative;
background: none;
}
p.s. This solves the problem you asked, but you need to tweak the font and size so that there is no difference

Categories

Resources