Dropdown menu hidden within navbar - javascript

i'm doing a project in which I have to make a website from scratch using no frameworks. The problem i'm having is that I'd like to make a navigation bar that can collapse down on mobile devices aswell as have a dropdown menu on a desktop.
I've managed to get it properly working for mobile devices, but when on a desktop the dropdown menus just hide within the nav bar container. I believe this is a problem where the height isn't adjusting for the dropdown, but i'm not too sure how i'd fix it. The navigation bar has to be fixed to the top, collapse when below 900px and the dropdowns must be visible when hovering over them.
The Website in question is
http://www.ico.mmu.ac.uk/13143651/webdev/
CSS
nav {
background-color: #b8b8b8;
font-family: arial;
position: fixed;
top: 0;
z-index:999;
text-decoration: none;
width: 100%;
padding:0px;
overflow:auto;
margin:0px;
clear:both;
}
HTML
<nav role="navigation">
<ul class="slimmenu" id="navigation">
<li>
Courses
<ul>
<li>Digital Media</li>
<li>Web Development</li>
<li>Journalism</li>
<li>Information Communications</li>
</ul>
</li>
<li>
Facilities
<ul>
<li>Societies</li>
<li>Jobs and Placements</li>
<li>Library</li>
</ul>
</li>
<li>
Manchester and Student Life
<ul>
<li>Travel</li>
<li>Attractions</li>
<li>Nightlife</li>
</ul>
</li>
<li>
Student Help
<ul>
<li>Finance</li>
<li>Student Union</li>
<li>Assistance</li>
</ul>
</li>
<li>Contact</li>
</nav>
Thanks in advance.

In your css, change your .nav overflow rule.
From
overflow: auto
to
overflow: visible

It's hard to know what the desired behaviour is, but you can try variations on this:
ul.slimmenu li > ul{
position: fixed;
top: 50px;
left: none;
}

Related

Open child div on hover parent and close other child divs ( w/ Javascript)

