How to dynamically change the color of the selected menu item of a web page?
Asked Answered
F

8

20

I am new to developing web pages. I am looking to create menus similar to the ones in stackoverflow.com (like Questions, Tags, Users shown above). How do I change the color of the selected menu (for example, the background color of the Question changes to orange when 'clicked')?

I have managed to change the color while hovering (using CSS) as that was simple, but I am having trouble with this.

Can I achieve this effect of changing the color of a clicked item using only CSS?

Fritter answered 4/6, 2011 at 21:48 Comment(2)
I think there is a %20 chance people will answer. (Try to approve answers to your other questions to improve your chances of future questions being answered.)Wilden
well, i wasn't aware of that fact. I always vote for my answers. Thanks for letting me know.Fritter
C
25

Set the styles for class active and hover:


Than you need to make the li active, on the server side. So when you are drawing the menu, you should know which page is loaded and set it to:

 <li class="active">Question</li>
 <li>Tags</li>
 <li>Users</li>

But if you are changing the content without reloading, you cannot change set the active li element on the server, you need to use javascript:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
<style>
  .menu{width: 300px; height: 25; font-size: 18px;}
  .menu li{list-style: none; float: left; margin-right: 4px; padding: 5px;}
  .menu li:hover, .menu li.active {
        background-color: #f90;
    }
</style>
</head>
<body>

<ul class="menu">
<li>Item 1</li>
<li class="active">Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
</ul>

<script type="text/javascript">

var make_button_active = function()
{
  //Get item siblings
  var siblings =($(this).siblings());

  //Remove active class on all buttons
  siblings.each(function (index)
    {
      $(this).removeClass('active');
    }
  )


  //Add the clicked button class
  $(this).addClass('active');
}

//Attach events to menu
$(document).ready(
  function()
  {
    $(".menu li").click(make_button_active);
  }  
)

</script>
</body>

</html>
Claudio answered 4/6, 2011 at 21:53 Comment(7)
Thanks for the suggestion Anze. I am doing it for a static page. Can you suggest me how to do it using javascript ?Fritter
Are you using any javascript frameworks? Like jQuery or MooTools?Claudio
Nope. Do you suggest me to use them ? If so, which is easier to learn ? and which one is better ?Fritter
Well we could start a war about that. The majority uses jQuery, it's quick to learn there is a huge repository of already written plugins. I on the other hand prefer MooTools, I have written quite a few larger plugins for MooTools so that is why it's my preferences. If you are new to this, you should probably use jQuery, because the community is larger.Claudio
And yes, you should use js framework if you want to get things done quick and sharp. If you want to learn the fundamentals of js and sometimes be hurt by it (for example try drag'n'drops), than you should learn how to write js without any framework and than start to use frameworks.Claudio
So, how do you plan to change the content without jumping the site? Because i'm not really sure that you want to do that with javascript. Even if your building a static site, there is url jumping involved. Using javascript to change menus and content is only used when there is a reason for not using the classic linking way. So what reason do you have?Claudio
Basically i have a html page with 3 frames. Frame-1 has the menu items, frame-2 is a header and frame-3 is where the content of the selected link in frame-1 loads. Here is my problem, i need to change only the color of the selected item in frame-1.Fritter
V
9

It would probably be easiest to implement this using JavaScript ... Here's a JQuery script to demo ... As the others mentioned ... we have a class named 'active' to indicate the active tab - NOT the pseudo-class ':active.' We could have just as easily named it anything though ... selected, current, etc., etc.

/* CSS */

#nav { width:480px;margin:1em auto;}

#nav ul {margin:1em auto; padding:0; font:1em "Arial Black",sans-serif; }

#nav ul li{display:inline;} 

#nav ul li a{text-decoration:none; margin:0; padding:.25em 25px; background:#666; color:#ffffff;} 

#nav ul li a:hover{background:#ff9900; color:#ffffff;} 

#nav ul li a.active {background:#ff9900; color:#ffffff;} 

/* JQuery Example */

<script type="text/javascript">
$(function (){

    $('#nav ul li a').each(function(){
        var path = window.location.href;
        var current = path.substring(path.lastIndexOf('/')+1);
        var url = $(this).attr('href');

        if(url == current){
            $(this).addClass('active');
        };
    });         
});

