Unitz LLC
Home   |   Unitz News   |   Contact Us

A Cufón Small Caps Hack

Bookmark and Share
Posted by Paul Reilly at 12:13 am on June 3, 2010 • General,Programming,User interfaces

I love the cufón font replacement technique. It allows developers to use custom fonts dynamically in their websites.  It’s incredibly easy to use compared to earlier options like siFR.  The@font-face CSS3 property (and Google Font Directory!) are of course an even better solution, but the limited browser support means we’ll have to wait awhile before this approach has dominance. For now, Cufón is easy enough and works in just about every browser – even IE6!

I’ve used this approach recently for several sites with dynamic page titles with great success.  That doesn’t mean it still has some limitations. The two biggest in my opinion are the inability to select the replaced text, and the lack of a reliable hover option (so you can change the replaced font color on mouse-over). Another issue that has affected me is the lack of small-caps support. Although it’s slated to be included in a future Cufon version, I hacked together an approach that works now using jQuery and JavaScript regular expressions.

The process is fairly simple – first replace your text with Cufón, then run a regular expression that inserts SPAN tags around the first letter of each word, and then use jQuery to increase the font size of these span’s classes. Simply setting the classes font-size larger in CSS before hand does not work.

Below you can see the three stages of the process that I went through – first I loaded up a headline that uses the CSS small caps attribute – it works but it’s not the font I want. The next headline is Cufon replaced – it looks much better, but I’ve lost the small caps effect. Finally using the hack, I’ve achieved the custom font with small caps.

Un-replaced Text with Small Caps

Replaced Text before Small Caps Hack

Replaced Text with Small Caps

The first step is to load in your various javascript files. You can download cufon and create your own font javascript files at cufon.shoqolate.com.

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="PATHTO/cufon-yui.js"></script>
<script type="text/javascript" src="PATHTO/font-file-you-create.js"></script>

Then you can set up the styles you want your headlines to have:

<style type="text/css">
h1 {
	font-family:times,times new roman, serif;
	font-size:20px;
	text-transform:uppercase;
	color:#900;
}
</style>

The next step is to create your headline:

<h1>This is the headline I'm font-replacing</h1>

Finally, use the follow JavaScript to create the effect:

jQuery(document).ready(function($) {
	Cufon.replace('h1');
	var text = $('h1').html();
	$('h1').html(text.replace(/\b([A-Za-z0-9])/g,'<span class="caps">$1</span>'));
	$('.caps').css('font-size',30);
});

This script, which loads when the DOM is ready, first replaces the font, then inserts <span class=”caps”> around the first letter of each word, and finally increases the font size on these first letters from 20px to 30px. You can of course change these font sizes to meet your needs. The particular font I used here, Adobe Garamond Pro, had a slight line-height offset after this JavaScript was run – I fixed this with a style for the ‘caps’ CSS class – you may need something similar for the font you choose

h1 span.caps {
	position:relative;
	top:2px;	
}

I hope someone finds this useful.

