I want to make onclick dropdown menu without JavaScript, also PHP can't be used. I was using targets, but page jumps every time I click on it, because it is not on the top of page.
Is it possible to make dropdown menu without JS and PHP, but onclick?
What you are after is actually possible, though I would not advise you to actually use this technique. It is nothing less then a hack, semanticly very incorrect, and probably a nightmare for SEO.
This taken into account, I will explain the technique as a proof of concept:
First make sure you organise your html like this:
<nav>
<ul>
<li>
<label for='item-1'>main item 1</label>
<input type="checkbox" id="item-1"/>
<ul>
<li>sub 1</li>
...
</ul>
</li>
...
</ul>
</nav>
Some smart use of the :checked selector and the sibling + selector now allows you to simulate a dropdown on click. The relevant css would look like this:
/* we hide the checkboxes, they are just there to store the 'state' in the background */
/* their state will be triggered by clicking the corresponding label */
nav input[type="checkbox"] {
display: none;
}
/* we hide the sub menu's by default */
nav > ul > li > ul {
display: none;
}
/* we show the sub menu, if it follows a checked checkbox */
nav input[type="checkbox"]:checked + ul {
display: block;
}
For a working example, check the fiddle i set up: http://jsfiddle.net/Xj8Ce/
If you want "onclick" event, you need JavaScript.
With hover you can try this: http://line25.com/tutorials/how-to-create-a-pure-css-dropdown-menu
Hope it helps!
Related
I have a particularly specific question that there are many articles online but they don't answer my question.
I have a menu bar on my website where some <li> elements appear when the user is logged in. That <li> element also has an onhover dropdown styled in css with the following:
ul li:hover > ul {
display: block;
}
So what happens is, when the <li> element of the main (which has a direct child of <ul>) is hovered upon, the dropdown will appear. Pretty straightforward.
My problem is, when I hide that particular <li> element with the dropdown attached to it (through the following code within a javascript if statement), the hover style remains.
So even though the parent <li> is set to display: none;, the child dropdown can be revealed by hovering over a tiny invisible rectangle (see picture) in the header.
TLDR: is there a way I can temporarily disable that particular :hover style preferrably through javascript or jQuery?
Thanks for the help in advance.
My HTML code for anyone wondering: (I have removed unncessary stuff so it is easier to see what I mean)
<ul>
<li>Foo</li>
<li id="dropdown">
<p class="drop" id="loggedInValue"></p>
<ul class="dropdown-content">
<li>My Account</li>
<li>Logout</li>
</ul>
</li>
</ul>
When you are setting li to display: none, you can add a class to li (class-name, for example) and add :not(class-name) to the css.
See below example for reference
ul li:not(.class-name):hover > ul {
display: block;
}
P.S: I am wondering how is that little rectangle even visible, when you have set it to display: none. There is definitely some part left out when setting display to none
You could add a logged-in css class to the root html element, and predicate the hover selector on the presence of that class.
const onLoginSuccess = () => {
document.documentElement.classList.add('logged-in');
}
.logged-in ul li:hover > ul {
display: block;
}
If there should be no drop down then you should run some code similar to this.
Please let me know if this helped.
Have a good one.
const dropdown = document.querySelector('#dropdown');
dropdown.classList.remove('dropdown-styles');
Maybe you can just completely delete the element from the DOM
const dropdown = document.querySelector('#dropdown');
dropdown.parentNode.removeChild(dropdown);
I have 3 menus in 3 different location on a website that they translate to one mobile toggle menu on phone.
My problem on mobile the 3 menus are showing up in the toggle panel but one over the other instead of one after the other. I define that this is a menu in my html using .main-nav
I tried appending .main-nav again but it doesn't work, I tried giving each menu a top margin in css it shows but along with its background.
live example - here how it is on codepen https://codepen.io/anon/pen/VOeKpE
I want all 3 menus in the website to show the links one after the other instead of over each other now.
if ($('.main-nav').length) {
var $mobile_nav = $('.main-nav').clone().prop({
class: 'mobile-nav d-lg-none'
});
$('body').append($mobile_nav);
$('body').prepend('<button type="button" class="mobile-nav-toggle d-lg-none"><i class="fa fa-bars"></i></button>');
$('body').append('<div class="mobile-nav-overly"></div>');
$(document).on('click', '.mobile-nav-toggle', function(e) {
$('body').toggleClass('mobile-nav-active');
$('.mobile-nav-toggle i').toggleClass('fa-times fa-bars');
$('.mobile-nav-overly').toggle();
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav class="main-nav float-right d-none d-lg-block">
<ul>
<li>home</li>
<li>about</li>
</ul>
</nav>
how it looks now
now
desired result
result needed
You could either use
li { display: inline-block }
Or
li { float: left;}
in your css.
the <li> element is by default styled with the display: block property. meaning it behaves similarly to an element like <p> or <div>, taking up the whole width of the content.
Changing this display property to inline-block ensures you still have the same functionalities you would also have with display: block but the elements will from now on only take up as much space as they need.
I have the following code below for list into master page
<div id="header">
<ul>
<li>Home</li>
<li>Page1</li>
</ul>
</div>
with css
#header a:hover {
color: #AA1111;
border-color: #AA1111;
}
#header a:active {
color: #AA1111;
border-color:#AA1111;
}
but the link doesn't highlight with color when page is actived .
:active does not indicate that the link will be highlighted when the current page is active.
:active is the state of the link between mouse click and mouse released on the link. Try holding your mouse down on the link to see for yourself.
To set the current page's link in a different style you will need to either give the current page link a different class and target that class in your CSS.
If you're using .NET I recommend using the various CSS menu adapters / list controls that have the option of specifying the current page menu link class.
I think you are confusing the meaning of the pseudo-selector :active. That css rule will apply when you click on the link. But if that link brings you to a new page, the anchor is no longer active.
What you need to do is add a class to the anchor depending on what page you are on. So, in default.aspx you need to make sure that you have <a class="active" href="default.aspx">Home</a>. Then, you will need to change your css rule to #header a.active.
The way you may want to setup your page:
#header li {}
#header li.active a {color: #AA1111; border-color:#AA1111;}
<div id="header">
<ul>
<li class="active">Home</li>
<li>Page1</li>
</ul>
</div>
You will need to set the active class on the li based on which page.
Demo: http://jsfiddle.net/lucuma/HT4U4/
Question about logics here:
What's the most elegant way to make the menu appear/disappear onmouseover/onmouseout?
See the following JsBin:
http://jsbin.com/owayeb/edit#source
The Menu is hidden by default.
If the user moves his cursor above the Link the showme() function gets called.
When the user moves his cursor away the hideme() functions gets called.
How would I get the Menu to persist while the user moves his mouse away from the Link to above the Menu?
Or is this all the wrong school of thought?
Assuming this is for cascading navigation or something similar, I would do something like...
<style type="text/css">
ul#nav li {
position: relative;
height: 20px;
}
ul#nav li ul {
display: none;
position: absolute;
top: 20px;
}
ul#nav li.selected ul { display: block; }
</style>
<ul id="nav">
<li>
Link
<ul>
<li>Hi There!</li>
<li>Secone Nav Item</li>
...
</ul>
</li>
</ul>
Within the onmouseover state of your list items, you would add the .selected class to #nav thus causing all child UL's to be displayed. Because the child UL elements are within ul#nav, your hover state will still be active while you're rolling over the children.
You'll obviously need to tweak the CSS to match the desired look you want, but that's the general idea. If you were using prototype js for example, your javascript would look something like...
$$('#nav li').each(function(x) {
x.onmouseover = function() { $(this).addClassName('selected'); }
x.onmouseout = function() { $(this).removeClassName('selected'); }
});
you could add the same onmouseover listener to the drop div, so that it stays open:
<div id="drop" class="dropdown" onmouseover="showme('drop')" onmouseout="hideme('drop')">
Hi there!
</div>
Best and most simple way I've done it is use the :hover selector to keep the submenu displayed.
Here's how I would go about it:
1. define a menu structure
<ul id='menu'>
<li>Menu Item</li>
<ul id='submenu'>
<li>Sub menu item 1</li>
<li>Sub menu item 2</li>
</ul>
</ul>
Hide submenu in css and define submenu:hover to leave display: block
Attach to the menu item, the onmouseover to display the submenu (you might just toggle a class or something and toggle again about 5 secs later.)
Hopefully that works for you. The idea here is that you are hovering over the menu item to display the submenu, then the hover selector will keep the menu displayed, finally when the user hovers out the hover selector stops.
Can't remember exactly how I did it before because this was an on the fly thing, but the idea is there.
Not sure if this is what you're looking for or not, but check it out!
http://jsfiddle.net/5NmTB/
Let me know if you have questions
I use the superfish jQuery plugin to build Javascript drop-down menus. Superfish is an enhanced Suckerfish-style menu jQuery plugin that takes an existing pure CSS drop-down menu (so it degrades gracefully without JavaScript) and adds some useful enhancements.
I've got a little HTML/CSS/JQuery drop down menu working. My pseudo code for it is:
function closeMenus() {
$('.subMenu').css('display', 'none');
}
#mainMenu ul li .subMenu {
display: none;
position: absolute;
}
#mainMenu ul li:hover .subMenu {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mainMenu">
<ul>
<li>
Menu Header
<div class="subMenu" onClick="closeMenus();">Menu Content</div>
</li>
</ul>
</div>
The CSS works so when someone hovers over Menu Header, the subMenu appears below it and disappears when the mouse leaves the menu. My problem comes when a user clicks an item in the menu; I'd like to hide the menu. The JavaScript hides the menu fine but when the user mouses over the menu header again, it doesn't reappear. It appears that CSS won't override the JavaScript display property. Most, if not all, of the links won't be going to other pages, just calling more JavaScript.
Anyone have any ideas how to hide the sub menu on click so that it will be again visible, or do I need more Javascript to show the menu every time someone hovers?
Use JQuery more fully -- look into the .toggle() command and bind it via click:
$('.subMenu').click(function() {$(this).toggle();});
Then you can eliminate most of your other code.
You're trying to do half of it with CSS and half of it with jQuery. Just do it all with jQuery: http://jsfiddle.net/hw5qr/
$('.subMenu').click(function() {
$(this).hide();
});
$('#mainMenu').hover(function() {
$(this).find('.subMenu').show();
}, function() {
$(this).find('.subMenu').hide();
});
Stryle attribute has highest priority.
$('.ftpBrowseSubMenu').css('display','none');
make
<div style="display:none">
, so rule
#mainMenu ul li:hover
has lower priority against style attribute. So, you have to do everything with javascript.
Like you already said are element styles stronger than css styles (unless you use !important). So you have to to do everything with Javascript what shouldn't be to hard. You have just to register two more event listener: onmouseover and onmouseout. With them you can set the display property to the correct value and it will work this way.