Stylin’ with CSS

The Blog and Books of Charles Wyke-Smith

Click States with jQuery and CSS - Part 1

by Charles Wyke-Smith

One of the most simple and useful tasks that jQuery (a JavaScript-based library) can perform is to add and remove classes from HTML markup, as this enables toggling—a click-once-for-on, click-once-for-off interaction that cannot be achieved using CSS. You can create all kinds of interactivity in your Web pages by using jQuery to add and remove class attributes and so switch between different CSS-based visual states. Let's start by seeing first how CSS styles are applied on a hover, and then by the addition of class to the markup.

Creating Basic Hover and Click Responses

Without the use of JavaScript, CSS interactivity is limited to hover effects, which happen when the cursor moves over an object, and are typically created with the :hover pseudo-class. Figure 1 shows an example of a simple hover effect.


<div class="box1">Hover Me</div>

div.box1 {
	margin:10px 50px;
	height:120px;
	width:150px;
	background:#4eb8ea;
	color:#fff;
	cursor:pointer;
	}
div.box1:hover {background:#f58c21;}
Hover Me
Figure 1 Only hover interactions can be created with CSS. Point at the box to see this for yourself!

Obviously, the styles defined by the :hover pseudo-class rule are only applied as long as the element is being hovered. As Figure 1 illustrates, as soon as the cursor moves off the object, the pseudo-class styles are no longer applied.

However, by using a class name in a CSS selector, the associated CSS styles will be be applied as long as that class is present on an HTML element, regardless of the location of the cursor. So, by using jQuery to manage the addition or removal of a class when an element is clicked, then the changed state persists even when the cursor is no longer over the element. Figure 2 shows the same box, but this time using a class on the element to invoke the CSS for the changed state instead of a CSS :hover pseudo-class.


<div class="box2">Click Me</div>

div.box2 {
	margin:10px 50px;
	height:120px;
	width:150px;
	background:#4eb8ea;
	color:#FFF;
	cursor:pointer;
	}
div.box2.hilite {background:#f58c21;} 
/* note there is no space between class names because they are on same element */
    
Click Me
Figure 2 By adding a class with jQuery, a visual state can be toggled on and off with a click. Click the box to see this for yourself!

Before we look at the jQuery, let's see what happens in the markup. If you open the browser’s Element Inspector (right-click or Control-click on the element, then select Inspect Element from the pop-up), you can see the class being added and removed by jQuery, as the screenshots in Figure 3 illustrate.

screenshot of unclicked element - no class added   screenshot for clicked element - class added
Figure 3 Using the browser’s Element Inspector, you can see the hilite class being added and removed when the element is clicked.

As soon as the class is applied to the HTML element, any CSS that relates to that class is also applied. Let's now look at the jQuery that adds and removes the class. In this case, the CSS that is applied by the addition of the class simply changes the color of the box.

A Simple Class Toggle With jQuery

As I mentioned at the start of this article, a toggle is an interaction that switches between two states each time it is invoked—for example, once for on, once for off. In the example in Figure 2, the class is added on the first click and removed on the second. Here's the jQuery that is added to the head of the document to toggle a class on an HTML element.


<em>// load the jQuery library from Google
<script src="https://ajax.googleapis.com/ajax/libs/
     jquery/1.7.1/jquery.min.js">
<script>
$(document).ready(function(){  // when the page has loaded in browser...
  $('.box2').click(function(){      // bind a click event to the div element...
    $(this).toggleClass('hilite');  // that toggles the 'hilite' class
  });
});

Let's look at how this code works. First, I add the code to load jQuery directly from the Google API libraries into the user’s browser, so I don’t have to host it. Now I can add my jQuery script.

You always want to be sure that the DOM (effectively, the HTML code) is loaded in the browser before you attempt to mainipulate it with jQuery. To ensure this, the code that manages the addition and removal of the hilite class is wrapped inside the document ready function.


$(document).ready(function(){ // runs when the page has loaded in browser
// code goes here
});

Any code inside this function is called only when the DOM is completely loaded. At that point in time, the code binds (attaches) what is called an event listener to the element that will receive the click—the div with the box2 class. Because the element might be clicked at any time, the event listener, as its name suggests, patiently listens for its event and calls its related function when that event happens. (A function that waits to runs its code until a specific event occurs is known as a callback function.)


$(document).ready(function(){            
$('.box2').click(function(){ // binds event listener to box2 element
  });
});

jQuery selects the element with the box2 class, and binds a function that will be triggered when the event occurs—alternately adding or removing the class from the element.


$(document).ready(function(){
  $('.box2').click(function() {
    $(this).toggleClass('hilite');  // toggles the 'hilite' class
  });
});

Note the use of the jQuery selector $(this), which, inside a click callback handler, references the clicked element. $(this) references the element with the box2 class that was selected in the second line of the code. (Note that $(this) and this are different in jQuery). The toggleClass function which alternately adds and removes the class each time it is called.

Toggling a Class on Multiple HTML Elements with jQuery

In the previous example, the code simply affected one element, but with minimal modification, the same code can add and remove a class from a set of elements; here, each element in the set shares the same class.


<div class="boxSet">Click Me 1</div>
<div class="boxSet">Click Me 2</div>
<div class="boxSet">Click Me 3</div>

$(document).ready(function(){  /* when the page has loaded... */
  $('.boxSet').click(function(){  /* ...bind click event to .boxSet elements */
    $('.boxSet').removeClass('hilite'); /* On click, remove any 'hilite' class */
    $(this).addClass('hilite'); /* ...and add 'hilite' class to clicked element */ 
   });
});
Click Me 1
Click Me 2
Click Me 3
Figure 3 When an element is clicked, the hilite class is removed from all three boxes and then added only to the clicked element.

All three boxes in Figure 3 have the boxSet class, so the event is bound to all of them once the page loads. When one of them is clicked, I first select all three boxes (I can't use $(this) here because it now references the clicked object, not the entire set) and remove the hilite class from them if present. Note you don't have to loop though them to see if the class is present on one of them; instead, simply remove it off all of them, as there is no error generated when attempting to remove a class from an element that does not have it. The $(this) keyword references the clicked element, so I use it to add the class to that element. The net effect is that the highlighting switches to the clicked element.

This article has shown you the basics of managing classes with jQuery and illustrates the power that this give you. In the next article, I'll create a tabbed panel that displays its content with an animation effect when the tabs are clicked, all controlled by CSS and the jQuery addition and removal of classes.

Leave a comment

More posts