16 Comments

  1. Simply brilliant. Great use of common sense too ;) Thanks.

    Comment by JDesai at 11:28 pm on July 14, 2010

  2. Hi there

    this is exactly what I want to achieve but i am very much a novice.

    any chance you can cast you eye over my code and set me straight?

    i have the caps working but not the small caps with the code.

    i can email everything over to you.

    cheers

    jason

    Comment by jason at 2:03 pm on August 1, 2010

  3. Hi Jason – are you getting the font replacement to work? What I’d probably do is try to get the small caps effect working without Cufon – just try and use the JavaScript to set the CSS classes on the first letter and set that class to something totally different. Once that’s working add back the Cufon part – hopefully that helps you narrow down the issue.

    Comment by Paul Reilly at 4:13 pm on August 2, 2010

  4. Is there a typo in the Cufon.replace(‘h1}); line?? Appears there should be a ‘ and not a }. Also, I can get the small caps effect working by itself, and I can get the cufon replacement to work by itself, but when used together it displays all the cufon span classes. Any suggestions???

    Comment by schef at 12:22 pm on August 16, 2010

  5. Right you are – I fixed that } typo.

    As for your issue – that hasn’t happend to me – I was assure you’re using the latest jQuery – and do the steps in the same order as in my post – run cufon, then insert the spans, then apply the style to the spans. Hope that helps.

    Comment by Paul Reilly at 2:36 pm on August 16, 2010

  6. FYI if yer having problems getting cufon to work on multiple identifiers within your html and it seems the script is replacing html everywhere you have an H3 or what ever … it is .. you need to make each call unique after fiddleing with it for a whiel i came up with a solution … take a look

        jQuery(document).ready(function($) {
    	Cufon.replace('#brand h1, #besocial h3, #widget-1 h3, #widget-2 h3, #widget-3 h3', { fontFamily: 'Eccentric Std' });
    	var social = $('#besocial h3').html();
    	var main = $('#brand h1').html();
    	var text1 = $('#widget-1 h3').html();
    	var text2 = $('#widget-2 h3').html();
    	var text3 = $('#widget-3 h3').html();		
    	
    	$('h1').html(main.replace(/\b([A-Za-z0-9])/g,'$1'));
    	$('#besocial h3').html(social.replace(/\b([A-Za-z0-9])/g,'$1'));
    	$('#widget-1 h3').html(text1.replace(/\b([A-Za-z0-9])/g,'$1'));	
    	$('#widget-2 h3').html(text2.replace(/\b([A-Za-z0-9])/g,'$1'));
    	$('#widget-3 h3').html(text3.replace(/\b([A-Za-z0-9])/g,'$1'));	
    	$('.homecaps').css('font-size',36);
        $('.caps').css('font-size',48);
    }); 
    

    Comment by Marc Juneau at 12:49 pm on September 28, 2010

  7. it seems to of cut off my html in the comment
    after each /g,'<span class="homecaps">$1</span>’));

    sp it should read

    $(‘#widget-3 h3′).html(text3.replace(/\b([A-Za-z0-9])/g,'<span class="homecaps">$1</span>’));

    Comment by Marc Juneau at 12:52 pm on September 28, 2010

  8. Thanks for this tip! Worked great. One thing I would mention: if you put the “Cufon replace” before the var text (et al), it will try and convert the cufon styling and you’ll end up with converted entities (e.g. all of the source code will show up for Cufon). Just put the Cufon call AFTER the text/replace calls and you’ll be good to go.

    Thanks for posting this!

    Comment by andrew at 10:20 pm on January 24, 2011

  9. Scratch that…was working great, but you can’t call the function with multiple uses on the page; e.g. if I have a selector ‘.module h2’ and I have multiple h2’s, EACH one gets replaced with the text…bummer!

    Comment by andrew at 10:30 pm on January 24, 2011

  10. I like this solution a little more. Just match it against whatever selectors you want and it will only add the large caps to characters which are actually capitalised.

    $(function($)
    {
    Cufon.replace(‘h1, h2, h3, h4, h5, h6, p, a, label’, {
    fontFamily: ‘Font Name’
    });
    $(‘h1, h2, h3, h4, h5, h6, p, a, label’).each(function()
    {
    var text = $(this).html();
    $(this).html(text.replace(/\b([A-Z]+)/g,’$1′));
    });
    var fontSize = parseInt($(‘.caps’).css(‘font-size’))
    $(‘.caps’).css(‘font-size’,fontSize*1.05);
    });

    Though this is just my preference.

    Comment by Charlie at 9:27 pm on January 28, 2011

  11. I wrote the following jQuery plugin based on the comments in this post:

    (function($){
    $.fn.extend({
    smallCaps: function(options) {
    var defaults = {multiplier: 1.2}
    var options = $.extend(defaults, options);
    return this.each(function() {
    var obj = $(this);
    $(obj).html($(obj).html().replace(/\b([A-Z])/g,’$1′));
    });
    }
    });
    })(jQuery);

    $(function(){
    $(‘h1’).smallCaps();
    Cufon.replace(‘h1′, {fontFamily:’Font Name’});
    });

    Comment by James Moberg at 2:45 pm on July 7, 2011

  12. This forum borked up the source code I posted, so I re-posted the jQuery plugin at PasteBin:
    http://pastebin.com/pxi1Kv5x

    Comment by James Moberg at 2:48 pm on July 7, 2011

  13. Hi there!

    This one could help me a lot!! Thanks for sharing these code snippet!
    But i still have one problem => german Umlaute (ö ä ü)

    When i use your unmodified code this is what i get for a word with an Umlaut:

    GeschäFtsleitung

    The Umlaut “ä” seems to be recognized as a blank/end of word and the following letter is rendered as capital.
    I tried to fix this by myself, but my regex-experience is not that good…do you know a way to make your code handle Umlaute?? Would be a great improvement for us poor german-speaking webdevelopers ;)

    Hope for an answer!
    greetings,
    Flo

    Comment by muetzenflo at 11:10 am on September 1, 2011

  14. @Flo – It sounds like you’re encountering a common problem with JavaScript regular expressions and international characters:

    http://stackoverflow.com/questions/5311618/javascript-regular-expression-problem-with-b-and-international-characters

    It seems to affect other languages, too. As a workaround, you could get a copy of an alternative JS regexp library called XRegExp from http://xregexp.com/ and its Unicode plug-in, then update the “text.replace()” section of the code with the equivalent XRegExp syntax. Hope this helps.

    Comment by Chris Dornfeld at 11:34 am on September 2, 2011

  15. Hi Chris!

    Sorry for the late reply; i had some other deadlines and some vacation. I didnt know about xregex and it looks quite powerful. I think this should do the trick, thanks for sharing your experience!!

    greetings,
    Flo

    Comment by Flo at 9:26 am on September 21, 2011

  16. My partner and I absolutely love your blog and find most of your post’s to be precisely what I’m looking for. Would you offer guest writers to write content for you personally? I wouldn’t mind composing a post or elaborating on a lot of the subjects you write regarding here. Again, awesome website!

    Comment by healthy weight lose at 2:41 pm on July 28, 2012

Comments are closed for this post.

TrackBack URI

Unitz LLC, 850 North Randolph St., Suite 103 - A38, Arlington, VA  22203 * Tel. 703-539-2542 Email us