Sometimes we want to highlight table columns when they are hovered over. Table rows are easy - it's as simple as adding tr:hover{background:red;} to your CSS. This will cause all table cells in a row to be red when the row is hovered over. However, columns are not as easy. The main reason behind this is that HTML tables are grouped by row, not by column. This means that while it is easy to select a group of table cells as a row (using tr in your CSS, or targeting tr tags in your javascript), it is not as easy to group table cells by columns.

You may think that you can use the html colgroup and col tags, but alas, such is not the case. They will allow for grouping elements by columns. However, these tags are deceptive. While they do allow for some limited styling of columns, they are not actually parents of the td tags that are in the column, and do not respond to the :hover attribute in CSS, nor do they trigger the javascript onmouseover event. Now, if this last statement didn't make sense to you, don't worry, it's not really important. What it is important is that you understand that it takes javascript to be able to highlight an HTML table column. And that is what this tutorial is going to show. It's possible to do this using pure javascript, but I'm a jQuery guy, so I will be showing two jQuery methods of doing this.

Method 1: Static

Step 1: Set up your table, giving common class names to all elements in a column

The first thing we need to do is set up an HTML table. The main point here is that all the cells in a column have the came class name. So let's look at an example:

<table>
	<thead>
		<tr>
			<th class="col1">A</th>
			<th class="col2">B</th>
			<th class="col3">C</th>
			<th class="col4">D</th>
			<th class="col5">E</th>
			<th class="col6">F</th>
			<th class="col7">G</th>
			<th class="col8">H</th>
			<th class="col9">I</th>
			<th class="col10">J</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td class="col1">1</td>
			<td class="col2">2</td>
			<td class="col3">3</td>
			<td class="col4">4</td>
			<td class="col5">5</td>
			<td class="col6">6</td>
			<td class="col7">7</td>
			<td class="col8">8</td>
			<td class="col9">9</td>
			<td class="col10">10</td>
		</tr>
		<tr>
			<td class="col1">1</td>
			<td class="col2">2</td>
			<td class="col3">3</td>
			<td class="col4">4</td>
			<td class="col5">5</td>
			<td class="col6">6</td>
			<td class="col7">7</td>
			<td class="col8">8</td>
			<td class="col9">9</td>
			<td class="col10">10</td>
		</tr>
		<tr>
			<td class="col1">1</td>
			<td class="col2">2</td>
			<td class="col3">3</td>
			<td class="col4">4</td>
			<td class="col5">5</td>
			<td class="col6">6</td>
			<td class="col7">7</td>
			<td class="col8">8</td>
			<td class="col9">9</td>
			<td class="col10">10</td>
		</tr>
		<tr>
			<td class="col1">1</td>
			<td class="col2">2</td>
			<td class="col3">3</td>
			<td class="col4">4</td>
			<td class="col5">5</td>
			<td class="col6">6</td>
			<td class="col7">7</td>
			<td class="col8">8</td>
			<td class="col9">9</td>
			<td class="col10">10</td>
		</tr>
	</tbody>
</table>

As you can see, I've set up a table with one row in the header, using th tags for the cells, and five rows in the body using td tags for the cells. There are ten columns, each cell has a class name, with all the elements in a column having a common class name.

Step 2: Set the CSS

We need to set some CSS to style this table. First, let's set some default styling just to make the table look a little nicer. This isn't actually necessary, but it will make the tutorial easier on the eyes:

table{border-collapse:collapse}
td, th{padding:5px;border:solid black 1px;}

Next we will create a new class. This class will contain the styling we want when a column is hovered over. In this tutorial, we will be setting the background color, as we want to highlight the columns when they are hovered over:

.hover_class{background:pink;}

At the moment, this class doesn't exist in our HTML. Basically, we are pre-loading it as it were, and will then use this class name in step 4 using jQuery. So while the class doesn't exist in the HTML at present, it will be applied after the fact. This is why we need to set it up in the initial CSS. This could be done later on purely in javascript/jQuery, but by creating the class ahead of time, it simplifies the jQuery code that will be used.