When I open a child div on hover with Javascript it works, also when I hover over the next parent div that child div opens but when I go back to the first parent the second one stays open (on top) and doesn't fade-out.
What I would like is that the other child div('s) close when hovering to a new one. Maybe good to know is that I only want the other child div(s) to close when hovering to a new parent with a child div not when im just hovering out of the current parent.
Does anyone know the trick?
$('li.menu-item-has-children').hover(function () {
$('ul.dropdown-menu-main', this).fadeIn('slow');
});
ul, ul li {
list-style:none;
padding:0;
margin:0;
}
li {
display: inline-block;
position: relative;
margin-right:20px !important;
}
ul.dropdown-menu-main {
display:none;
position:fixed;
top:0px;
left:0px;
width:100%;
height:100vh;
background:black;
z-index:-1;
padding:50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="menu-item-has-children">
<a href="#">Main 1</div>
<ul class="dropdown-menu-main">
<li>Sub 1</li>
</ul>
</li>
<li class="menu-item-has-children">
<a href="#">Main 2</div>
<ul class="dropdown-menu-main">
<li>Sub 2</li>
</ul>
</li>
</ul>
I found the solution when 'parent()' and 'children()' are not 'this'.
$('li.menu-item-has-children').hover(function () {
$('ul.dropdown-menu-main', this).fadeIn('slow');
$(this).parent().children().not(this).find('ul.dropdown-menu-main').fadeOut('fast');
});
ul, ul li {
list-style:none;
padding:0;
margin:0;
}
li {
display: inline-block;
position: relative;
margin-right:20px !important;
}
ul.dropdown-menu-main {
display:none;
position:fixed;
top:0px;
left:0px;
width:100%;
height:100vh;
background:black;
z-index:-1;
padding:50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="menu-item-has-children">
<a href="#">Main 1</div>
<ul class="dropdown-menu-main">
<li>Sub 1</li>
</ul>
</li>
<li class="menu-item-has-children">
<a href="#">Main 2</div>
<ul class="dropdown-menu-main">
<li>Sub 2</li>
</ul>
</li>
</ul>
Sorry have just re-read your question and realised you wanted the menu to stay active. I've created a demonstration which does this by adding an .active class and toggling the submenus are you initially wanted using fadeIn and fadeOut. This will also allow you to attribute css styles to the dropdown if you would rather use that rather than jquery.
// Toggle function on hover, ignore if already active
$(".menu-item-has-children:not('.active')").hover( function() {
// Remove active class from all menus
$(".menu-item-has-children.active").toggleClass();
// Add toggle class to this menu
$(this).toggleClass("active");
// Fade out existing dropdown menus
$(".dropdown-menu-main").fadeOut('slow');
// Fade in this child dropdown menu
$(this).find(".dropdown-menu-main").fadeIn('slow');
});
The second example I will leave up for others, it shows how to do a more traditional dropdown where it fades out once the hover leaves the parent. You can use the exit function as well as the entry function of hover, the first function you provide is ran on mouseenter and the second on mouseleave.
Jquery .hover()
EXAMPLE WITH PERSISTENT DROPDOWNS
// Toggle function on hover, ignore if already active
$(".menu-item-has-children:not('.active')").hover( function() {
// Remove active class from all menus
$(".menu-item-has-children.active").toggleClass();
// Add toggle class to this menu
$(this).toggleClass("active");
// Fade out existing dropdown menus
$(".dropdown-menu-main").fadeOut('slow');
// Fade in this child dropdown menu
$(this).find(".dropdown-menu-main").fadeIn('slow');
});
ul, ul li {
list-style:none;
padding:0;
margin:0;
}
li {
display: inline-block;
position: relative;
margin-right:20px !important;
}
ul.dropdown-menu-main {
display:none;
position:fixed;
top:0px;
left:0px;
width:100%;
height:100vh;
background:black;
z-index:-1;
padding:50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="menu-item-has-children">
<a href="#">Main 1</div>
<ul class="dropdown-menu-main">
<li>Sub 1</li>
</ul>
</li>
<li class="menu-item-has-children">
<a href="#">Main 2</div>
<ul class="dropdown-menu-main">
<li>Sub 2</li>
</ul>
</li>
</ul>
EXAMPLE WITH TRADITIONAL DROPDOWNS
These collapse when the hovering over the parent ends.
// Hover function
$('li.menu-item-has-children').hover(
// Hover in function
function() {
$('ul.dropdown-menu-main', this).fadeIn('slow');
},
// Hover exit function
function() {
$('ul.dropdown-menu-main', this).fadeOut('slow');
}
);
ul,
ul li {
list-style: none;
padding: 0;
margin: 0;
}
li {
display: inline-block;
position: relative;
margin-right: 20px !important;
}
ul.dropdown-menu-main {
display: none;
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 100vh;
background: black;
z-index: -1;
padding: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="menu-item-has-children">
<a href="#">Main 1</div>
<ul class="dropdown-menu-main">
<li>Sub 1</li>
</ul>
</li>
<li class="menu-item-has-children">
<a href="#">Main 2</div>
<ul class="dropdown-menu-main">
<li>Sub 2</li>
</ul>
</li>
</ul>

How can I scroll to an element inside a scrollable div?

I have a parent container which has two child elements. The left element is a list of items returned from a database query. The parent container has a fixed height, so any items returned in the left panel are scrollable within that left panel, not the body.
When navigating to this page, I would like for the left panel to be positioned at the point of a matching element ID. This ID i will handle through Angular's routing subscriptions, but for demo purposes I have hard coded it here.
I have tried the code below (primarily the JS) with no luck. Any assistance would be greatly appreciated.
var list = document.getElementById("list");
var targetLi = document.getElementById('myID');
list.scrollTop = (targetLi.offsetTop - 50);
#wrapper {
width:1280px;
height:600px;
border:1px solid #d9d9d9;
border-radius:5px;
display:flex;
margin:20px auto;
}
#list {
width:200px;
height:100%;
border-right:1px solid #d9d9d9;
display:flex;
overflow:hidden;
}
#right span {
color:#999;
font-size:12px;
font-family:helvetica;
}
ul {
width:100%;
margin:0;
padding:0;
list-style:none;
overflow-y: scroll;
}
li {
width:100%;
padding:20px 10px;
box-sizing:border-box;
border-bottom:1px solid #d9d9d9;
display:block;
font-family:helvetica;
color:#666;
}
<div id="wrapper">
<div id="list">
<ul>
<li>
Item
</li>
<li>
Item
</li>
<li>
Item
</li> <li>
Item
</li> <li>
Item
</li>
<li>
Item
</li>
<li>
Item
</li>
<li>
Item
</li>
<li>
Item
</li>
<li>
Item
</li>
<li>
Item
</li>
<li>
Item
</li>
<li>
Item
</li>
<li>
Item
</li>
<li>
Item
</li>
<li id="myID">
Item with ID
</li>
</ul>
</div>
<div id="right">
<button id="button">Demo purposes button</button>
<span> Note: this would instead be called in 'ngAfterViewInit' or after the firestore query has completed.
</div>
</div>
The best (and AFAIK only) option that will work across all browsers is to implement a hidden input element (like a checkbox for example) and set the focus to that element. This way the browser will scroll the container so that the focused input is visible. The trick is not to set the styling to display: none but only make the element optically invisible, for example:
opacity: 0;
width: 0;
height: 0;
display: block;

hover-menu in right side of fixed div

I have a div with a fixed position (a top panel) which shall also contain a settings menu at the far right (currently via floating).
When hovering over the settings-image, I want to display a menu below the image.
I want the menu to be aligned to the right side just like the image.
<div id="panel" style="position:fixed">
<panel-entry 1>
<panel-entry 2>
<panel-entry n>
<div id="settings" style="float:right/snapped to the right side>
<img src=settings>
<ul>
<li>setting 1</li>
<li>setting 2</li>
<li>setting n</li>
</ul>
</div>
</div>
Any idea using jQuery very much appreciated, feel free to rearrange any html.
No jQuery necessary, just give your #panel a width:
#panel {
position: fixed;
width: 100%;
}
#settings {
float: right;
}
See DEMO.
Aside from your example not being HTML, I would anyhow correct the conceptual approach. There is no jQuery required for such a task, which can be done entirely in CSS.
You want your #panel to first of all contain a <ul> which will contain <li>s, which will be your <panel-entry>, those should be set as inline-block.
The #settings should be one of those, perhaps with a special class or id (we'll keep settings for now). You can position: absolute this to right: 0, or have it float. Don't use an image element for this, but rather use a background-image.
Inside this element, you will have a submenu: i.e. another <ul> with display: none, a position:absolute, right: 0 and top: X, so that X doesn't overlap with your #panel.
Next, you want to make the element visible on :hover of li#settings.
Here's a working demo
Basic HTML
<div id="panel">
<ul>
<li>Panel entry 1</li>
<li>Panel entry 2</li>
<li>Panel entry n</li>
<li id="settings">
<ul>
<li>setting 1</li>
<li>setting 2</li>
<li>setting n</li>
</ul>
</li>
</ul>
</div>
Basic CSS
#panel {
position: fixed;
top: 0;
width: 100%;
}
#panel > ul > li {
display: inline-block;
}
#panel > ul > li > ul {
display: none;
position: absolute;
top: {X};
right: 0;
}
li#settings {
background: url({youricon}) no-repeat top center;
position: absolute;
right: 0;
min-width: {youricon-x};
min-height: {youricon-y};
}
li#settings:hover > ul{
display: block;
}

