Archive for August, 2006

Nifty CSS Link Hover Effect

Posted on August 30, 2006 in Presentation by Jeff Starr

This nifty CSS link hover effect magically reveals a hidden span of text after specified links. The trick employs an anonymous span nested within an anchor tag. CSS then acts upon the markup with a set of rules that basically says hide the nested span until the link is hovered. Here is an example.

Here is the CSS code and XHTML markup that makes it happen:

a:link, a:visited {
	text-decoration: underline;
	color: #990000;
}
a:hover, a:active {
	text-decoration: none;
	color: #990000;
}
li a:link span, li a:visited span {
	display: none;
}
li a:hover span, li a:active span {
	display: inline;
}
<ul>
 <li><a href="#">Here is a nice link <span> &raquo; select this item</span></a></li>
 <li><a href="#">Here is a nice link <span> &raquo; select this item</span></a></li>
 <li><a href="#">Here is a nice link <span> &raquo; select this item</span></a></li>
</ul>

XHTML Document Header Resource

Posted on August 30, 2006 in Structure by Jeff Starr

This XHTML header tags resource is a work in progress, perpetually expanding and evolving as new information is obtained, explored, and integrated. Hopefully, you will find it useful in some way. Even better, perhaps you will share any complimentary or critical information concerning the contents of this article.

Table of Contents

Continue Reading

Auto Clear and Restore Form Elements

Posted on August 29, 2006 in Function by Jeff Starr

Using a small bit of JavaScript, it is possible to auto-clear and restore form elements when users bring focus to them. Simply copy, paste, and modify the following code example to achieve an effect similar to this:

 
<form action="http://domain.com/" method="post">
   <p>
      <input value="Click here and this will disappear.." onfocus="if(this.value == 'Click here and this will disappear..') {this.value = '';}" onblur="if (this.value == '') {this.value = 'Click here and this will disappear..';}" type="text" size="77" />
   </p>
</form>

Update [January 2nd, 2007] » Here is another auto-clear JavaScript trick that cleans up the (X)HTML code but does not auto-restore the element. Simply place the first code block into the document head (or external JavaScript file), and then flesh out form elements in the second of block of code and place within the document body:

<script type="text/javascript">
<!--//--><![CDATA[//><!--
   function m(el) {
      if ( el.defaultValue == el.value ) el.value = "";
}
//--><!]]>
</script>
<form method="post" action="<?php echo $PHP_SELF; ?>">
 <p>
  <input type="text" name="target" value="This will disappear upon user focus.." onFocus="m(this)">
  <input type="submit" name="submit" value="Submit">
 </p>
</form>

Optimize Convoluted Code via JavaScript

Posted on August 29, 2006 in Function, Optimization by Jeff Starr

Search engines loathe crawling through convoluted lines of code. Oceans of complex JavaScript scare away the priceless indexing and archiving efforts of most major search engines, which will generally abort a crawl upon encountering such mess. The good news is that search engines actually do not deploy JavaScript, so it is possible to use JavaScript to hide those miles of messy code by using the fundamental document.write function.

Place this function in an external JavaScript file, “navmenu.js”:

function navMenu() {
   document.open();
   document.write("<div>Convoluted code goes here.</div>");
   document.close();
}

Link to the external JavaScript file by placing this code in the document head:

<script src="js/navmenu.js" type="text/javascript"></script>

Finally, call the function by adding this to the target location within the document body:

<script type="text/javascript">
<!--//--><![CDATA[//><!--

   navMenu();

//--><!]]>
</script>

HTML Frames Notes Plus

Posted on August 29, 2006 in Structure by Jeff Starr

If you think that nobody uses frames anymore, think again. I personally know of one person who threw down some tuf HTML frame action for a personal site. So, in the interest of prosperity, we are hereby establishing this post as our official dumping ground for all HTML frame-related garbage.

Break your pages out of someone else’s frames

We begin our journey with a totally sick JavaScript method for breaking pages out of the illegitimate frames of some ineffectually pathetic bastard:

<script type="text/javascript">
<!--//--><![CDATA[//><!--

   if (window.self ! = window.top) window.top.location = window.self.location;

//--><!]]>
</script>

Likewise, here is an equally effective method that should work in all JS-enabled browsers:

<script type="text/javascript">
<!--//--><![CDATA[//><!--

if (window.frames) {
   if (parent != self) {
   location.href="index.html"
   }
}

//--><!]]>
</script>

Alternatively, this method also works well in all non-NN browsers:

<script type="text/javascript">
<!--//--><![CDATA[//><!--

if (parent.frames.length > 0) {
   parent.location.href = location.href;
}

//--><!]]>
</script>

Here is a similar version of the previous method:

<script type="text/javascript">
<!--//--><![CDATA[//><!--

if (parent.frames.length > 0) top.location.replace(document.location);

//--><!]]>
</script>

Here is yet another slightly similar version:

<script type="text/javascript">
<!--//--><![CDATA[//><!--

if (top.frames.length > 0) {
   top.location = self.location;
}

//--><!]]>
</script>

Yet another fine method for breaking out of frames:

<script type="text/javascript">
<!--//--><![CDATA[//><!--

if ( top.location != document.location.href ) { 
   top.location = document.location.href; 
}

//--><!]]>
</script>

Here is the script we use for Monzilla Media (monzilla.biz):

<script type="text/javascript">
<!--//--><![CDATA[//><!--

if ( self.location.href != top.location.href ) {
   top.location.href = self.location.href;
}

//--><!]]>
</script>

This method stops recursively framed pages:

<script type="text/javascript">
<!--//--><![CDATA[//><!--

if ( window != top ) 
   top.location.href = window.location.href;

//--><!]]>
</script>

This method works great at breaking out and redirecting the browser to the original page:

<script type="text/javascript">
<!--//--><![CDATA[//><!--

var parent_location = new String(parent.location);
   if ( ( top.location != location ) && parent_location.indexOf('http://domain.tld/path/to/page.html') != 0 )
   top.location.href = document.location.href;

//--><!]]>
</script>

Optimize the content of an iframe

Moving right along, here is a helpful method for optimizing the content of an iframe. This code basically displays a link to the content that should be displayed if everything is working correctly. If for some reason the content is not displayed, the link will appear in its place, thereby enabling users to access the missing content via a new window:

<iframe src="page.html" width="333" height="333" scrolling="auto" frameborder="1">
   <a href="page.html" target="_blank">
      [Your browser does not support frames or is configured not to display frames. Click here to visit the related document.]
   </a>
</iframe>

Control frameborder and scroll attributes for iframes via CSS

To control the frameborder=”value” and scroll=”yes/no” attributes for iframes using CSS, add the following styles to the document which is being displayed in the iframe:

<style type="text/css">
html, body {
   overflow: hidden;
   border: none;
}
</style>

This method works on all IE 4+ with the following exceptions:

IE 4

  • Ignores overflow on html and body elements (i.e., no scrollbar elimination in IE 4)
  • Border property must be applied to the body element

IE 5 and IE 5.5

  • Overflow property must be applied to the body element
  • Border property may be applied to either the html or the body element

IE 6 / Quirks Mode (Transitional DTD)

  • Overflow property must be applied to the body element
  • Border property may be applied to either the html or the body element

IE 6 / Standards Mode (Transitional DTD)

  • Overflow property must be applied to the html element
  • Border property must be applied to the html element

BlogStats PCC Plugin

Posted on August 28, 2006 in WordPress by Jeff Starr

Announcing the BlogStats PCC plugin for WordPress! BlogStats PCC is the easy way to display the total number of posts, comments, categories, as well as several other great statistics for your WordPress-powered website. With BlogStats PCC, you display only the information you want, where you want — inside or outside of the WordPress loop. Completely customizable, BlogStats PCC will display any combination of statistics you choose. This plugin is highly flexible, simple to use, and completely free.