Step 3: Link the jQuery library

If you already have jQuery loaded on your page, then you can skip this step. But if you don't have jQuery loaded, you will need it before the script in step 4 will work. This can be done very simply by linking to Google's jQuery library:

<script type="text/javascript" src="<a href="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
">http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></scrip...

Note: It's important (in fact, absolutely necessary), that the link to your jQuery library, whether it be on Google's servers, your own server, or any other location, comes before the script in step four. It will not work otherwise.

Step 4: The jQuery magic

The last step is to set up the jQuery that will highlight the columns. Basically what we want to do is the following:

  1. When a td or th tag is hovered over, get the class name
  2. Add the .hover_class to all other tags that have the class name retrieved in step one
  3. When the td or th tag is done being hovered over, remove the .hover_class from all tags that have it

We will do this using the jQuery .hover() function. This function takes two functions as its arguments. The first function describes what to do on mouse over, and the second function describes what to do on mouse out. We will add a class on mouse over, and remove that class on mouse out, as described above:

<script type="text/javascript">
// We set up our ready function
$(document).ready(function()
{
	// We need to set a global variable to store the class name. This will
        // keep our script more efficient when we need to remove the class name
        // later on, as it allows us to know exactly which elements to remove
        // the class from.
	var cellClassName = false;
	// Next, we set jQuery .hover() on all td and th tags
	$("td, th").hover
	(
		// This first function is our mouse over function
		function()
		{
			// First, we grab the class name of the hovered element.
                        // We save this class name to the global variable we
                        // created earlier, so that we can use this class name
                        // in the mouse out function.
			cellClassName = $(this).attr("class");
			// next, we add the .hover_class to all elements that have
                        // that class
			$("." + cellClassName).addClass("hover_class");
		},
		// This second function is our mouse out function
		function()
		{
			// We remove the .hover_class from the elements that have
                        // it applied, using the class name we saved to the global
                        // variable earlier.
			$("." + cellClassName).removeClass("hover_class");
		}
	);
});
</script>

And there we have it. We are grabbing the class name of the hovered element, adding the hover class to all elements with that class name, then removing that class name when the hovering is finished.

Points to note

This example is very basic at its core. I have tried to keep things as simple as possible. Here are some points to keep in mind:

  1. If you have multiple class names on any of the td or th tags, the script will fail, or at the very least do some strange things. For this script as I am showing it to work, you need to ensure that there is only one class name on each of the cells. If you do have multiple class names on a cell, you will need to expand this script. I personally would grab the class names as has already been done, then use a regex to check whether a particular pattern of class name exists, then use that class name to execute the rest of the script as shown. But, that is further than I am willing to go with this example, as I am trying to keep it simple.
  2. If you want to add hovering to rows, it's as simple as adding tr:hover{background:pink} to your CSS.
  3. As this example requires javascript, users who do not have javascript enabled will not see the columns highlighted.
  4. This code will hit every and any table on the page. You can make the script more efficient by increasing the specificity of the elements targeted. For example, if you give your table an id of #my_table, then you can change the jQuery that targets the td and th tags to be $("#my_table td, #my_table th").hover. This will put less strain on the browser.

Code in its entirety

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "<a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html">http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html</a> xmlns="<a href="http://www.w3.org/1999/xhtml">
">http://www.w3.org/1999/xhtml">
</a>	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
		<title>Highlighting HTML columns with jQuery and CSS</title>
		<style type="text/css">
			table{border-collapse:collapse}
			td, th{padding:5px;border:solid black 1px;}
			.hover_class{background:pink;}
		</style>
		<script type="text/javascript" src="<a href="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
 
