I am trying to make a submenu which slides down from the main menu bar when hovering over a certain element. I am currently doing this using the following code:
$(document).ready( function() {
$('.navlist li a').hover( function() {
if( $(this).attr( 'data-param' ) == "parent" )
{
$('#subnavbar-' + $(this).attr( 'data-slug' )).slideDown( 200 );
}
}, function() {
if( $(this).attr( 'data-param' ) == "parent" )
{
var name = '#subnavbar-' + $(this).attr( 'data-slug' );
setTimeout( function() {
if( !$(name).is(':hover') )
{
$(name).slideUp( 200 );
}
}, 200 );
}
});
});
a {
color: white;
}
.navbar {
background-color: green;
margin-bottom: 0;
height: 30px;
}
ul.navlist {
list-style: none;
text-indent: 0;
margin: 0;
padding: 0;
float: left;
}
ul.navlist li {
display: block;
width: 100px;
float: left;
}
.subnavbar {
background-color: blue;
margin-top: 0;
height: 20px;
display: none;
}
ul.subnavlist {
list-style: none;
text-indent: 0;
margin: 0;
padding: 0;
float: left;
}
ul.subnavlist li {
display: block;
width: 80px;
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="navbar">
<ul class="navlist">
<li>Item 1</li>
<li>Hover Here</li>
<li>Item 3</li>
</ul>
</div>
<div class="subnavbar" id="subnavbar-test">
<ul class="subnavlist">
<li>Subitem 1</li>
<li>Subitem 2</li>
<li>Subitem 3</li>
</ul>
</div>
As you can see by running the snippet; it works, but there are lots of bugs that I'm not sure what the best way to iron out are. Firstly, if the user hovers back and forth over the main menu item I don't want the event to be spammed, I could solve this problem using a setTimeout() and clearTimeout() but I'd like a better way if at all possible. Secondly, I'm not sure how best to get the subnavbar not to retract if the user has hovered over it instead of the parent menu item, how I'm doing it at the moment works, but then if the user hovers off, the navbar doesn't retract.
The efficient solution would be using just CSS. Absolutely no JQUERY required! Try this Fiddle.
HTML:
<nav>
<ul>
<li>Item 1</li>
<li>Item 2
<ul>
<li>Sub Item 1</li>
<li>Sub Item 2</li>
<li>Sub Item 3
<ul>
<li>Sub Sub Item 1</li>
<li>Sub Sub Item 2</li>
</ul>
</li>
</ul>
</li>
<li>Item 3
<ul>
<li>Sub Item 1</li>
<li>Sub Item 2</li>
</ul>
</li>
</ul>
</nav>
CSS Code:
nav {
margin: 100px auto;
text-align: center;
}
nav ul ul {
display: none;
}
nav ul li:hover > ul {
display: block;
}
nav ul {
background: -moz-linear-gradient(center top , #efefef 0%, #bbbbbb 100%) repeat scroll 0 0 rgba(0, 0, 0, 0);
border-radius: 10px;
box-shadow: 0 0 9px rgba(0, 0, 0, 0.15);
display: inline-table;
list-style: outside none none;
padding: 0 10px;
position: relative;
}
nav ul::after {
clear: both;
content: "";
display: block;
}
nav ul li {
float: left;
}
nav ul li:hover {
background: -moz-linear-gradient(center top , #4f5964 0%, #5f6975 40%) repeat scroll 0 0 rgba(0, 0, 0, 0);
}
nav ul li:hover a {
color: #fff;
}
nav ul li a {
color: #757575;
display: block;
padding: 15px 20px;
text-decoration: none;
}
nav ul ul {
background: none repeat scroll 0 0 #5f6975;
border-radius: 0;
padding: 0;
position: absolute;
top: 100%;
}
nav ul ul li {
border-bottom: 1px solid #575f6a;
border-top: 1px solid #6b727c;
float: none;
position: relative;
}
nav ul ul li a {
color: #fff;
padding: 5px 10px;
}
nav ul ul li a:hover {
background: none repeat scroll 0 0 #4b545f;
}
nav ul ul ul {
left: 100%;
position: absolute;
top: 0;
}
as you told me better css I've made a quick fiddle for you.
Of course you need to polish the style but the "working" is there.
css just:
.container {
height:30px;
background-color:green;
color:#fff;
}
.container > ul {position:relative;}
.container > ul li {
display:inline-block;
margin-right:30px;
}
.container > ul >li > ul {
position:absolute;
left:0;
background-color:blue;
top:0px;
z-index:-1;
}
.container > ul > li:hover > ul {
top:30px;
-webkit-transition: all 0.4s ease;
-moz-transition: all 0.4s ease;
-ms-transition: all 0.4s ease;
-o-transition: all 0.4s ease;
transition: all 0.4s ease;
}
edited: I change the aproach and insteed of makign the transition with height I've use just top. check it out
to solve your first issue I would recommend using the jQuery plugin Hover Intent. Like the name suggests, this provides an easy way to determine if the user intends to hover over the element and avoids the possibility of spamming the animation by quickly hovering in and out of the element multiple times.
To solve your second issue, if possible, you can add a containing element around both navbar and subnavbar and use that to close the subnavbar when you leave the containing element, if the subnavbar happens to be visible.
HTML:
<div id="containing_element">
<div class="navbar">
<ul class="navlist">
<li>Item 1</li>
<li>Hover Here</li>
<li>Item 3</li>
</ul>
</div>
<div class="subnavbar" id="subnavbar-test">
<ul class="subnavlist">
<li>Subitem 1</li>
<li>Subitem 2</li>
<li>Subitem 3</li>
</ul>
</div>
</div>
jQuery:
$(document).ready( function() {
function hoverEnter() {
$('#subnavbar-test').slideDown(200);
}
$('#hoverlink').hoverIntent( hoverEnter );
$('#containing_element').mouseleave(function () {
if($('#subnavbar-test').is(':visible')) {
$('#subnavbar-test').slideUp(200);
}
});
});
Remember to include the script for hover intent as well.
Related
I've been looking around here for an example drop down nav menu that does three things:
When the user CLICK on the menu drop it shows the drop down (this works)
When the user CLICKS outside of the nav area or anywhere else on the page is closes an open drops (this works too)
When a user CLICKS on another drop down if one is already open, it closes the previously open drop and opens the new drop menu. <-(I'm stuck here).
Currently if you click on one drop menu, then click on another, the first stays open. I want any other menus that are open to close if you click on another drop down. But i want to retain the behavior that when the user clicks outside of the menu anywhere in the document it closes too.
I've found several SO posts that solve some of this. However sometimes they nav bar only has 1 drop down as an example. Other times for some reason the solution causes other issues in my nav. So i decided to create a new post.
Please note that i'm learning JS and jquery now.
Here is my code:
$(document).ready(function() {
$('.dropdown').click(function(e) {
e.stopPropagation();
// hide all dropdown that may be visible -
// this works but it breaks the functionality of toggling open and closed
// when you click on the menu item
e.preventDefault();
// close when click outside
$(this).find('.dropdown-content').toggleClass('open')
});
// Close dropdown when u click outside of the nav ul
$(document).click(function(e) {
if (!e.target.closest("ul") && $(".dropdown-content").hasClass("open")) {
$(".dropdown-content").removeClass("open");
}
})
});
.nav__topbar {
position: relative;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
min-height: 2em;
background: #fff;
}
.nav__links {
overflow: hidden;
display: flex;
align-items: center;
margin-left: auto!important;
a {
float: left;
display: block;
text-align: center;
padding: 14px 16px;
text-decoration: none;
&:hover {
color: #ccc;
}
}
.icon {
display: none;
}
}
.nav__links .dropdown .dropdown-content {
position: absolute;
max-width: 25%;
}
.dropdown .dropbtn,
.nav__links a {
font-size: 1.5em!important;
color: #222;
}
/* Upon click the menu should turn into a vertical stacked menu with a soft drop shadow */
.nav__links.vertical {
position: absolute;
display: flex;
flex-direction: column;
align-items: flex-start;
padding-top: 2em;
top: 50%;
left: 70%;
background-color: #fff;
z-index: 1;
border: 1px solid #f2f3f3;
border-radius: 4px;
background: #fff;
-webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
}
.dropdown {
float: left;
overflow: hidden;
}
/* Codepen doesn't like when i nest styles */
.dropdown .dropbtn {
border: none;
outline: none;
padding: 14px 16px;
background-color: inherit;
font-family: inherit;
margin: 0;
}
.dropdown {
cursor: pointer;
display: block;
&:hover {
background-color: #444;
}
}
/* Style the dropdown content (hidden by default) */
.dropdown-content {
display: none;
background-color: #fff;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
width: 100%;
transition: all 0.25s ease-in;
transform: translateY(-10px);
}
/* Style the links inside the dropdown codepen doesn't like my nesting */
.dropdown-content a {
float: none;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-content li,
.nav__links li,
.nav__links li a {
list-style-type: none;
text-decoration: none;
}
.dropdown li {
padding: 20px
}
.dropdown .dropdown-content.open {
display: block;
padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav class="nav__topbar">
<ul class="nav__links">
<li class="dropdown" data-hover="title">
<button class="dropbtn">community <span class="downBtn">▼</span>
</button>
<ul class="dropdown-content">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
</li>
<li>Menu item 2</li>
<li class="dropdown" data-hover="title">
<button class="dropbtn">menu <span class="downBtn">▼</span>
</button>
<ul class="dropdown-content">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
</li>
<li class="dropdown" data-hover="title">
<button class="dropbtn">menu <span class="downBtn">▼</span>
</button>
<ul class="dropdown-content">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
</li>
</ul>
</nav>
And here [is a codepen](https://codepen.io/lwasser/pen/BaVKYNX as well with the same code in case you want to play with the code.
UPDATE: the code above works with the fixes provided in the accepted answer below! The code had another bug which was drop down links didn't work. but i was able to remove / fix that by removing:
e.stopPropagation();
e.preventDefault();
Many thanks for the folks who helped below!! And i'll try to fully update my codepen with the hamburger as well as soon as I can in case that helps people.
You are almost there!
Store in a var the clicked element.
Remove the open class name from all elements except the clicked one.
Toggle the open class of the clicked element.
$(document).ready(function () {
$(".dropdown").click(function (e) {
e.stopPropagation();
e.preventDefault();
// 1. Store in a var the clicked element
var current_dropdown = $(this).find(".dropdown-content");
$(".dropdown-content").each(function() {
var element = $(this);
// 2. Remove the `open` class name from all elements except the clicked one.
if (!element.is(current_dropdown)) {
$(this).removeClass("open");
}
});
// 3. Toggle the open class of the clicked element.
current_dropdown.toggleClass("open");
});
// Close dropdown when u click outside of the nav ul
$(document).click(function (e) {
if (!e.target.closest("ul") && $(".dropdown-content").hasClass("open")) {
$(".dropdown-content").removeClass("open");
}
});
});
I forked your codepen:
https://codepen.io/Valeriu-Ciuca/pen/KKezYME
While adding the open class, remove open class of the other dropdowns
$(this).siblings('.dropdown').find('.dropdown-content').removeClass('open');
Finding the siblings with dropdown class and removing open class of the corresponding element.
$(document).ready(function () {
$(".dropdown").click(function (e) {
e.stopPropagation();
e.preventDefault();
// close when click outside
$(this).find(".dropdown-content").toggleClass("open");
$(this).siblings('.dropdown').find('.dropdown-content').removeClass('open');
});
// Close dropdown when u click outside of the nav ul
$(document).click(function (e) {
if (!e.target.closest("ul") && $(".dropdown-content").hasClass("open")) {
$(".dropdown-content").removeClass("open");
}
});
});
.nav__topbar {
position: relative;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
min-height: 2em;
background: #fff;
}
.nav__links {
overflow: hidden;
display: flex;
align-items: center;
margin-left: auto!important;
a {
float: left;
display: block;
text-align: center;
padding: 14px 16px;
text-decoration: none;
&:hover {
color: #ccc;
}
}
.icon {
display: none;
}
}
.dropdown .dropbtn, .nav__links a {
font-size: 1.5em!important;
color: #222;
}
/* Upon click the menu should turn into a vertical stacked menu with a soft drop shadow */
.nav__links.vertical {
position: absolute;
display: flex;
flex-direction: column;
align-items: flex-start;
padding-top: 2em;
top: 50%;
left: 70%;
background-color: #fff;
z-index: 1;
border: 1px solid #f2f3f3;
border-radius: 4px;
background: #fff;
-webkit-box-shadow: 0 2px 4px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12);
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12);
}
.dropdown {
float: left;
overflow: hidden;
}
/* Codepen doesn't like when i nest styles */
.dropdown .dropbtn {
border: none;
outline: none;
padding: 14px 16px;
background-color: inherit;
font-family: inherit;
margin: 0;
}
.dropdown {
cursor: pointer;
display: block;
&:hover {
background-color: #444;
}
}
/* Style the dropdown content (hidden by default) */
.dropdown-content {
display: none;
background-color: #fff;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
width: 100%;
transition: all 0.25s ease-in;
transform: translateY(-10px);
}
/* Style the links inside the dropdown codepen doesn't like my nesting */
.dropdown-content a {
float: none;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-content li, .nav__links li, .nav__links li a {
list-style-type: none;
text-decoration: none;
}
.dropdown li {
padding: 20px
}
.dropdown .dropdown-content.open {
display: block;
padding: 0;
}
.nav__links .dropdown .dropdown-content {
position: absolute;
max-width: 25%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><html>
<head>
</head>
<body>
<nav class="nav__topbar">
<ul class="nav__links">
<li class="dropdown" data-hover="title">
<button class="dropbtn">community <span class="downBtn">▼</span>
</button>
<ul class="dropdown-content">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
</li>
<li>Menu item 2</li>
<li class="dropdown" data-hover="title">
<button class="dropbtn">menu <span class="downBtn">▼</span>
</button>
<ul class="dropdown-content">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
</li>
<li class="dropdown" data-hover="title">
<button class="dropbtn">menu <span class="downBtn">▼</span>
</button>
<ul class="dropdown-content">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
</li>
</ul>
</nav>
</body>
</html>
Ok, I have a dropdown list which appears 'on hover', is there a way to change it to have it appear 'on click' instead. Ideally, CSS only, but open to JS options as well. If I could push the boat out further I would also like a cross in the top right-hand corner to close the dropdown list.
I have made a fiddle here so that you can see my current 'on hover' setup
current CSS
ul {
padding: 15px;
list-style: none;
text-align: center;
}
.navigationWrap ul li {
width: 100%;
float: left;
color: #000;
font-size: 16px;
position: relative;
}
.navigationWrap ul li a {
text-decoration: none;
color: #000;
display: block;
}
.navigationWrap ul li a:hover {
color: #000;
background-color: #e6ffe6;
}
.navigationWrap ul li ul.subNav {
position: absolute;
width: 95%;
padding: 10px;
background-color: #fff;
border: #4399fc solid 1px;
display: none;
z-index: 999;
left: 0;
top: 100%;
text-align: left;
max-height: 350px;
overflow: auto;
overflow-x: hidden;
}
.navigationWrap ul li ul.subNav li {
float: left;
width: 100%;
font-size: 20px;
letter-spacing: 1px;
padding-bottom: 10px;
}
.navigationWrap ul li ul.subNav a {
float: left;
width: 100%;
transition: all 0.3s ease-in-out;
display: block;
}
.navigationWrap ul li ul.subNav li a:hover {
color: #000;
padding-left: 10px;
}
.navigationWrap ul li ul.subNav li.active a {
color: #04A000;
}
.navigationWrap ul li.dropdown:hover ul.subNav {
display: block;
}
The HTML code
<div class="navigationWrap">
<ul>
<li class="dropdown">☰ See Options<ul class="subNav">
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
<li>Option 4</li>
<li>Option 5</li>
<li>
<p></p>
</li>
<li>Option 6</li>
<li>Option 7</li>
</ul>
</li>
</ul>
</div>
Many thanks, Jason.
It's very much possible to using JavaScript. I did by jQuery. I closed dropdown if user click outside of the dropdown container.
Here is JS code.
$(function(){
$('.dropdown .dropdown-toggle').on('click', function(e){
e.preventDefault;
e.stopPropagation;
$(this).parents('.dropdown').toggleClass('show');
});
// Remove dropdown if click outside of dropdown
const $menu = $('.dropdown');
$(document).mouseup(e => {
if (!$menu.is(e.target) // if the target of the click isn't the container...
&& $menu.has(e.target).length === 0) // ... nor a descendant of the container
{
$menu.removeClass('show');
}
});
});
CSS change.
/* Before */
.navigationWrap ul li.dropdown:hover ul.subNav {
display: block;
}
/* After */
.navigationWrap ul li.dropdown.show ul.subNav {
display: block;
}
Here is HTML.
<div class="navigationWrap">
<ul>
<li class="dropdown">
<a class="dropdown-toggle" href="javascript:void(0);">☰ See Options</a>
<ul class="subNav">
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
<li>Option 4</li>
<li>Option 5</li>
<li>
<p></p>
</li>
<li>Option 6</li>
<li>Option 7</li>
</ul>
</li>
</ul>
</div>
Here is the CodePen.
You can do this
We toggle class (add/remove) and change display value via css
document.querySelector('.dropdown').onclick = () => {
document.querySelector('.dropdown').classList.toggle('show');
};
If class .show exists then display: block
.navigationWrap ul li.show ul.subNav{
display: block;
}
Check this out
I have to create a drop down with two columns just like the image It should be like when i click on the drop down menu it should display like this so far i am not successful!. This is the sample code i am working with.. if i execute this code it is no where what i am expecting and also i am new to coding.
$(document).ready(function() {
// NAV TOGGLE ONCLICK WITH SLIDE
$(".clickSlide ul").hide();
$(".clickSlide").click(function() {
$(this).children("ul").stop(true, true).slideToggle("fast"),
$(this).toggleClass("dropdown-active");
});
// NAV TOGGLE ONCLICK WITH FADE
$(".clickFade ul").hide();
$(".clickFade").click(function() {
$(this).children("ul").stop(true, true).fadeToggle("fast"),
$(this).toggleClass("dropdown-active");
});
// NAV TOGGLE ONHOVER WITH SLIDE
$(".hoverSlide ul").hide();
$(".hoverSlide").hover(function() {
$(this).children("ul").stop(true, true).slideToggle("fast"),
$(this).toggleClass("dropdown-active");
});
// NAV TOGGLE ONHOVER WITH FADE
$(".hoverFade ul").hide();
$(".hoverFade").hover(function() {
$(this).children("ul").stop(true, true).fadeToggle("fast"),
$(this).toggleClass("dropdown-active");
});
});
/**/
#navbar {
width: 100%;
padding: 10 10 10 10;
}
#dropdown1 {
width: 960px;
margin: 0 auto;
padding: 0;
height: 1em;
font-weight: bold;
}
#dropdown1 li {
list-style: none;
float: left;
}
#dropdown1 li a {
padding: 0px 0px 0px 5px;
text-decoration: none;
}
#dropdown1 li ul {
display: none;
background-color: #fff;
}
#dropdown1 li:hover ul,
#navbar li.hover ul {
display: block;
position: absolute;
margin: 0;
padding: 0;
}
#dropdown1 li:hover li,
#navbar li.hover li {
float: left;
}
#dropdown1 li:hover li a,
#navbar li.hover li a {
background-color: #fff;
color: #000;
}
.topnav a {
color: #000;
text-decoration: none;
}
.topnav a:hover {
border-bottom: 1px solid gold;
}
.column {
display: inline-block;
list-style-type: none;
float: left;
margin: 5px 0 0 0;
padding: 0 5px 0 0;
width: 500px !important;
}
.column li {
float: left;
display: inline;
}
.column a {
color: #999;
text-decoration: none;
font-size: .7em;
}
.column a:hover {
border-bottom: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="navbar">
<ul id=dropdown1>
<li class="topnav">
<div class="column">
Services <span>▼</span>
<ul>
<li>Web hosting</li>
<li>Web builder</li>
<li>Themes</li>
</ul>
</div>
<div class="column">
<ul>
<li>Web hosting</li>
<li>Web builder</li>
<li>Themes</li>
</ul>
</div>
</ul>
</div>
if i understood properly,
This jsfiddle maybe helpful
looks like u use two div but have same class name, then with your css only set "column" .
so the two div will display in same position, that's why u have two div but only display one.
<div class="navbar">
<ul id=dropdown1>
<li class="topnav">
<div class="column">
Services <span>▼</span>
<ul>
<li>Web hosting</li>
<li>Web builder</li>
<li>Themes</li>
</ul>
</div>
<div class="column2">
<ul>
<li>Web hosting</li>
<li>Web builder</li>
<li>Themes</li>
</ul>
</div>
</ul>
then you should set column2's css
UPDATE:
this fiddle
look this fiddle above
i change the li and set
.column a:after{
content:"\a";
white-space: pre;
}
\a means line break, character U+000A, and white-space: pre tells browsers to treat it as a line break in rendering.
found answer here Line break (like <br>) using only css
I have developed drop-down as per your image, without using any plugin.
I am using:
HTML
CSS
Explaination:
I am using table tag to design multiple columns.
<table>
<tr>
<td></td>// for left-col links
<td></td>// for right-col links
</tr>
</table>
Then inside <td> tag I am using <ul><li></li></ul>tag. Inside <li> you can have multiple links.
Similarly I did for right-side column.
Full Code
CSS code
<style>
.dropbtn {
background-color: #4CAF50;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown-content a:hover {background-color: #f1f1f1}
.dropdown:hover .dropdown-content {
display: block;
}
.dropdown:hover .dropbtn {
background-color: #3e8e41;
}
.link-format {
list-style-type:none;
width:100px
}
</style>
HTML code
<body>
<h2>Dropdown Menu with multiple columns</h2>
<p>Move the mouse over the button to open the dropdown menu.</p>
<div class="dropdown">
<button class="dropbtn">Dropdown</button>
<div class="dropdown-content">
<table>
<tr>
<td>
<ul class="link-format" style="border-right:1px gray dashed">
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
<li>Link 4</li>
</ul>
</td>
<td>
<ul class="link-format">
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
<li>Link 4</li>
</ul>
</td>
</tr>
</table>
</div>
</div>
</div>
</body>
Working JsFiddle: https://fiddle.jshell.net/mayankBisht/cvsrqn3r/1/
Hope this helps.
Please reach out to me for more information/help.
Thanks.
I built a CSS collapsible tree structure using the code from this source. I made some changes to remove the "+" and "-" images because it was throwing the formatting out of order, and decided to display the expanded part of the tree by using another folder image (one that's open), like so.
I tried doing this in CSS using the ~ selector, but it doesn't work because the label is right before its associated input. I cannot switch it because then the tree won't expand/contract as expected.
I am exploring the possibility of using Javascript, but since I have around 300 label-checkbox pairs, it doesn't seem feasible to use getElementbyID to get the exact label I'm trying to fix. Is there an easier way to do this?
HTML Code:
<ol class="tree">
<li>
<label for="CB1">Label1</label><input type="checkbox" id="CB1" />
<ol>
<li class="file">File 1</li>
<li class="file">File 2</li>
<li class="file">File 3</li>
</ol>
</li>
</ol>
CSS Code:
ol.tree li.file a
{
background: url(../images/document.png) 0 0 no-repeat;
color: #2D629A;
padding-left: 21px;
text-decoration: none;
display: block;
}
ol.tree li input
{
position: absolute;
opacity: 0;
z-index: 2;
cursor: pointer;
height: 1em;
width: 1em;
top: 0;
}
ol.tree li label
{
background: url(../images/folder-horizontal.png) 15px 1px no-repeat;
cursor: pointer;
display: block;
padding-left: 37px;
}
ol.tree li input:checked ~ label
{
background: url(../images/folder-open.png) 40px 5px no-repeat;
}
First, the <input> element is in the wrong place.
It has to be before the label for it to work.
Second, for it to work properly, you need to set the <ol> to be hidden and then show it when the <input> is checked.
The resulting html:
<ol class="tree">
<li>
<input type="checkbox" id="CB1" /><label for="CB1">Label1</label>
<ol>
<li class="file">File 1</li>
<li class="file">File 2</li>
<li class="file">File 3</li>
</ol>
</li>
</ol>
The new CSS:
ol.tree ol
{
display:none;
}
ol.tree li.file a
{
background: url(../images/document.png) 0 0 no-repeat;
color: #2D629A;
padding-left: 21px;
text-decoration: none;
display: block;
}
ol.tree li input
{
position: absolute;
opacity: 0;
z-index: 2;
cursor: pointer;
height: 1em;
width: 1em;
top: 0;
}
ol.tree li label
{
background: url(../images/folder-horizontal.png) 15px 1px no-repeat;
cursor: pointer;
display: block;
padding-left: 37px;
}
ol.tree li input:checked ~ label
{
background: url(../images/folder-open.png) 40px 5px no-repeat;
}
ol.tree li input:checked ~ ol
{
display:block;
}
See it in action here: http://jsfiddle.net/mjx8t596/1/
Notice:
I didn't touched on the images: I kept the same path and didn't changed any other thing in the code.
So I've made some drop down menus. The drop downs are ul nested in li. For style reasons I need have the drop down height set to 0px with some padding when the page first loads. All my drop downs have different heights. When I put 100% in as the height to animate too, it does not work.
Here is a link: http://www.jasonfoumberg.com/test/writing.html
How do I get the drop downs to animate to the proper height. Each drop down has a different number of items.
jQuery
$(document).ready(function () {
var defHeight = $('ul:first', this).height();
console.log(defHeight);
$("ul li").hover(
function () {
$('ul:first', this).animate({
height: "100%"
});
}, function () {
$('ul:first', this).animate({
height: "0px"
});
});
});
HTML
<div id="mainWrapperContent">
<div id="writingMenu">
<ul>
<li>critical reviews
<ul>
<li>frieze</li>
<li>Modern Painters</li>
<li>photograph</li>
<li>sculpture</li>
<li>NewCity</li>
</ul>
</li>
<li>Exhibition Catalogs
<ul>
<li>Catalog One</li>
<li>Catalog Two</li>
<li>Catalog Three</li>
<li>Catalog Four</li>
<li>Catalog Five</li>
</ul>
</li>
<li>BreakOut Artists
<ul>
<li>2012</li>
<li>2011</li>
<li>2010</li>
<li>2009</li>
<li>2008</li>
</ul>
</li>
<li>Cover Stories
<ul>
<li>Catalog One</li>
<li>Catalog Two</li>
<li>Catalog Three</li>
<li>Catalog Four</li>
<li>Catalog Five</li>
<li>Catalog One</li>
<li>Catalog Two</li>
<li>Catalog Three</li>
<li>Catalog Four</li>
<li>Catalog Five</li>
</ul>
</li>
</ul>
</div><!-- writing Menu -->
</div><!-- mainWrapper Content -->
CSS
#writingMenu a {
margin: 0px 0px 0px 0px;
padding: 12px 5px 5px 5px;
text-align: right;
-webkit-transition: all .3s ease;
-moz-transition: all .3s ease;
-o-transition: all .3s ease;
-ms-transition: all .3s ease;
transition: all .3s ease;
background: #ffffff;
color: #B3B3B3;
min-width: 140px !important;
display: block;
}
#writingMenu a:hover {
color: #37342e;
}
#writingMenu ul li ul {
position: absolute;
width: 90%;
float: left;
overflow: hidden;
border-left: thin solid black;
border-bottom: thin solid black;
border-right: thin solid black;
margin-left: -5px;
padding-top: 5px;
background-image: url(images/speckled_backgrounddk.jpg);
display: block;
height: 0px;
}
#writingMenu ul li ul li {
background-image: none;
float: none;
}
#writingMenu ul li ul a {
margin: 0px;
padding: 0px;
text-align: left;
-webkit-transition: all .3s ease;
-moz-transition: all .3s ease;
-o-transition: all .3s ease;
-ms-transition: all .3s ease;
transition: all .3s ease;
color: #B3B3B3;
background-color: transparent;
background-image: none;
text-transform: lowercase;
color: #999999;
}
$(document).ready(function() {
var defHeight = $('ul:first',this).height();
console.log(defHeight);
$("ul li").hover(
function () {
$('ul:first',this).stop().animate({height : "toggle"});
},
function () {
$('ul:first',this).stop().animate({height : "toggle"});
});
});
Havent tried but this should work
I'vde made a css-only based dd menu if you're interested...
HTML =>
<!-- by rocky -->
<div id="wrapper">
<div id='navMenu'>
<ul>
<li>Menu1
<ul>
<li>Dropdown1</li>
<li>Dropdown2</li>
<li id="submenu">Dropdown3
<ul>
<li>Submenu 1</li>
<li>Submenu2</li>
<li>Submenu3</li>
</ul>
</li>
</ul> <!-- End of Menu1-->
</li> <!-- Menu2 -->
<li>Menu2
<ul>
<li>Dropdown2 </li>
<li id="submenu">Dropdown2
<ul>
<li>Dropdown2</li>
</ul>
</li>
<li>Dropdown2</li>
</ul> <!-- End Inner UL -->
</li> <!-- ABOUT -->
<li>Menu3
<ul>
<li>Submenu3</li>
<li id="submenu">Submenu3
<ul>
<li>Submenu3</li>
</ul>
</li>
</ul> <!-- End Inner UL -->
</li> <!-- End main LI -->
</ul> <!-- End main UL -->
</div> <!-- End Nav -->
</div> <!-- End wrapper -->
And the CSS:
#navMenu {
margin: 0;
padding: 0;
}
#navMenu ul{
margin: 0;
padding: 0;
line-height: 30px;
}
#navMenu li{
margin: 0;
padding: 0;
list-style: none;
float: left;
position: relative;
}
#navMenu ul li a {
text-align: center;
text-decoration: none;
height: 30px;
width: 150px;
display: block;
color: #000;
}
#navMenu ul ul {
position: absolute;
visibility: hidden;
top: 30px;
}
#navMenu ul li:hover ul {
visibility: visible;
}
#navMenu ul li ul a:hover {
color: #999;
}
#navMenu ul ul li#submenu ul {
position: absolute;
visibility: hidden;
top: 30px;
}
#navMenu ul ul li#submenu:hover ul {
margin-top: -30px;
margin-left: 105px;
visibility: visible;
}
There is a demo here:
http://dbwebb.se/style/?id=152