Responsive Menu, Multi-level, CSS and Javascript ONLY, no jQuery [closed] - javascript

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
All,
Using ONLY javascript and CSS, I need to create a responsive menu. The menu must also supports one level sub-menus.
Due to the memory limitations of the embedded hardware, I cannot use external libraries/frameworks.
I have browsed as much as I could. The examples I have found don't quite address my problem.
If the menu is responsive, it does not support sub-menus ...
If it supports sub-menus, the submenus expand within the menus, instead of replacing them ...
If it does everything I need, then it is in jQuery, and I cannot use it ...
I have been 'piecing' together snippets of code (http://codepen.io/vpappano/pen/NRLRWJ)
However, I am now stuck with the following problem. Because I embedded the submenu (id="myDropdown")
<div class="dropdown-content" id="myDropdown">
Link 1
Link 2
Link 3
</div>
within the main menu (id="myTopnav"), I don't manage to display the submenu when in the minimized state.
The only solution I could come up with is to duplicate the submenu (id="myDropdown2")
<div class="dropdown-content" id="myDropdown2">
Link 1
Link 2
Link 3
</div>
which, of course, is "so wrong on so many different levels" ... :-)
Can you improve my code in such a way that I am using only one occurrence of the submenu? A link to a JSFiddle, CodePen, or similar would be extremely helpful ...
Please NO jQuery. I can only use javascript and CSS. However, if you are aware of a little js-css-only library that achieves what I am looking for (MIT license), that will also do the trick ... :-)
Thank you so much ...
Vincenzo

Here is a "not so simple" demo of responsive navigation taken from w3schools, and modified by me to show a simple submenu behavior.
The most important part here to take note is that you might have to create a function to close other submenus, when you open another one and edit the non responsive CSS.
function myFunction() {
var x = document.getElementById("myTopnav");
if (x.className === "topnav") {
x.className += " responsive";
} else {
x.className = "topnav";
}
}
function openSubMenu() {
var x = document.getElementById("submenuNav");
if (x.hidden === true) {
x.hidden = false;
} else {
x.hidden = true;
}
}
body {margin:0;}
ul.topnav {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
}
ul.topnav li {float: left;}
ul.topnav li a {
display: inline-block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
transition: 0.3s;
font-size: 17px;
}
ul.topnav li a:hover {background-color: #555;}
ul.topnav li.icon {display: none;}
#media screen and (max-width:680px) {
ul.topnav li:not(:first-child) {display: none;}
ul.topnav li.icon {
float: right;
display: inline-block;
}
}
#media screen and (max-width:680px) {
ul.topnav.responsive {position: relative;}
ul.topnav.responsive li.icon {
position: absolute;
right: 0;
top: 0;
}
ul.topnav.responsive li {
float: none;
display: inline;
}
ul.topnav.responsive li a {
display: block;
text-align: left;
}
}
<ul class="topnav" id="myTopnav">
<li><a class="active" href="#home">Home</a></li>
<li>News</li>
<li>Contact
<ul class="subnav" id="submenuNav" hidden >
<li>Sub Menu1</li>
<li>Sub Menu2</li>
<li>Sub Menu3</li>
</ul>
</li>
<li>About</li>
<li class="icon">
☰
</li>
</ul>
<div style="padding-left:16px">
<h2>Responsive Topnav Example</h2>
<p>Resize the browser window to see how it works.</p>
</div>

Related

I neeHelp at making a responsive menu

