Multiple Fancy Drop Caps

After I wrote a couple entries (Fancy Drop Cap, Part 1 and Part 2) on creating a drop cap for the first paragraph in a DIV, a couple people asked how one would go about making the drop cap apply to every paragraph in a DIV.

Most of the code can remain the way we left it in Fancy Drop Cap - Part 2. We created a swap_letter() function to:

  1. find the first letter of the paragraph
  2. concatenate that letter with the rest of an image tag if it matches one of the letters in a regular expression
  3. strip the letter out of the paragraph since we want to replace it with the image
  4. prepend the image tag to the paragraph

We also gave the image a class name of "fancy-letter" so that we could style it a bit:

CSS:
  1. .fancy-letter {
  2.  float: left;
  3.  margin: -1px 2px 2px 0;
  4. }

So, what needs to change? Not much actually.

The first thing to do is remove the line that sets the "first_paragraph" variable: var first_paragraph = $('#main-content p')[0]. In its place we'll use jQuery's .each(), which takes the pain out of for loops. All of the work will be done inside this .each() method, starting with setting a variable for "each" of the paragraphs:

JavaScript:
  1. $('#drop-caps p').each(function(index) {
  2.   var paragraph = this;
  3.   . . .
  4. });

We set the paragraph variable as this instead of $(this) for the same reason that we had (in the earlier entries) put the [0] after $('#main-content p') instead of writing $('#main-content p:eq(0)'): because we need to work on the actual DOM node. Also, note that I changed the DIV's id from "main-content" to "drop-caps" for this example, but you can name yours whatever you want.

The rest of the code is pretty much the same, because all we really needed to do was get a different set of elements Here is the new code in all its glory:

JavaScript:
  1. $(document).ready(function(){
  2.   swap_letter();   
  3. });
  4.    
  5. function swap_letter() {
  6.   $('#drop-caps p').each(function(index) {
  7.     var paragraph = this;
  8.     var node = paragraph;
  9.     while (node.childNodes.length) {
  10.       node = node.firstChild;
  11.     }
  12.     var text = node.nodeValue;
  13.     var first_letter = text.substr(0,1);
  14.  
  15.     var match = /[a-zA-Z]/.test(first_letter);
  16.     if ( match ) {
  17.       node.nodeValue = text.slice(1);
  18.       $('<img />')
  19.           .attr('src','/images/alphabet/' + first_letter.toLowerCase() + '.gif')
  20.           .attr('alt',first_letter)
  21.           .addClass('fancy-letter')
  22.           .prependTo( paragraph );
  23.       first_letter = "";
  24.     }
  25.   });
  26. }

For an explanation of the other parts, please refer to Fancy Drop Cap - Part 2 and Fancy Drop Cap - Part 1. In the meantime, feast your eyes on the beauty of these fancy first letters.

This is the first paragraph. The "T" in "This" should be replaced by the drop-cap image. The image is floated left with a little padding to the right and the bottom.

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.

Ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.

10 Responses to “Multiple Fancy Drop Caps”

  1. Ty Says:

    Hey cool, I'm stuck with trying to design a site around an old-english lettering styled large logo.
    Why did drop caps never occur to me. This may be easier to setup for some than sIFR.
    I might just give it a try.
    thanks.

  2. Ty Says:

    Another thought on creating the images required would be to put the whole font character set together in imageReady or Fireworks. Drag out guides to seperate all the letters, and then click create slices from guides. Now save the slices and you're ready to rock and roll!

  3. Karl Says:

    Yeah, slicing is a good idea for getting those letters ready. Thanks for the tip!

  4. Kingsley Says:

    It'd be even better to make a sprite grid out of all the letters.

  5. Jurriaan Says:

    I didn't want to use the image replacement but just a bigger font for the first letter. I could've used the first-letter tag in css but since this doesn't work in IE6 I used the code below to replace the first letter of all paragraphs.

    
    		  swap_letter();
    				});
    				function swap_letter() {
    				  $('#content p').each(function(index) {
    					var paragraph = this;
    					var node = paragraph;
    					while (node.childNodes.length) {
    					  node = node.firstChild;
    					}
    					var text = node.nodeValue;
    					var first_letter = text.substr(0,1);
    					var match = /[a-zA-Z]/.test(first_letter);
    					if ( match ) {
    					  node.nodeValue = text.slice(1);
    					  $('')
    						  .text( first_letter )
    						  .addClass('eerste-letter')
    						  .prependTo( paragraph );
    					  first_letter = "";
    					}
    				  });
    				}
    
    

    CSS

    
    #content .eerste-letter
    font-size:2.5em;
    line-height:90%;
    padding-right:3px;
    text-transform:uppercase;
    }
    
    
  6. Jurriaan Says:

    I'm sorry i pasted the wrong code

    
    swap_letter();
    	});
    	function swap_letter() {
    	  $('#content p').each(function(index) {
    		var paragraph = this;
    		var node = paragraph;
    		while (node.childNodes.length) {
    		  node = node.firstChild;
    		}
    		var text = node.nodeValue;
    		var first_letter = text.substr(0,1);
    		var match = /[a-zA-Z]/.test(first_letter);
    		if ( match ) {
    		  node.nodeValue = text.slice(1);
    		  $('')
    			  .text( first_letter )
    			  .addClass('eerste-letter')
    			  .prependTo( paragraph );
    		  first_letter = "";
    		}
    	  });
    	}
    
    
  7. Jurriaan Says:

    sorry i pasted the wrong code

    
    swap_letter();
    	});
    	function swap_letter() {
    	  $('#content p').each(function(index) {
    		var paragraph = this;
    		var node = paragraph;
    		while (node.childNodes.length) {
    		  node = node.firstChild;
    		}
    		var text = node.nodeValue;
    		var first_letter = text.substr(0,1);
    		var match = /[a-zA-Z]/.test(first_letter);
    		if ( match ) {
    		  node.nodeValue = text.slice(1);
    		  $('')
    			  .text( first_letter )
    			  .addClass('eerste-letter')
    			  .prependTo( paragraph );
    		  first_letter = "";
    		}
    	  });
    	}
    
    
  8. Jurriaan Says:

    wtf it deletes my span tag

  9. Karl Says:

    Jurriaan,

    Did you use &lt; instead of < and &gt; instead of >? (see "IMPORTANT" above comment textarea.)

  10. Everquest platinum Says:

    Thanx For sharing such a beautiful resource. I really appreciate it..

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <pre> <em> <i> <li> <ol> <strike> <strong> <ul>

IMPORTANT: If you wish to post code examples, please wrap them in <code> tags. Multi-line code should be wrapped in <pre><code> </code></pre> Also, use &lt; instead of < and &gt; instead of > in the examples themselves. Otherwise, you could lose part of the comment when it's submitted.