Using the DOM with my Image Replacement technique to create Drop Caps on the fly

This article was first published on tjkdesign.com (01-01-2006).

Thanks to Michael from Valley Web Designs for suggesting I try the technique to create Drop Caps.

A Drop Cap is the first letter of a paragraph that appears larger and drops down two or more lines. Fancy CSS or scripts replace that letter with an image. This solution is about doing all of this and more...

We start with this simple (X)HTML markup:

<p>Lorem ipsum ...</p>
<p>Puis nostrud ...</p>
<p>Paliquip exea ...</p>
<p>Quoi ad minim ...</p>
<p>Sans reprehenderit ...</p>

That's all we need. The magic happens when the page loads:

Authors have nothing else to do other than making sure they have an image for every letter that starts a paragraph.

Take a look at this technique in action

Using CSS rules:

In case you wish to style them, span and img elements have been given a class:

How to use this script:

First, download TJK_dropCap.zip (1 KB) and unzip the file into a directory within your site. Then, use a script element to link the JS file (TJK_dropCap.js) to your pages within the head element of your documents, as shown below:

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

Note: In this case, the file has been saved inside a directory called "JS" within the root folder.

Then you'll need to use the onload event to call the function. I'd recommend using this technique; but most important, do not forget to pass the proper parameters to the function. These are two examples using the ONLOAD attribute of the body element:

<body onload="TJK_dropCap(50,50);">.
Your images are 50 pixels wide by 50 pixels high, all the paragraphs in your document will have Drop Caps.
<body onload="TJK_dropCap(40,70,'content');">.
Your images are 40 pixels wide by 70 pixels high, Drop Caps will appear only in paragraphs within the wrapper #content.

Things to make sure of:

Is this technique "safe" to use?

If you look at the generated source code of the demo page you see that the spans contain both the letter and the image. That first letter is present regardless of the status of the image (created or not, downloaded or not).

For the curious:

This is the script:

function TJK_dropCap(z_Width,z_Height,z_Node_ID){// v1.2.1 Copyright (c) 2006 TJKDesign - Thierry Koblentz
// Edit "z_FolderPath" to match the path of your image folder and replace the file extension *if* needed
    if (!document.getElementsByTagName || !document.createElement) return;
    if (!z_Width || !z_Height) alert("TJK_dropCap: Missing parameter(s)");
    var z_El = (z_Node_ID) ? document.getElementById(z_Node_ID) : document;
    var z_P = z_El.getElementsByTagName("p");
    var z_FolderPath = "<span class="highlighter">/articles/img/</span>";
    for (var z=0;z<z_P.length;z++){
        var z_FILE =z_FolderPath+z_P[z].firstChild.data.charAt(0)+".gif";
        var z_Span = document.createElement('span');
        var z_Image = document.createElement('img');
        var z_Letter = document.createTextNode(z_P[z].firstChild.data.charAt(0));
        z_P[z].firstChild.data=z_P[z].firstChild.data.slice(1); // removes first letter
        z_P[z].insertBefore(z_Span,z_P[z].firstChild);
        z_Span.appendChild(z_Image);
        z_Span.appendChild(z_Letter);
        z_Span.style.height=z_Height+"px";
        z_Span.style.width=z_Width+"px";
        z_Span.className="z_SpanClass";
        z_Span.style.fontSize=eval(z_Height-10)+"px"; // letters like "Q" are not cut-off
        z_Image.width="1"; // JS on / CSS off
        z_Image.className="z_ImageClass";
        z_Image.style.width=z_Width+"px";
        z_Image.style.height=z_Height+"px";
        z_Image.alt="";
        z_Image.src=z_FILE;
    }
}
document.write('<style type="text/css">.z_SpanClass {float:left;display:block;position:relative;margin-right:5px;text-transform:uppercase;font-weight:bold;overflow:hidden}.z_ImageClass{position:absolute}</style>');

This script should degrade nicely in JS-challenged UAs.