So i want to make this responsive menu. On Desktop it looks like this:
And on Mobile it should look stacked overlapping everything under it but not pushing it down. So not like this:
(Before button pressed)
(After button pressed)
You can see that the Slideshow below is pushed down and the obvious misplacement of the menu on the button in general.
Plese help me to fix this, im a poor backend dev.
Here is my code:
function myFunction() {
var x = document.getElementById("menu");
if (x.className === "menu") {
x.className += " responsive";
} else {
x.className = "menu";
}
}
.menu .icon {
display: none;
}
#media screen and (max-width: 965px) {
.menu a {display: none;}
.menu a.icon {
float: right;
display: block;
}
}
/* The "responsive" class is added to the menu with JavaScript when the user clicks on the icon */
#media screen and (max-width: 965px) {
.menu.responsive {
background-color: white;
position: relative;
}
.menu.responsive a.icon {
position: absolute;
right: 0;
top: 0;
}
.menu.responsive a {
float: none;
display: block;
text-align: left
}
}
<div class="mainheader">
<div class="logo">
<img src="../bilder/Logo_Koeln_Fliesen_Esch.jpg">
</div>
<div id="menu" class="menu">
Unternehmen
Leistungen
Referenzen
Kontakt
<a href="javascript:void(0);" class="icon" onclick="myFunction()">
<img class="bigicon" src="../bilder/menu.png">
</a>
</div>
</div>
So the anwer to fix the issue was to set the responsive menu class to absolute, also you have to use right: 0; so it stays in place.
After that i figured out that i could just move the menu links down since they are also absolute now in order to prevent them from overlapping the button.
Thanks for the effort of helping everyone ;)
function myFunction() {
var x = document.getElementById("menu");
if (x.className === "menu") {
x.className += " responsive";
} else {
x.className = "menu";
}
}
.menu .icon {
display: none;
}
#media screen and (max-width: 965px) {
.menu a {display: none;}
.menu a.icon {
float: right;
display: block;
}
}
/* The "responsive" class is added to the menu with JavaScript when the user clicks on the icon */
#media screen and (max-width: 965px) {
.menu.responsive {
background-color: white;
position: relative;
}
.menu.responsive a {
float: none;
display: block;
text-align: right
}
}
<img src="../bilder/Logo_Koeln_Fliesen_Esch.jpg">
</div>
<div id="menu" class="menu">
<img class="bigicon" src="../bilder/menu.png">
<span>
Unternehmen
Leistungen
Referenzen
Kontakt
</span>
</div>
</div>
with out looking at whole page code here is what you need to do or something I would always check before going forward.
for css to work properly add this meta tag in head <meta name="viewport" content="minimal-ui, height=device-height, width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
secondly menu is something that should be stacked higher up on the interactive and display layer so it does not mess with other elements on the page. One way of doing this is to place the tag at the bottom of everything last on page (remember to css absolute positioning on the menu div) or zoom it up like +10000 should do.
please try not to add responsiveness after the fact like when user clicks this will create whole lot of problem going forward as computed vs initial values collide. Leave things to css as much as possible. It is good code from w3school follow its instructions as stated.
For the positioning issue calculate height of the image;
it is actually your icon that is being positioned every thing else is relative to where it should be. so move your icon as first item then every other anchor tag below it. this should solve your positioning issue.
Add z-index property to .menu.responsive class.

How to make active button in navigation bar change color

Ok so i'm super beginner with html and css and i don't know javascript at all.I'm creating a little website as a school project, i made horizontal navigation bar from w3schools tutorial, what i want to do is when i press one of the buttons to stay colored, not just change color for 1 sec because they are 'active'. My code may be completely messy but i really need help.
Also i have 3 more subpages connected to this one, i want them to stay colored as well.
What i'm trying to achieve is exactly this: How can I add class on active li with JavaScript code
But it doesnt work for me, maybe i need to change something in javascrip because my class is named 'navbar'?
I've tried several solves from this topic on stack overflow but none of these work for me :\
HTML:
<ul class="navbar">
<li>Pocetna</li>
<li>Stranica 2</li>
<li>Stranica 3</li>
<li style="float: right;">Kontakt</li>
</ul>
CSS:
.navbar {
list-style-type: none;
position: sticky;
top: 0;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
}
.navbar li {
float: left;
}
.navbar li a {
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-family: Arial;
}
.navbar li a:hover {
background-color: #111;
}
Im expecting link to stay orange when im on that page.
you can do some things with jquery like add an event listener that changes the css of html elements
const changeColor = () => {
$('ul > li > a').css('background-color', 'inherit')
$(event.target).css("background-color", "red")
}
$('ul > li > a').on('click', changeColor)
https://jsfiddle.net/z02ndowt/
You can do this by adding a class onto your html <a> tag on the link that is active and then just style the active class within your CSS. See below:
HTML
<ul class="navbar">
<li><a class="active" href="sajt.html">Pocetna</a></li>
<li>Stranica 2</li>
<li>Stranica 3</li>
<li style="float: right;">Kontakt</li>
</ul>
CSS
.active {
color: orange;
}
Ok so i did some testing and kinda found a solution. I put identificator on instead of class. So on my main page i put id="active" on first link, on my second page on second link etc. then just added #active { background-color: orange; } and it works just how i wanted it to work.