</script>

 /* HTML */

<div id="nav" >
    <ul>
        <li><a href='index.php?1'>One</a></li>
        <li><a href='index.php?2'>Two</a></li>
        <li><a href='index.php?3'>Three</a></li>
        <li><a href='index.php?4'>Four</a></li>
    </ul>
</div>
Vanettavang answered 5/6, 2011 at 0:10 Comment(4)
I guess i have to replicate your code in every page where i want the menu. My pages are a little different. Here is my problem explained in other words. Please let me know if i am not clear. Basically i have a html page with 3 frames. Frame-1 has the menu items, frame-2 is a header and frame-3 is where the content of the selected link in frame-1 loads. Here is my problem, i need to change only the color of the selected item in frame-1.Fritter
Please don't mind my immediate previous comment. This is my inference after executing your code above. I observed that the color of the selected menu item is changed when it is clicked(and the link opens in a new window), but as i return to the page containing the menu, the selected menu item loses its changed color immediately. I want the current menu item to go back to its original color only when another menu item is clicked. Can you recommend something for this effect ?Fritter
The code I'm using here is actually adding the active class to the current url if it is defined in the href attribute of the link ... not on the click event ... Basically what its saying is ... "If the url matches the link add the class active to the anchor element" As far as opening in a new window ... I'm not sure what you have going on there ...Vanettavang
Sorry for the gravedig(?), but I would like to point out that if you're on the index (and the basename isn't revealed), this code won't work. I worked around this by getting the current URL from the server and telling it to the client.Ambidexterity
R
4

I'm late to this question, but it's really super easy. You just define multiple tab classes in your css file, and then load the required tab as your class in the php file while creating the LI tag.

Here's an example of doing it entirely on the server:

CSS

html ul.tabs li.activeTab1, html ul.tabs li.activeTab1 a:hover, html ul.tabs li.activeTab1 a  { 
    background: #0076B5;
    color: white;
    border-bottom: 1px solid #0076B5;
}

html ul.tabs li.activeTab2, html ul.tabs li.activeTab2 a:hover, html ul.tabs li.activeTab2 a {
    background: #008C5D;
    color: white;
    border-bottom: 1px solid #008C5D;
}

PHP

<ul class="tabs">
    <li <?php print 'class="activeTab1"' ?>>
        <a href="<?php print 'Tab1.php';?>">Tab 1</a>
    </li>

    <li <?php print 'class="activeTab2"' ?>>
        <a href="<?php print 'Tab2.php';?>">Tab 2</a>
    </li>
</ul>
Rigidify answered 3/2, 2012 at 21:58 Comment(0)
U
3

Assuming you want to change the colour of the currently selected link/tab... you're best bet is to apply a class (say active) to the currently selected link/tab and then style this differently.

Example style could be:

li.active, a.active {
  background-color: #f90;
}
Ufa answered 4/6, 2011 at 21:54 Comment(4)
using active only helps to change color for a fraction of a second when the link is clicked and held. I am looking for some trick to make the menu item hold its changed color until another menu item is clicked.Fritter
@Fritter Not the :active pseudo class. Just a normal class with the value active.Chesna
@melhoseiny: are you suggesting to have a class like this in my CSS li.active, a.active { background-color: #f90;} and i assign the class to the class to the menu item like this in my html file ? <li class="active"><a href="Questions.html">Questions</a></li>Fritter
But this won't change the background color dynamically. So, when i click a menu item it will change the background color and that color will remain for ever, right ?Fritter
S
3

I use PHP to find the URL and match the page name (without the extension of .php, also I can add multiple pages that all have the same word in common like contact, contactform, etc. All will have that class added) and add a class with PHP to change the color, etc. For that you would have to save your pages with file extension .php.

Here is a demo. Change your links and pages as required. The CSS class for all the links is .tab and for the active link there is also another class of .currentpage (as is the PHP function) so that is where you will overwrite your CSS rules. You could name them whatever you like.

<?php # Using REQUEST_URI
    $currentpage = $_SERVER['REQUEST_URI'];?>
    <div class="nav">
        <div class="tab
             <?php
                 if(preg_match("/index/i", $currentpage)||($currentpage=="/"))
                     echo " currentpage";
             ?>"><a href="index.php">Home</a>
         </div>
         <div class="tab
             <?php
                 if(preg_match("/services/i", $currentpage))
                     echo " currentpage";
             ?>"><a href="services.php">Services</a>
         </div>
         <div class="tab
             <?php
                 if(preg_match("/about/i", $currentpage))
                     echo " currentpage";
             ?>"><a href="about.php">About</a>
         </div>
         <div class="tab
             <?php
                 if(preg_match("/contact/i", $currentpage))
                     echo " currentpage";
             ?>"><a href="contact.php">Contact</a>
         </div>
     </div> <!--nav-->
Staciastacie answered 5/6, 2011 at 1:2 Comment(0)
E
3

There is a pure CSS solution I'm currently using.

Add a body ID (or class) identifying your pages and your menu items, then use something like:

HTML:

<html>
    <body id="body_questions">
        <ul class="menu">
            <li id="questions">Question</li>
            <li id="tags">Tags</li>
            <li id="users">Users</li>
        </ul>
        ...
    </body>
</html>

CSS:

.menu li:hover,
#body_questions #questions,
#body_tags      #tags,
#body_users     #users {
    background-color: #f90;
}
Elf answered 5/6, 2011 at 2:0 Comment(2)
Thanks for your help. I have a doubt in this implementation. Do i have to have my menu (questions, tags, users) in every page. In this case there are 3 html files namely questions.html, tags.html and users.html ? Should all these html files have the above code (with different body id/class) ?Fritter
If you can use some page processor like php, you may post your menu code in a separate file and include it in every page. If not, you will need to repeat it everywhere. But in both cases, yes, you must only change the body id/class for every page, the menu snip is the same for all pages. (sorry about my english)Elf
S
3

Try this. It holds the color until another item is clicked.

<style type="text/css">

.activeElem{
 background-color:lightblue
}       
.desactiveElem{
 background-color:none
}       

}

</style>

<script type="text/javascript">
var activeElemId;
function activateItem(elemId) {
 document.getElementById(elemId).className="activeElem";
 if(null!=activeElemId) {
   document.getElementById(activeElemId).className="desactiveElem";
 }
 activeElemId=elemId;

}
</script>

<li id="aaa"><a href="#" onclick="javascript:activateItem('aaa');">AAA</a>
<li id="bbb"><a href="#" onClick="javascript:activateItem('bbb');">BBB</a>
<li id="ccc"><a href="#" onClick="javascript:activateItem('ccc');">CCC</a>
Shive answered 9/4, 2012 at 9:9 Comment(0)
F
2

At last I managed to achieve what I intended with all your help and the post Change a link style onclick. Here is the code for that. I used JavaScript for doing this.

<html>
    <head>
        <style type="text/css">
            .item {
                width:900px;
                padding:0;
                margin:0;
                list-style-type:none;
            }

            a {
                display:block;
                width:60;
                line-height:25px; /*24px*/
                border-bottom:1px  none #808080;
                font-family:'arial narrow',sans-serif;
                color:#00F;
                text-align:center;
                text-decoration:none;
                background:#CCC;
                border-radius: 5px;
                -webkit-border-radius: 5px;
                -moz-border-radius: 5px;
                margin-bottom:0em;
                padding: 0px;
            }

            a.item {
                float:left;        /* For horizontal left to right display. */
                width:145px;       /* For maintaining equal  */
                margin-right: 5px; /* space between two boxes. */
            }

            a.selected{
                background:orange;
                color:white;
            }
        </style>
    </head>
    <body>
        <a class="item" href="#" >item 1</a>
        <a class="item" href="#" >item 2</a>
        <a class="item" href="#" >item 3</a>
        <a class="item" href="#" >item 4</a>
        <a class="item" href="#" >item 5</a>
        <a class="item" href="#" >item 6</a>

        <script>
            var anchorArr=document.getElementsByTagName("a");
            var prevA="";
            for(var i=0;i<anchorArr.length;i++)
            {
                anchorArr[i].onclick = function(){
                    if(prevA!="" && prevA!=this)
                    {
                        prevA.className="item";
                    }
                    this.className="item selected";
                    prevA=this;
                }
            }
        </script>
    </body>
</html>
Fritter answered 4/6, 2011 at 21:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.