Update: New version of BlogStats PCC now available! The new version now provides all of these great site statistics:

  • Total number of posts
  • Total number of comments
  • Total number of categories
  • Total number of members
  • Total number of guests
  • Total number of pages
  • Date of most recent update
  • Most recent commentator
  • Most recent post

Display any or all of the provided site statistics — customize your own set to provide only the statistics you want!

Installation and Usage

  1. Unzip blogstats-pcc.zip and copy blogstats-pcc.php to your plugins directory.
  2. Upload and activate via WordPress plugin admin panel.
  3. Add any of the following calls to wherever you would like the information displayed:
Display the entire set of statistics in a nice list format:
<?php if (function_exists('fullstats')) { fullstats(); } ?>

Display the total number of posts, comments, and categories:
<?php if (function_exists('blogstats')) { blogstats(); } ?>

Display the total number of posts:
<?php if (function_exists('poststats')) { poststats(); } ?>

Display the total number of comments:
<?php if (function_exists('commstats')) { commstats(); } ?>

Display the total number of categories:
<?php if (function_exists('catstats')) { catstats(); } ?>

Display the total number of registered users:
<?php if (function_exists('regusers')) { regusers(); } ?>

Display the total number of unregistered users:
<?php if (function_exists('userstats')) { userstats(); } ?>

Display the total number of individual, static pages:
<?php if (function_exists('pagestats')) { pagestats(); } ?>

Display the date of the most recent post modification:
<?php if (function_exists('modstats')) { modstats(); } ?>

Display a link to the most recently published blog post:
<?php if (function_exists('recpost')) { recpost(); } ?>

Display the name of the most recent commentator as a link:
<?php if (function_exists('reccomm')) { reccomm(); } ?>

Display the date of the last update in your blog's default date format:
<?php if (function_exists('recstats')) { recstats(); } ?>

Download the Latest Version

Download BlogStats PCC [ version 2.3.1 | ~3KB | .zip | 902 downloads ]

Previous/Alternate versions of BlogStats PCC

Display the Total Number of WordPress Posts, Comments, and Categories

Posted on August 28, 2006 in Function, WordPress by Jeff Starr

Would you like to display the total number of posts, comments, and categories for your WordPress-powered website? Here is the code that can make it happen 1!

Update: The count posts part of this method should only be used for WordPress versions less than 2.5. For WordPress versions 2.5 and better, there is a built-in function for displaying the total number of posts. See The WordPress Codex for more information.

<?php
$numposts = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_status = 'publish'");
if (0 < $numposts) $numposts = number_format($numposts); 

$numcomms = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = '1'");
if (0 < $numcomms) $numcomms = number_format($numcomms);

$numcats = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->categories");
if (0 < $numcats) $numcats = number_format($numcats);
?>
<p><?php printf(__('There are currently %1$s <a href="%2$s" title="Posts">posts</a> and %3$s <a href="%4$s" title="Comments">comments</a>, contained within %5$s <a href="%6$s" title="categories">categories</a>.'), $numposts, 'edit.php',  $numcomms, 'edit-comments.php', $numcats, 'categories.php'); ?></p>

Here is a modified version of the code, customized for our use here at Perishable Press:

<?php
$numposts = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_status = 'publish'");
if (0 < $numposts) $numposts = number_format($numposts); 
$numcomms = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = '1'");
if (0 < $numcomms) $numcomms = number_format($numcomms);
$numcats = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->categories");
if (0 < $numcats) $numcats = number_format($numcats);
?>

<?php echo $numposts . ' posts and ' . $numcomms . ' comments in ' . $numcats . ' categories'; ?>

Footnotes

Accessibility Notes Plus

Posted on August 28, 2006 in Accessibility by Jeff Starr

Just a few useful accessibility notes..

Add accesskey attributes to important list items, content areas, and any other key areas of the document.

Use alphanumeric characters as accesskey values, as in this example:

<ul>
   <li><a id="home" accesskey="h" href="http://domain.com/home.html"><span class="accesskey">h</span>home</a></li>
   <li><a id="menu" accesskey="m" href="http://domain.com/menu.html"><span class="accesskey">m</span>menu</a></li>
   <li><a id="search" accesskey="s" href="http://domain.com/search.html"><span class="accesskey">s</span>search</a></li>
</ul>

When an accesskey attribute is present within a link tag, pressing alt+letter on the keyboard is equivalent to double-clicking that link. Generally speaking, the presence of an accesskey attribute within an element brings focus to that element. Thus, radio and check boxes are toggled, links are clicked, and form elements are navigated as the alt+letter combination is pressed.

It is also helpful to provide “skip-to” links that target specific areas of the site. For example, you may wish to enable users of screen readers to skip past or skip to navigational controls:

<div class="hide">
 <ul id="top" class="access">
  <li><a href="#content" title="Skip to Content" accesskey="c">Skip to Content</a></li>
  <li><a href="#navigation" title="Skip to Menu" accesskey="m">Skip to Menu</a></li>
  <li><a href="#search" title="Skip to Search" accesskey="s">Skip to Search</a></li>
 </ul>
</div>

However, due to current lack of widespread browser support, explicit id-targeting may serve better:

<a href="#menu" title="Skip to navigation menu">Skip to navigation menu</a>
<a href="#content" title="Skip to main content">Skip to main content</a>

Another useful accessibility tool involving document meta-navigation is the tabindex, which is a numerical index that represents each element’s position in the tabbing order. By default, certain elements are ignored by the tabindex, while others retain a default order which may be overridden with explicitly stated tabindex values. Consider the following example, in which the tabbing order will be "red", "yellow", "blue", regardless of where the input elements appear on the page:

<form>
 <input id="red" tabindex="1" />
 <input id="yellow" tabindex="2" />
 <input id="blue" tabindex="3" />
</form>

More to come..

Spamless Email Address via JavaScript

Posted on August 28, 2006 in Function by Jeff Starr

[ Photo of Mr. T ] Let’s face it, spam sucks. Give spammers the figurative finger by using this nifty bit of JavaScript to hide your email address from the harvesters. Here is an easy “copy-&-paste” snippet for including a spam-proof email address in your web pages. Although there are a million ways of doing this, I am posting this for the record (and because I just can’t stand deleting usable code). This technique uses JavaScript, and therefore is not 100% ideal for all users. My advice would be to include a <noscript> element that contains an image of your email address. That way, users without JavaScript will still have access to your (spam-proof) email address. Of course, image-based text presents issues for text-only browsers, but hey, you gotta start somewhere! ;)

Spamless Email

Secure the function by adding this block of code to the document head, or by placing it within an external JavaScript file:

<script type="text/javascript">
<!--//--><![CDATA[//><!--

function email(name, domain, extension) {
   if (!document.write) return false;
   if (document.write) {
      var name; var domain; var extension;
      document.write('<a href="' + 'mailto:' + name + '@' + domain + '.' + extension + '">' + name + '@' + domain + '.' + extension + '<\/a>');
   }
}

//--><!]]>
</script>

Then, add this to the document body, replacing the three variables with real values:

<script type="text/javascript">
<!--//--><![CDATA[//><!--

email("name", "domain", "extension");

//--><!]]>
</script>

Finally, you may also add this line for those without JavaScript:

<noscript><p>(enable javascript or view source to see the email link)</p></noscript>

Or, you may wish to create a text-image of your email address for display on non-JavaScript machines:

<noscript>
   <img src="images/email.gif" alt="Email Address" class="noscript" style="border: 0px;" />
</noscript>

Specific Example

Here is an example of how the function may be configured on an actual web page. This is the specific code that we use at Monzilla Media to hide email addresses from the spamholes:

<script type="text/javascript">
<!--//--><![CDATA[//><!--

function email(m, o, n) {
   if (!document.write) return false;
   if (document.write) {
      var m; var o; var n;
      document.write('<p>Contact: <a href="' + 'mailto:' + m + '@' + o + '.' + n + '?subject=General%20Business" title="Contact">' + m + '@' + o + '.' + n + '<\/a><\/p>');
   }
}