Menu mobile not work in internet explorer

I have a problem with menu mobile in internet explorer it does not work -
I still have a menu from desktop viev. In chrome, firefox, opera is good. Where is the mistake and can i fix it?
function myFunction() {
var x = document.getElementById("myTopnav");
if (x.className === "topnav") {
x.className += " responsive";
} else {
x.className = "topnav";
}
}
#media screen and (max-width:579px) {
ul.topnav li {display: none;}
ul.topnav li.icon {
display: inline-block;}
}
#media screen and (max-width:579px) {
ul.topnav.responsive {position: relative;}
ul.topnav.responsive li.icon {
position: absolute;
right: 0;
top: 40px;
}
}
ul.topnav.responsive li {
float: none;
display: inline;
}
<nav id="menu">
<ul class="topnav" id="myTopnav">
<li><a class="active" data-scroll-nav='1'>Home</a></li>
<li><a data-scroll-nav='2'>text1</a></li>
<li><a data-scroll-nav='3'>text2</a></li>
<li><a data-scroll-nav='4'>text3</a></li>
<li><a data-scroll-nav='5'>tex4</a></li>
<li class="icon">
<i class="fa fa-bars"></i>
</li>
</ul>
</nav>
After reviewing your site I strongly believe you have some parsing errors. Some browsers will ignore them and properly work-around your bugs, which is why it works on Chrome for example, but IE is a little bit more picky on that.
Specifically, you have quite a few brackets that are not properly closed. You can use a service like http://csslint.net/ to properly identify the breaklines.
There's nothing else wrong with the CSS as the bug is that the .icon never appears due to that portion of CSS (the media query that sets it as display: inline-block) not being interpreted in IE so it still reads display: none;.

CSS li dropdown on touch devices

EDIT: Thanks for the answers. Do these suggestions keep the li:hover dropdown working, just adding the onclick feature for touch devices? I don't want desktop users to have to click, the menu should appear on:hover for them.
I have done my research on this subject but can't seem to find a good solution.
My site http://www.eastbournenl.com
Menu's in question are 'League Info' and 'Results' in the top navigation bar.
My CSS dropdown menu activates on li:hover (the li item is NOT a link, I changed the cursor so it appears as a hand but clicking will take you nowhere).
However, clearly this doesn't work on touch devices.
Is there a way to maintain the setup I have currently with the li:hover working on non-touch devices, but adding some javascript to enable functionality for touchscreen devices?
HTML
<div id="link_bar">
<ul>
<li>League Info
<ul class="drop">
<li>Team Directory</li>
<li>Fixtures</li>
<li>Rules</li>
<li>Umpire Directory</li>
</ul>
</li>
</ul>
</div>
And CSS
#link_bar ul ul {
display: none
}
#link_bar ul li:hover > ul {
display: block
}
#link_bar ul:after {
content: "";
clear:both;
display:block
}
#link_bar ul ul {
position: absolute;
top: 1em;
width: 10em;
padding-top: 1em;
margin-left: 0;
}
#link_bar ul ul li {float:none ; position: relative ; padding: 1em 1em 1em 0}
#link_bar ul ul li {width:100%}
#link_bar .drop li:hover a {color: #99FF33}
With Modernizr, you can target touch devices, so include it in your code, and then :
JS part :
if(Modernizr.touch){
$('.hasDropDown').click(function(){
$(this).find('.drop').addClass('visible');
});
}
HTML part :
<div id="link_bar">
<ul>
<li class="hasDropDown">League Info
<ul class="drop">
<li>Team Directory</li>
<li>Fixtures</li>
<li>Rules</li>
<li>Umpire Directory</li>
</ul>
</li>
</ul>
</div>
CSS :
.visible {
display: block;
}
That's weird, most of touch devices emulate hover events.
as you know touch device not supported hover effects
you can use some plugin for that,like Modernizer.js
another solution i see on the Web is:
div#menu ul li:hover ul needs to become div#menu ul li:active ul for it to respond on touch devices because they don't support hover states.
my specific solution for you is:
Jquery Smart Menu

