Using CSS3 :target selectors
Friday, March 14th, 2008This is a quick post to present a JavaScript that provides CSS3 :target pseudo selector like functionality for browsers that do not provide native :target support.
function() { var cssClass = 'target'; // Initialise targeted fragments if any. var target = document.getElementById(window.location.hash.slice(1)); if (target) { target.className += ' ' + cssClass; } // Click event handler function generator. This is passed a "frag" argument // that is a reference to the target element. var reCSS = new RegExp("\\b" + cssClass + "\\b"); function newTargetClickHandler(frag) { return function() { if (target) { target.className = target.className.replace(reCSS, ''); } target = frag; target.className += ' ' + cssClass; } } // Run thru <a> elements and add an onclick handler to those that reference // document fragments within the current page. var reURI = new RegExp('^' + window.location.href.match(/^[^#]+/)[0] + '#([^#]+)$'); var elems = document.getElementsByTagName('a'); for (var i=0; i<elems.length; i++) { if (elems[i].href && elems[i].href.match(reURI)) { elems[i].onclick = newTargetClickHandler(document.getElementById(RegExp.$1)); } } };
When the user clicks on a link that points to a fragment within the current page, this code will add a CSS class of “target” to the targeted element, and will remove the same “target” class from any previously targeted element.
Originally I was using the CSS3 :target pseudo selector and the .target class selector together in the same rule set, but I found that Opera (9.26) would not apply the rules presumably because it considered it invalid.
/* THIS DOES NOT WORK! */ h2:target, h2.target { color: red; }
I’m not sure if this is correct behavior, but regardless of cause, I found I had to use a duplicate set of CSS rules; one for both modes of selection.
h2:target { color: red; } h2.target { color: red; }
And basically… that’s it! You can see it in action on this test page, and I hope to add a follow up post soon…. time allowing.
You download the the JavaScript here:
Full-fat script with white-space and comments [1621 bytes]
Minified script [1101 bytes]