Highlight active tab in navigation menu [duplicate] - javascript

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.

Related

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.

sub-menu expansion and innerHTML replacement based on onclick, using just Javascript

First, I should mention that I'm about 4-weeks new to the coding world, and this is the first time I'm trying to make (what I thought would be) a simple site.
I have seen many similar questions on Stack Overflow, but in trying to adapt the code samples provided in the solutions, the solution would stop working.
So, the current hurdle is:
I have a menu defined in HTML with a sub-menu in one of the <li> elements ("Portfolio"), and that <li> element contains the character ▼ (&#9660).
I set up an onclick event for that <li> element so that when it was clicked it would do two things: expand/display the sub-menu <li> elements directly below it (pushing the other <li> elements in the menu further down), and replace the ▼ character with a ▲ character (&#9650)... until the <li> element was clicked again to shrink/hide the sub-menu.
I'm not sure if it matters, but this menu is inside a grid item because the page is set up using CSS Grid.
So basically:
HOME
ABOUT US
PORTFOLIO ▼
INFORMATION
CONTACT
...would become:
HOME
ABOUT US
PORTFOLIO ▲
LINK 1
LINK 2
LINK 3
INFORMATION
CONTACT
No matter how I set up my classes and IDs, I cannot get the arrow symbol to swap, and somewhere along the line, I messed up the coding and now the sub-menu doesn't even expand anymore.
It's likely embarrassingly bad code (given that I've tried to mash together bits from samples I've seen) but here is what I have. Thanks in advance.
var arrowstring = document.getElementById("arrowdirection").innerHTML;
document.getElementById("IDforPortfolioLink").classList.toggle("show");
if (IDforPortfolioLink.classList.contains('show')) {
arrowstring = "&#9650"
} else {
arrowstring = "&#9660"
}
arrowdirection.textContent = arrowstring;
}
.sub-menu-content {
display: none;
position: absolute;
}
.sub-menu-content a {
display: block;
}
.sub-menu-content a:hover {
background-color: green;
}
.show {
display: block;
}
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<ul class="menu">
<li>Home</li>
<li>About us</li>
<li class="LinkForPortfolio" id="IDforPortfolioLink" onclick= "myFunction()">LINK <span class="arrow" id= "arrowdirection">▼</span><div class="sub-menu-content" id="myportfolio">
<ul>
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
</ul>
</div>
</li>
<li>Information</li>
<li>Contact</li>
</ul>
</body>
</html>
Well, your code had so many flaws I had to rewrite it.
I'll explain everything that I possibly can of what I did here:
I changed the HTML a bit: I have added div's, instead of ul's with li's, inside a nav(container). It's more indicated to do so because it keeps the markup clean, and is less harder to debug.
I have assigned nav a display: flex; justify-content: center; align-items: center; which centers the divs inside nav, and inlines them. I did so with nav div, which pretty much centered the text inside of them.
I have removed all of the classes expect of .portfolio because it's useless to have that many classes.
I made div.expand-portfolio a child of div.portfolio, which in itself(.expand-portfolio) has another ul child, which holds the links. You might've noticed that I've added .portfolio a position: relative; and .expand-portfolio a position: absolute;. I did that because, I wanted to take .expand-portfolio out of the document flow, which basically means I wanted to make .expand-portfolio not interact with any element on the page. Now, when assigning position: absolute; to a child inside a container, the child's position is going to be relative to the document and not the parent. This is why you may add position: relative; to the parent.
I created a separate class called .expanded which gives .expand-portfolio a height of 150px when assigned to it.
You also might have noticed I gave the divs inside the nav a transition: 500ms ease, what that does is make the transition between the properties smooth, and not sudden. You may remove that property from them if you don't want that.
Now, the javascript.
When I made those 3 variables, which are the references of the elements from the page, you noticed I used document.getElementsByClassName followed by a [0]. What document.getElementsByClassName() returns is: a nodelist. Documentation here. It's basically a sort of "array", and with [0] appended to it, I select only the first and only element of the page with that class.
You may have observed I added the onclick function in the javascript file. Personal preference. I said that when I click the portfolio button, first, you should change that span's innerHTML. (the span element holds the actual symbol). I also said you should toggle the .expanded class. And, I made an if statement, checking if .expand-portfolio doesn't contain the class. If it doesn't, you can pretty much see what it does.
I hope it helps. If you have any more questions, ask them in the comments.
var portfolio = document.getElementsByClassName("portfolio")[0];
var portfolioInner = document.getElementsByClassName("inner-html")[0];
var expandPortfolio = document.getElementsByClassName("expand-portfolio")[0];
portfolio.onclick = function(){
portfolioInner.innerHTML = "▲";
expandPortfolio.classList.toggle("expanded");
if(!expandPortfolio.classList.contains("expanded")){
portfolioInner.innerHTML = "▼"
}
};
html, body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
}
.menus-container {
height: 100%;
width: auto;
}
.menus-container > div {
padding: 10px 10px 5px;
transition: 500ms ease;
width: 30%;
height: 100%;
cursor: pointer;
}
.expand-portfolio {
overflow: hidden;
width: 100px;
height: 0;
background-color: #000;
transition: 500ms ease;
}
.expand-portfolio ul {
padding-left: 25px;
}
.expand-portfolio ul li {
padding: 10px 0 10px 0;
color: #fff;
}
.portfolio span {
margin-left: 5px;
}
.expanded {
height: 150px;
}
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class="menus-container">
<div>Home</div>
<div>About Us</div>
<div class="portfolio">Portfolio <span class="inner-html">&#9660</span>
<div class="expand-portfolio">
<ul>
<li>LINK 1</li>
<li>LINK 2</li>
<li>LINK 3</li>
</ul>
</div>
</div>
<div>Information</div>
<div>Contact</div>
</div>
</body>
</html>

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

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>