Highlight active tab in navigation menu [duplicate]

This question already has an answer here:
How to highlight active tab on the website menu?
(1 answer)
Closed 9 years ago.
My question is :
I have a menu items, and I want to highlight the active tab that users switch to that points to another page for sure .
stackover flow use :
.nav {
float: left;
font-size: 125%;
}
.nav ul {
margin: 0;
}
.nav li {
background: none repeat scroll 0 0 #777777;
display: block;
float: left;
margin-right: 7px;
}
**.nav .youarehere {
background: none repeat scroll 0 0 #FF9900;
}**
.youarehere a {
color: #FFFFFF;
}
.nav li:hover {
background-color: #FF9900;
}
.nav a {
color: #FFFFFF;
display: block;
padding: 6px 12px;
text-decoration: none;
}
Can anybody tell me what else they use to make this work ?
menu :
<ul class="nav">
<li> <a href="{$smarty.const._URL}/index.{$smarty.const._FEXT}" class="wide-nav-link menu_link" >{$lang.homepage}</a></li>
<li class="dropdown">
{$lang.category} <b class="caret"></b>
<ul class="dropdown-menu menu_link">
{dropdown_menu_video_categories}
</ul>
</li>
{if $smarty.const._MOD_ARTICLE == 1}
<li class="dropdown">
{$lang.articles} <b class="caret"></b>
<ul class="dropdown-menu menu_link">
{dropdown_menu_article_categories}
</ul>
</li>
{/if}
<li> {$lang.top_videos}</li>
<li>{$lang.new_videos}</li>
<li>{$lang.random_video}</li>
{if isset($mm_menu_always_inject1)}{$mm_menu_always_inject1}{/if}
<li>{$lang.contact_us}</li>
{if isset($mm_menu_always_inject2)}{$mm_menu_always_inject2}{/if}
{if $logged_in != 1 && isset($mm_menu_notlogged_inject)}{$mm_menu_notlogged_inject}{/if}
</ul>
Or you can add programmatically class="active" (or selected) to the current selected menu and do this:
.nav li a.active {
color: #FFFFFF;
}
#ChrisHerbert your solution will not work... you will change all the li of the menu... because the class is in your body tag. (EDIT: the solution was changed, see comments)
With #ChrisHerbert answer, you can do it in two ways:
1) with Javascript, take the class in the body tag then select the one with the associate index (:eq() in jQuery). (you can find a way without javascript for non-javascript user)
OR
2) you can do: .home .nav li:nth-child(0) {}, .about-us .nav:nth-child(1) {}, etc. if you know the index of each page in your menu! Or other child selector but, old versions of IE don't like it!
I think you should do it with my solution rather then the body tag. Still, it is really useful to have that class in the body for page specific thingy to add.
Add a unique class to the <body> tag of each page. For example, on the home page:
<body class="home">
On the contact page: <body class="contact">
On the blog page: <body class="blog">
..and so on.
Then, in your CSS, do something like this:
.home .nav li.home, .contact .nav li.contact, .blog .nav li.blog {
// styling to indicate active state
}
I think the question is, are you looking to have this done dynamically? Or are you coding each page? The other two solutions are great, but a bit overkill if actually you're accessing each page individually. You could just add a class to the selected nav element depending on the page. This is probably the easiest to get your head around if you've not done it before, but #ChrisHerbert's solution is the nicest way of doing it dynamically just using CSS (no PHP ifs etc).
HTML
<div class="nav">
Home
About us
Portfolio
</div>
CSS
.nav a {
color:#ff4444;
}
.nav a.selected {
color:#ff44ff;
}
EDIT: Just realised that #AnnieCaron's answer is the same as mine.

Categories

Resources