">http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></scrip...</a>		<script type="text/javascript">
		    $(document).ready(function()
		    {
			var cellClassName = false;
			$("td, th").hover
			(
				function()
				{
					cellClassName = $(this).attr("class");
					$("." + cellClassName).addClass("hover_class");
				},
				function()
				{
					$("." + cellClassName).removeClass("hover_class");
				}
			);
		    });
		</script>
	</head>
	<body>
		<table>
			<thead>
				<tr>
					<th class="col1">A</th>
					<th class="col2">B</th>
					<th class="col3">C</th>
					<th class="col4">D</th>
					<th class="col5">E</th>
					<th class="col6">F</th>
					<th class="col7">G</th>
					<th class="col8">H</th>
					<th class="col9">I</th>
					<th class="col10">J</th>
				</tr>
			</thead>
			<tbody>
				<tr>
					<td class="col1">1</td>
					<td class="col2">2</td>
					<td class="col3">3</td>
					<td class="col4">4</td>
					<td class="col5">5</td>
					<td class="col6">6</td>
					<td class="col7">7</td>
					<td class="col8">8</td>
					<td class="col9">9</td>
					<td class="col10">10</td>
				</tr>
				<tr>
					<td class="col1">1</td>
					<td class="col2">2</td>
					<td class="col3">3</td>
					<td class="col4">4</td>
					<td class="col5">5</td>
					<td class="col6">6</td>
					<td class="col7">7</td>
					<td class="col8">8</td>
					<td class="col9">9</td>
					<td class="col10">10</td>
				</tr>
				<tr>
					<td class="col1">1</td>
					<td class="col2">2</td>
					<td class="col3">3</td>
					<td class="col4">4</td>
					<td class="col5">5</td>
					<td class="col6">6</td>
					<td class="col7">7</td>
					<td class="col8">8</td>
					<td class="col9">9</td>
					<td class="col10">10</td>
				</tr>
				<tr>
					<td class="col1">1</td>
					<td class="col2">2</td>
					<td class="col3">3</td>
					<td class="col4">4</td>
					<td class="col5">5</td>
					<td class="col6">6</td>
					<td class="col7">7</td>
					<td class="col8">8</td>
					<td class="col9">9</td>
					<td class="col10">10</td>
				</tr>
			</tbody>
		</table>
	</body>

Method 2: Dynamic

This method is a little more resource intensive, but doesn't require any special class names. Please see the last method for the following:

  • The table structure
  • The method for highlighting rows (using CSS)
  • How to link the jQuery library

The jQuery magic

The script below does the following:

  • When a cell is hovered over, it gets the current index of the cell within the row in which it exists
  • It adds the background color to all table cells that are at that index within their own rows

$(document).ready(function()
{
	$("th, td").mouseover(function()
	{
		var targetIndex, elements;
		targetIndex = $(this).index() + 1;
		elements = $("th, td");
		elements.filter(":nth-child(" + targetIndex + ")").css("background-color", "pink");
		elements.not(":nth-child(" + targetIndex + ")").css("background-color", "transparent");
	});
	$("table").mouseleave(function()
	{
		$("th, td").css("background-color", "transparent");
	});
});

A nice little adjustment to this code can actually fade out all of the columns that are NOT hovered over, leaving the current row at full opacity:

$(document).ready(function()
{
	$("th, td").mouseover(function()
	{
		var targetIndex, elements;
		targetIndex = $(this).index() + 1;
		elements = $("th, td");
		elements.filter(":nth-child(" + targetIndex + ")").fadeTo(250, 1);
		elements.not(":nth-child(" + targetIndex + ")").fadeTo(250, 0.5);
	});
	$("table").mouseleave(function()
	{
		$("th, td").fadeTo(250, 1);
	});
});

Some notes:

The way my code is structured above, if you have more than one table on the page, and you were to hover over one of them, the same column in all tables on the page would be highlighted. This isn't exactly ideal. To prevent this, and to also make your script more efficient, you should add the id of the table to each of the $("td, th") selectors on the page. So for example, if your table has an ID of "my_table", you would use the following

$("#my_table td, #my_table th");