//--><!]]>
</script>

<script type="text/javascript">
<!--//--><![CDATA[//><!--

email("m0n", "monzilla", "biz");

//--><!]]>
</script>

<noscript><p>(enable javascript or view source to see the email link)</p></noscript>

Crazy CSS Underline Effects

Posted on August 27, 2006 in Presentation by Jeff Starr

Check out these crazy CSS underline effects:

u.double { /* -- double underline -- */
	border-bottom: 1px solid;
}
.altdouble { /* alternate double */
	border-bottom: 3px double;
	line-height: 1.7em;
}
u.triple { /* -- triple threat -- */
	border-bottom: 3px double;
	line-height: 1.9em;
}

Double Underline Effects! (via u.double class)

Alternate Double Underline! (via .altdouble class)

Triple Underline Effects! (via u.triple class)

Note: if these examples do not display correctly with the current theme, click here to see them in action!

CSS Hack Dumpster

Posted on August 27, 2006 in Presentation by Jeff Starr

Consider this page a virtual dumpster of wonderful CSS hacks..

Commented Backslash Hack V2

This hack effectively hides anything after the “\*/” from MacIE5:

/* commented backslash hack v2 \*/
div#something {
   boder: thin solid red;
}
/* end hack */

May also be used for CSS import directives:

<style type="text/css">
/* commented backslash hack v2 \*/
   @import url(http://www.site.com/stylesheet.css);
/* end hack */
</style>

Fix Division Widths in IE

Fix IE’s crazy box rendering. The first line limits to only IE. The second line

* html div#somediv { /* limits to all IE */
   width: 300px; /* width for WinIE5.x */
   w\idth: 333px; /* width for other IE */
}
div#somediv {
	padding: 33px;
	width: 377; /* width for all other browsers */
}

IE Double Float Bug

IE doubles the margin of any divs floated in the same direction. Great. To fix it, simply display the floated element as inline.

Clearing Divisions

Here are four relatively equally effective methods for clearing unruly divisions:

<div style="clear: both;">&nbsp;</div>
<br style="clear:both;" />
<hr style="clear:both;" />
div#unrulydiv {
   overflow: auto;
   height: 100%;
}

Clearing Floats

div.fix:after {
   content: ".";
   visibility: hidden;
   display: block;
   clear: both;
   height: 0; 
}
div.fix { display: inline-table; }
/* Hides from IE-mac \*/
* html div.fix { height: 1%; }
div.fix { display: block; }
/* End hide from IE-mac */

Or, you could float the parent div, and perhaps any other parents of the parent div — i.e., the float nearly everything method.

Box Model Hacks

IE versions below 6 render element width values to include borders and padding. This hack utilizes comment hacks to hide from all IE5.x:

div#somediv {
width: 33px; /* width for all browsers */
width/**/:/**/ 77px; /* first hide from IE5.0 then hide from IE5.5 */
}

Target Safari/Webkit/KHTML

body:last-child:not(:root:root) div {
	rules: target Safari/Webkit/KHTML only;
}

Target Firefox

This hack targets the body element in Firefox 1.5 & 2.0 only, but is not valid CSS2/CSS3:

/* targets body element in Firefox 1.5 & 2.0 only - invalid CSS2 & valid CSS3 */
body:empty {}

Target/Filter only Internet Explorer 7

Here are several hacks that target IE7, some valid CSS, some not (see code comments for details):

/* targets body element in IE7 only - invalid CSS */
>body {}
/* targets IE7 only - valid CSS */
*:first-child+html {}
/* targets IE7 & modern browsers only - valid CSS */
html>body {}
/* filters IE7, targets other modern browsers - valid CSS */
html>/**/body {}

Target/Filter only Internet Explorer (IE7 and below)

Here is our growing collection of hacks targeting all Internet Explorer, including IE7 and below:

/* targets all descendants of the html element in IE7 & below - invalid CSS */
html* {}
/* applies property in IE7 & below - invalid CSS */
selector { attribute: property !ie; }
/* applies property with importance in IE7 & below - invalid CSS */
selector { attribute: property !important!; }
/* targets IE7 & below - valid CSS */
a:link:visited, a:visited:link {}
/* may be used to target any element */
#target:link:visited, #target:visited:link {}
/* targets IE7 & below - valid CSS */
*:first-child+html {} * html {}
/* applies property in IE7 & below - invalid CSS (this hack is not recommended) */
*property: value;
/* imports stylesheet in all major browsers except IE7 & below */
@import "non-ie-styles.css" all;

Target only Internet Explorer 6 and below

/* applies property in IE6 & below - invalid CSS */
_property: value;
/* applies property in IE6 & below - invalid CSS */
-property: value;
/* targets IE6 & below - valid CSS */
* html {}
selector { 
	attribute: property !important; /* targets all major browsers */
	attribute: property; /* targets IE6 & below - this value overrides previous value */
} 

Filter Opera / Target Opera

This hack filters Opera (9 and below) and targets all modern browsers including IE7:

/* selects body element with class page-body in IE7 & all modern browsers except Opera 9 & below */
body[class|="page-body"] {}

Conversely, this hack targets Opera 9 and below:

/* targets Opera 9 & below - valid CSS */
html:first-child {}

Fun with the input (disabled) element

Employing the disabled attribute of the input element, it is possible to target a wide range of specific browser types. Given this (X)HTML markup:

<input type="hidden" disabled id="dis" />
<p>target element</p>

..it is possible to target and filter our CSS by using any of these hacks:

/* filters IE7 & below - see below for more info */
input[disabled="disabled"] {} 

/* Firefox 1.5 & below, Safari 2.0 & below, Konqueror 3.5 & below (and perhaps future versions of these browsers) - valid HTML & invalid XHTML */
#dis[disabled=""]+p {}

* targets Opera 9 & below (and perhaps future versions) - valid HTML & invalid XHTML */
#dis[disabled="true"]+p {}

More to come!

Conditionally Load WordPress Pages

Posted on August 27, 2006 in Function, WordPress by Jeff Starr

Need to load a WordPress page conditionally? For example, perhaps you need a “special” page to appear for search results? Yes? This simple PHP/JavaScript solution may be just what the doctor ordered!

Simply replace “condition” with the required condition (or delete the if (condition) {} qualifier entirely), and then change the path and file names to suit your specific needs:

<?php
if (condition) {
   echo ("
   <script type=\"text/javascript\">
   <!--//--><![CDATA[//><!--

   parent.location=\"http://www.domain.com/path/to/file.html\"

   //--><!]]>
   </script>
   ");
} else {
   echo ("
   <script type=\"text/javascript\">
   <!--//--><![CDATA[//><!--

   parent.location=\"http://www.domain.com/path/to/other-file.html\"

   //--><!]]>
   </script>
   ");
}
?>

Specifically, I employ the following trickery in my Killer WordPress theme:

<?php endwhile; else: ?>
<?php echo ("
   <script type=\"text/javascript\">
   <!--//--><![CDATA[//><!--

   parent.location=\"http://perishablepress.com/press/?p=58\"

   //--><!]]>
   </script>
"); ?>
<?php endif; ?>

The previous code chunk returns a specially designed search results page that is specifically tailored to suit the Killer theme. Works wonders.

Execute External WordPress Functions

Posted on August 27, 2006 in Function, WordPress by Jeff Starr

To execute WordPress functions in an external directory (i.e., outside of the WordPress install directory), it is necessary to include a call to “wp-blog-header.php” at the top of the external file.

For example, if your WordPress-powered blog is located in a subdirectory called “blog” and the external file is in the domain root (e.g., the external file is located directly in http://domain.com/), add the following code to the top of the external file:

<?php require_once("./blog/wp-blog-header.php"); ?>

This may be generalized by writing:

<?php require($_SERVER['DOCUMENT_ROOT'].'/blog/wp-blog-header.php'); ?>