CSS Dynamic Navigation with Hover - How Do I make it work in iOS Safari?

In my site I use a CSS only dynamic menu. This is fine in desktop browsers, but not on iOS (iphone, ipad, etc) because the touch interface does not support the :hover selector.
My question is: what is the best way of supporting this on iOS? (Ideally either by patching with some CSS, or Javascript that will make the existing code work, rather than doing the whole thing over just to support iOS)
My html looks like this
<ul id="nav">
<li>
Item 1
<ul>
<li><a href=''>sub nav 1.1</a></li>
<li><a href=''>sub nav 1.2</a></li>
</ul>
</li>
<li>
Item 2
<ul>
<li><a href=''>sub nav 2.1</a></li>
<li><a href=''>sub nav 2.2</a></li>
</ul>
</li>
<li>
Item 3
<ul>
<li><a href=''>sub nav 3.1</a></li>
<li><a href=''>sub nav 3.2</a></li>
</ul>
</li>
</ul> ​​​​​
And the CSS is this
#nav li {
float:left;
padding:0 15px;
}
#nav li ul {
position: absolute;
width: 10em;
left: -999em;
margin-left: -10px;
}
#nav li:hover ul {
left: auto;
}
I have done a jsfiddle of this here: http://jsfiddle.net/NuTz4/
Check this article, perhaps it's a solution for you ;)
http://www.usabilitypost.com/2010/05/12/css-hover-controls-on-iphone/
Also JS solution, taken from: http://www.evotech.net/blog/2008/12/hover-pseudoclass-for-the-iphone/
var nav = document.getElementById('nav');
var els= nav.getElementsByTagName('li');
for(var i = 0; i < els.length; i++){
els[i].addEventListener('touchstart', function(){this.className = "hover";}, false);
els[i].addEventListener('touchend', function(){this.className = "";}, false);
}
In jQuery:
$('#nav li').bind('touchstart', function(){
$(this).addClass('hover');
}).bind('touchend', function(){
$(this).removeClass('hover');
});
css:
li:hover, li.hover { /* whatever your hover effect is */ }

