CSS + jQuery: Highlight important keywords inside text

CSS+jQuery Sample Screenshot

A few days ago while working on a new UI component I had to come up with a solution to highlight identified keywords (using named entity recognition) inside of a chunk of user generated text. While the idea was fairly simple, the challenge was creating a solution which would work [relatively] well for all modern browsers including IE7, IE8, Firefox, Safari, and Chrome.

View Demo

Background

The easiest solution to highlight keywords inside of a chunk of text would be to swap font colors, maybe even change the "highlighted" background color and type weight for added emphasis. However, the easiest solution is not always the best solution. Relying on font color and weight alone is not enough.

  • Images – Photos are full of color, bold, and attractive. Ignore these while toggling the text color of de-emphasized / emphasized content and a visitors eyes will still wander.
  • Dynamic – Content may be user generated. Assuming basic HTML like <em>, <strong>, <a>, etc are supported, original styles should remain untouched.

The better solution would be to create a "mask" overlaying the source content while using a spotlight-esque effect to highlight keywords. The overlay method is a safer option which reduces the likelihood of overriding any user generated content [styles].

Example HTML

This demo is a simplified version of the original code – shared as an example for fading the source content and highlighting important keywords within. Originally planned for use where classes are dynamically generated and wrapped around identified keywords, I have manually inserted classes for the purpose of this demo. The basic example HTML is below (text sampled from the Avatar Wikipedia entry):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div class="wrapper">
	<ul class="entity-results">
		<li><a class="d1" href="#">Summary</a></li>
		<li><a class="d2" href="#">Avatar</a></li>
		<li><a class="d3" href="#">Formats</a></li>
	</ul>
	<div class="content">
		<h2>Avatar (2009 film)</h2>
		<div class="entity-source">
			<img src="images/avatar.jpg" alt="Avatar poster"/>
			<p>Avatar, also known as James Cameron's Avatar, is an American 3-D science fiction epic film written and directed by <a href="http://en.wikipedia.org/wiki/James_Cameron">James Cameron</a>, and was released on December 16, 2009 by 20th Century Fox. The film is co-produced by <a href="http://en.wikipedia.org/wiki/Lightstorm_Entertainment">Lightstorm Entertainment</a>, and <span class="d1">focuses on an epic conflict on Pandora</span>, an inhabited Earth-sized moon of Polyphemus, one of three fictional gas giants orbiting <a href="http://en.wikipedia.org/wiki/Alpha_Centauri_A">Alpha Centauri A</a>. On Pandora, human colonists and the sentient humanoid indigenous inhabitants of Pandora, the Na'vi, engage in a war over the planet's resources and the latter's continued existence. The film's title refers to <span class="d2">an avatar, a representation of a real person in a virtual world</span>.</p>
			<p><span class="d3">The film was released in 2D and 3D formats</span>, along with an IMAX 3D release in selected theaters. The film is being touted as a breakthrough in terms of filmmaking technology, for its development of 3D viewing and stereoscopic filmmaking with cameras that were specially designed for the film's production.</p>
			<p>Read the rest of the <a href="http://en.wikipedia.org/wiki/Avatar_(2009_film)">original Wikipedia page about Avatar</a></p>
			<div class="mask"></div>
		</div>
	</div>
</div>

.entity-results is a sample list corresponding to select text inside of the .entity-source wrapper. Each <li><a></li> has a matching keyword phrase wrapped in the same class. Ideally these are dynamically included in the document. The "mask" is included inline as an empty <div> which can also be inserted using JavaScript.

Minimal CSS requirement

Using a few lines of CSS, overlay a mask above the content. The <span> around the keywords to highlight is crucial in order to pull the text out above the mask.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.entity-source, .entity-source span.show {
	position: relative;
}
.entity-source .mask {
	display:none;
	position:absolute;
	top:0;
	left:0;
	height:100%;
	width:100%;
	z-index:1;
}
.entity-source span {
	z-index:2;
}
.entity-source span.show {
	background:#ffc;
	color:#000;
}

Example jQuery

The example uses jQuery to handle the opacity changes and toggle of active / inactive states for detected keywords.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
jQuery(document).ready(function($) {
    // mask source
    var maskSource = jQuery('.mask');
    jQuery('.entity-results').hover(function() {
        maskSource.animate({opacity:0.7},1).fadeIn('750');
    }, function() {
        maskSource.fadeOut('1000');
    });
 
    // match hover
    var sample1 = jQuery('span.d1');
    var sample2 = jQuery('span.d2');
    var sample3 = jQuery('span.d3');
    jQuery('a.d1').hover(function() {
        sample1.addClass('show');
    }, function() {
        sample1.removeClass('show');
    });
    jQuery('a.d2').hover(function() {
        sample2.addClass('show');
    }, function() {
        sample2.removeClass('show');
    });
    jQuery('a.d3').hover(function() {
        sample3.addClass('show');
    }, function() {
        sample3.removeClass('show');
    });
});

When your mouse cursor hovers over a keyword in the right sidebar, the mask is set to display block with opacity handled by the jQuery .animate() effect. View the demo below or download the source.

View Demo

Discuss - 2 Comments

  1. Social comments and analytics for this post…

    This post was mentioned on Twitter by DesignG33k: CSS + jQuery: Highlight important keywords inside text http://bit.ly/6wO1ut

  2. […] “A few days ago while working on a new UI component I had to come up with a solution to highlight identified keywords (using named entity recognition) inside of a chunk of user generated text. While the idea was fairly simple, the challenge was creating a solution which would work [relatively] well for all modern browsers including IE7, IE8, Firefox, Safari, and Chrome. ” Demo | Project Home […]