{"id":33,"date":"2008-02-20T07:00:46","date_gmt":"2008-02-20T13:00:46","guid":{"rendered":"http:\/\/cssnewbie.com\/navigation\/intelligent-navigation\/"},"modified":"2008-02-20T07:00:46","modified_gmt":"2008-02-20T13:00:46","slug":"intelligent-navigation","status":"publish","type":"post","link":"https:\/\/cssdeck.com\/blog\/intelligent-navigation\/","title":{"rendered":"Intelligent Navigation Bars with JavaScript and CSS"},"content":{"rendered":"<p><img src='https:\/\/cssdeck.com\/blog\/wp-content\/uploads\/2008\/02\/terminator.jpg' alt='Arnold as the Terminator' title='Photo by xrrr on Flickr. Used under a Creative Commons license.' \/><\/p>\n<p>I\u2019ve developed a trick over the years that I\u2019ve used on a number of websites now for making my sites\u2019 navigation bars \u201cintelligent\u201d or \u201cself-aware.\u201d By that, I mean that the navigation bar automatically knows which tab\/button\/whatever should be considered the currently active link, without having to manually specify a class or ID on either the body tag or on the links themselves. And since I\u2019ve found it so useful, I thought I should share it with you, even though it does involve a smidgen of JavaScript. <\/p>\n<p>I start with an unordered list that looks something like this:<\/p>\n<pre lang=\"html4strict\" escaped=\"true\" line=\"1\">&lt;ul id=\"nav\"&gt;\n\t&lt;li&gt;&lt;a href=\"\/about\/\"&gt;About Us&lt;\/a&gt;&lt;\/li&gt;\n\t&lt;li&gt;&lt;a href=\"\/contact\/\"&gt;Contact Us&lt;\/a&gt;&lt;\/li&gt;\n\t&lt;li&gt;&lt;a href=\"\/archives\/\"&gt;Our Archives&lt;\/a&gt;&lt;\/li&gt;\n\t&lt;li&gt;&lt;a href=\"\/free\/\"&gt;Free Stuff&lt;\/a&gt;&lt;\/li&gt;\n&lt;\/ul&gt;<\/pre>\n<p>Then I turn the unordered list into a navigation bar, using <a href=\"\/navigation\/tab-based-navigation\/\">the technique I described in my last article.<\/a> I won\u2019t delve into those details here, for the sake of brevity and my fierce, fierce (fierce!) hatred of repetition, but you might want to read the prior post first if you missed it. The navigation bar gives me tabs that expand nicely for different text sizes and respond by growing and changing color when people hover over them. <\/p>\n<p>But what if you want to somehow indicate to your users which page or section of the site they\u2019re currently visiting? For that, I use the following JavaScript magic:<\/p>\n<pre lang=\"javascript\" escaped=\"true\" line=\"1\">function setActive() {\n  aObj = document.getElementById('nav').getElementsByTagName('a');\n  for(i=0;i&lt;aObj.length;i++) { \n    if(document.location.href.indexOf(aObj[i].href)&gt;=0) {\n      aObj[i].className='active';\n    }\n  }\n}<\/pre>\n<p>This tiny little function does four things:<\/p>\n<ol>\n<li>Finds all of the anchor tags (via getElementsByTagName) inside of the element with the \u201cnav\u201d id (getElementById) \u2013 our unordered list, in this case.<\/li>\n<li>Cycles through every anchor tag that we\u2019ve found (our \u201cfor\u201d loop).<\/li>\n<li>Compares the \u201chref\u201d of the anchor tag with the page we\u2019re currently on (document.location, which is the URL that shows up in the bar at the top of your browser) to see if the href is contained therein.<\/li>\n<li>If the href is a match for the page we\u2019re on, it sets a class of \u201cactive\u201d on the anchor tag (className=\u2019active\u2019).<\/li>\n<\/ol>\n<p>Then we have to make sure to run the setActive script when we load the page, so that our tab gets set as soon as the page is loaded. I accomplish that with this line of JavaScript somewhere below my setActive function within the same file:<\/p>\n<pre lang=\"javascript\" escaped=\"true\" line=\"1\">window.onload = setActive;<\/pre>\n<p>After that comes the CSS. Because we\u2019ve used our JavaScript to set a class of \u201cactive\u201d on our tab, all we need to do is style the active class. I usually do something fairly simple like the code below, which make the tab drop down from the top, applies a background color, and gives it a dark border on all sides but the top:<\/p>\n<pre lang=\"css\" escaped=\"true\" line=\"1\">ul#nav li a.active {\n\tpadding-top: 15px;\n\tbackground-color: #075a97;\n\tborder: 1px solid #333;\n\tborder-top: none; \n}<\/pre>\n<p>And voila! Your navigation bar suddenly knows and indicates exactly where you are, without having to remember to specify any extra IDs on the body tag or navigation links. <a href=\"\/example\/intelligent-navigation\/?about\">You can see it in action here.<\/a><\/p>\n<p>As a caveat, this technique assumes that you\u2019re not linking to a lot of commonly-nested directories in your navigation. For instance, if you have one tab going to \u201c\/blog\/\u201d and another to \u201c\/blog\/archive\/\u201d, then both tabs will inherit the \u201cactive\u201d class when you\u2019re in the archive directory (because \/blog\/ is part of \/blog\/archive\/). One way to get around this limitation would be to be more specific on the first tab \u2013 for instance, linking to \u201c\/blog\/index.php\u201d instead.<\/p>\n<div class=\"wp-socializer wpsr-share-icons \" data-lg-action=\"show\" data-sm-action=\"show\" data-sm-width=\"768\" ><h3>Share and Enjoy !<\/h3><div class=\"wpsr-si-inner\"><div class=\"wpsr-counter wpsrc-sz-32px\" style=\"color:#000\"><span class=\"scount\"><span data-wpsrs=\"\" data-wpsrs-svcs=\"facebook,twitter,linkedin,pinterest,print,pdf\">0<\/span><\/span><small class=\"stext\">Shares<\/small><\/div><div class=\"socializer sr-popup sr-32px sr-circle sr-opacity sr-pad sr-count-1 sr-count-1\"><span class=\"sr-facebook\"><a rel=\"nofollow\" href=\"https:\/\/www.facebook.com\/share.php?u=\" target=\"_blank\"  title=\"Share this on Facebook\"  style=\"color: #ffffff\" ><i class=\"fab fa-facebook-f\"><\/i><span class=\"ctext\"><span data-wpsrs=\"\" data-wpsrs-svcs=\"facebook\">0<\/span><\/span><\/a><\/span>\n<span class=\"sr-twitter\"><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/intent\/tweet?text=%20-%20%20\" target=\"_blank\"  title=\"Tweet this !\"  style=\"color: #ffffff\" ><i class=\"fab fa-twitter\"><\/i><\/a><\/span>\n<span class=\"sr-linkedin\"><a rel=\"nofollow\" href=\"https:\/\/www.linkedin.com\/sharing\/share-offsite\/?url=\" target=\"_blank\"  title=\"Add this to LinkedIn\"  style=\"color: #ffffff\" ><i class=\"fab fa-linkedin-in\"><\/i><\/a><\/span>\n<span class=\"sr-pinterest\"><a rel=\"nofollow\" href=\"https:\/\/www.pinterest.com\/pin\/create\/button\/?url=&amp;media=&amp;description=\" target=\"_blank\"  title=\"Submit this to Pinterest\"  style=\"color: #ffffff\" data-pin-custom=\"true\"><i class=\"fab fa-pinterest\"><\/i><span class=\"ctext\"><span data-wpsrs=\"\" data-wpsrs-svcs=\"pinterest\">0<\/span><\/span><\/a><\/span>\n<span class=\"sr-print\"><a rel=\"nofollow\" href=\"https:\/\/www.printfriendly.com\/print?url=\" target=\"_blank\"  title=\"Print this article \"  style=\"color: #ffffff\" ><i class=\"fa fa-print\"><\/i><\/a><\/span>\n<span class=\"sr-pdf\"><a rel=\"nofollow\" href=\"https:\/\/www.printfriendly.com\/print?url=\" target=\"_blank\"  title=\"Convert to PDF\"  style=\"color: #ffffff\" ><i class=\"fa fa-file-pdf\"><\/i><\/a><\/span><\/div><\/div><\/div>","protected":false},"excerpt":{"rendered":"<\/p>\n<p>I\u2019ve developed a trick over the years that I\u2019ve used on a number of websites now for making my sites\u2019 navigation bars \u201cintelligent\u201d or \u201cself-aware.\u201d By that, I mean that the navigation bar automatically knows which tab\/button\/whatever should be considered [&#8230;]<\/p>\n<p><a class=\"more-link article\" href=\"https:\/\/cssdeck.com\/blog\/intelligent-navigation\/\" title=\"Click to read 'Intelligent Navigation Bars with JavaScript and CSS'\">Read Article<\/a><\/p>\n","protected":false},"author":18,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[188],"tags":[],"_links":{"self":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/posts\/33"}],"collection":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/users\/18"}],"replies":[{"embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/comments?post=33"}],"version-history":[{"count":0,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/posts\/33\/revisions"}],"wp:attachment":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/media?parent=33"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/categories?post=33"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/tags?post=33"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}