CSS Menu disappear

I created a menu in html/css but where I wanted the subitems to be shown on parent item hover. The problem is when I hover on it in IE it only shows it's subitems when I hover on the text in the menu item, If I hover over the element and not the text the subitems disappear again. So if I hover and want to move my mouse to my submenu the submenu disappears unless I'm fast enough. This is very annoying, does anyone know how I can solve this?
MY menu code is like so:
<ul id="leftnav">
<li><a>Item1</a></li>
<ul>
<li><a href='#'>SubItem1</a></li>
<li><a href='#'>SubItem2</a></li>
<li><a href='#'>SubItem3</a></li>
</ul>
<li><a>Item2</a></li>
<ul>
<li><a href='#'>SubItem1</a></li>
<li><a href='#'>SubItem2</a></li>
<li><a href='#'>SubItem3</a></li>
</ul>
</ul>
The menu should be a left sided menu which shows it's subitems only on hover, so I used css to achieve this with the following code:
#leftnav, #leftnav ul
{
padding: 0;
margin: 0;
}
#leftnav ul li
{
margin-left: 102px;
position: relative;
top: -19px; /*sets the childitems on the same height as the parent item*/
}
#leftnav li
{
float: left;
width: 100px;
}
#leftnav ul
{
position: absolute;
width: 100px;
left: -1000px; /*makes it disappear*/
}
#leftnav li:hover ul, #leftnav li.ie_does_hover ul
{
left: auto;
}
#leftnav a
{
display: block;
height: 15px;
margin-top: 2px;
margin-bottom: 2px;
}
Since this only works with firefox I also had to insert a javascript to get this to work in IE using code:
<script language="JavaScript">
sfHover = function()
{
var sfElsE = document.getElementById("leftnav").getElementsByTagName("LI");
for (var i=0; i<sfElsE.length; i++)
{
sfElsE[i].onmouseover=function()
{
this.className+=" ie_does_hover";
}
sfElsE[i].onmouseout=function()
{
this.className=this.className.replace(new RegExp(" ie_does_hover\\b"), "");
}
}
}
if (window.attachEvent) window.attachEvent("onload", sfHover);
</script>
Many many many thanks for replies
In your CSS you have:
#leftnav li:hover ul
Which would mean the rule is applied to ul elements that are children of li elements when that parent li is hovered.
But in your HTML, you have:
<li><a>Item2</a></li>
<ul>
<li><a href='#'>SubItem1</a></li>
</ul>
So the sub item ul is not a child of the item ul, so that rule never comes true. You need to make the sub-items nested to the items. Like this:
<ul id="leftnav">
<li><a>Item1</a>
<ul>
<li><a href='#'>SubItem1</a></li>
<li><a href='#'>SubItem2</a></li>
<li><a href='#'>SubItem3</a></li>
</ul>
</li>
<li><a>Item2</a>
<ul>
<li><a href='#'>SubItem1</a></li>
<li><a href='#'>SubItem2</a></li>
<li><a href='#'>SubItem3</a></li>
</ul>
</li>
</ul>
Notice how I don't close the list item until after the sub-list.
Reinventing the wheel: http://www.htmldog.com/articles/suckerfish/ teaches you about it. They even have a great example.

Categories