Closing drop-down menu by clicking on the button itself

I've seen a lot of questions on this wesite about closing a drop-down menu by clicking anywhere on the page.
My question is a little bit different though. I don't want the dropdown-menu to close by clicking outside of it. The moment I click on the button that shows me the menu, I want the menu to stay like that (drop-downed) untill the user clicks on that same button again. Also, the moment when the menu is shown, I want it to push the other elements direcly beneath it down. These elements could be for example other buttons. You guys might have seen this concept on some websites and I like the idea. I want to create the same thing, but I don't how.
This will probably be made with Javascript since this is easier, but I don't know how to do it. Do you guys have any ideas or tips?
I would be very grateful. Thanks in advance.
Edit: Here's an example of what I ment: Link to jsfiddle ->https://jsfiddle.net/Cerebrl/uhykY/
I want to push down button 2 and 3 the moment the first menu is drop downed, so it can create it's own space to display. And secondly, the menu should only close the moment I push the button, not by clicking outside of it.
Your can use toggleSlide method in two lines like
$(function(){
$('button').click(function(){
$('ul').slideToggle();
});
});
ul {
background: none #FA982E;
margin: 0;
padding: 0;
list-style: none;
display: none;
}
ul a {
display: block;
padding: 5px 20px;
text-decoration: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
<button data-toggle="#menu-main" title="Click to toggle">Toggle Menu</button>
</p>
<ul id="menu-main">
<li>Menu item 1</li>
<li>Menu item 2</li>
</ul>
If you want the menu to push the content below, than put it in normal flow. What you need is a simple jQuery's slideToggle method and to hide the menu by default:
$('[data-toggle]').on('click', function(e){
e.preventDefault;
var thisLink = $(this);
var toToggle = $( thisLink.data('toggle') );
toToggle.slideToggle(200);
})
* {
font-family: sans-serif;
}
.toggle-menu a {
display: block;
float: right;
padding: 5px 20px;
text-align: center;
background: none #F1B475;
cursor: pointer;
}
#menu-main {
background: none #FA982E;
margin: 0;
padding: 0;
list-style: none;
display: none;
}
#menu-main a {
display: block;
padding: 5px 20px;
text-decoration: none;
}
#menu-main a:hover,
#menu-main a:focus {
background: none #D0812D;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="toggle-menu">
<p>
HALLO
<a data-toggle="#menu-main" title="Click to toggle">+</a>
</p>
</div>
<ul id="menu-main">
<li>Menu item 1</li>
<li>Menu item 2</li>
</ul>
<p>
Other content
</p>
Since the menu has no absolute or fixed position, it will push the content below it. JSFiddle playground

Header changes on-scroll and sticks to the top

The header includes a simple large white title/logo, with a navigation right below it.
Then upon scrolling past the navigation, the header changes to a pink, semi-transparent bar with the title/logo on the left and a navigation to the right. It sticks to the top of the page as well.
HTML:
<header>
<h2>The</h2>
<h1>Catching Raindrops</h1>
<nav>
<ul>
<li>About</li>
<li>Contact</li>
<li>Music</li>
<li>Travel</li>
<li>Quotes</li>
</ul>
</nav>
</header>
How do I go about this? I've searched everywhere I can think of, but haven't found any tutorials on how to change it the way I want to. I did find this: http://codepen.io/senff/pen/ayGvD which only makes it sticky.
And I don't know JS so can't really figure out how to change it, but this one seems to be the kind I'm looking for, where the class changes, so that I only have to add another class in the css and put all of the on-scroll changes there, am I right? If I am, how do I go about changing it for the logo and navigation? In this CodePen example, only one class has been used, which would only be able to change the navigation, and not the headers, right? Sorry if this sounds incredibly confusing. :/
And in this, the JS code targets selectors and changes the colors, but as I've explained above my changes are more complicated.
The layout for this page is how I want it to be like, only this tutorial confused me to no end :/
This is my CSS
header {
font-family:'Steelfish';
color: #FFF;
margin: 10px 0 0 0;
}
header h1 {
font-size: 90px;
text-align: center;
text-transform: uppercase;
}
header h2 {
font-size: 40px;
text-align: center;
text-transform: uppercase
}
nav {
font-size: 30px;
text-align: center;
text-transform: uppercase;
margin-top: 5px;
}
nav ul {
margin:0;
padding: 0;
list-style-type: none;
}
nav ul li {
display: inline-block;
padding: 0 10px 0 10px;
}
nav ul li a {
text-decoration: none;
color: #fff;
}
nav ul li a:hover {
text-decoration: none;
color: #9E9E9E;
-webkit-transition: color 900ms ease;
-moz-transition:color 900ms ease;
-o-transition: color 900ms ease;
transition: color 900ms ease;
}
Thank you in advance.
The last link is from my site and my tutorials are written for WordPress and Suffusion theme. This can be a reason for what the tutorial looks confusing. In WordPress jQuery library is already loaded and the theme have a markup which is reffered in tutorial.
But html/javascript/css works in WordPress exactly as in any other site, so, with some little adjustments the solution from my site will works for you too. You only need some minor changes for making your markup ready for trasformations.
For making this solution to work will need to link jQuery library in the head section of your page (and I also added here the needed jQuery function):
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script type="text/javascript">
$j=jQuery.noConflict();
$j(document).ready(function() {
var nav = $j('#nav');
$j('#left-header').hide();
$j(window).scroll(function () {
if ($j(this).scrollTop() > 150) {
nav.addClass("scroll-nav");
$j('#header').hide();
$j('#left-header').show();
} else {
nav.removeClass("scroll-nav");
$j('#header').show();
$j('#left-header').hide();
}
});
});
</script>
</head>
Then you have to make some small changes in your markup, mostly for naming your sections, but also for adding a new div which need to hold the small logo (#left-header div):
<body>
<header id="header">
<h2>The</h2>
<h1>Catching Raindrops</h1>
</header>
<nav id="nav">
<div id="left-header">The Catching Raindrops</div>
<ul class="menu">
<li>About</li>
<li>Contact</li>
<li>Music</li>
<li>Travel</li>
<li>Quotes</li>
</ul>
</nav>
<div id="just-for-testing" style="height:1000px;"> </div>
</body>
The div with id #just-for-testing is added only for giving some height to the page otherwise you cannot scroll - replace that div with your real content.
Finally, add in your stylesheet the CSS for navigation bar after scrolling:
.scroll-nav {z-index: 9999; position: fixed; left: 0; top: 0 !important; width: 100%;background:rgba(255,0,0,0.5);}
.scroll-nav ul.menu {float:right;}
#nav #left-header {float:left;font-size:80%;}
#nav #left-header a {background:none;}
#left-header {display:none;border:none;}
#left-header img {border:none !important;}
You can see, test and use all these changes in the fiddle linked below
http://jsfiddle.net/drake/bg2S4/
Hope it help

Categories

Resources