Automatic pullquotes with JavaScript and CSS

As you may have noticed, there are now pullquotes in some articles on this site. I think they can be a nice design element and a good way of highlighting important phrases. As with most things there are several ways of creating pullquotes, the most straightforward being copying the text you want and paste it into a blockquote element. I didn’t want to do that for several reasons.

The main reason is the amount of work involved. I could go through my older articles to add pullquotes, but what if I should decide that I no longer want pullquotes? I’d have to go through every article again to remove the quotes. Lots of work. I wanted a way to add pullquotes without having to duplicate text in the markup, and came up with a JavaScript based technique.

Using JavaScript for this is fine with me since the pullquotes serve mostly as scannability aids and design elements. The text exists in the markup, so users with JavaScript off aren’t missing out on any actual content. If JavaScript is on but CSS is off, the pullquotes are still created but without any other styling than the browser’s default blockquote styling. That too is an acceptable fallback.

With the degradation discussion out of the way, it’s time to explain how the pullquotes are created. To turn a piece of text into a pullquote, all I need to do is wrap the text that will become a pullquote in a span element and give it the class name “pullquote”. An example:

  1. <p>To turn a piece of text into a pullquote, all I need to do is <span class="pullquote">wrap the text that will become a pullquote in a span element and give it the class name "pullquote"</span>.</p>

The JavaScript will turn that into this:

  1. <blockquote class="pullquote"><p>wrap the text that will become a pullquote in a span element and give it the class name "pullquote"</p></blockquote>
  2. <p>To turn a piece of text into a pullquote, all I need to do is <span class="pullquote">wrap the text that will become a pullquote in a span element and give it the class name "pullquote"</span>.</p>

Here’s the JavaScript, with explanatory comments (just copy and paste this into a file):

  1. var pullquote = {
  2. init : function() {
  3. // Check that the browser supports the methods used
  4. if (!document.getElementById || !document.createElement || !document.appendChild) return false;
  5. var oElement, oPullquote, oPullquoteP, oQuoteContent, i, j;
  6. // Find all span elements with a class name of pullquote
  7. var arrElements = document.getElementsByTagName('span');
  8. var oRegExp = new RegExp("(^|\\s)pullquote(\\s|$)");
  9. for (i = 0; i < arrElements.length; i++) {
  10. // Save the current element
  11. oElement = arrElements[i];
  12. if (oRegExp.test(oElement.className)) {
  13. // Create the blockquote and p elements
  14. oPullquote = document.createElement('blockquote');
  15. oPullquote.className = oElement.className;
  16. oPullquoteP = document.createElement('p');
  17. // Insert the pullquote text
  18. for(j = 0; j < oElement.childNodes.length; j++) {
  19. oPullquoteP.appendChild( oElement.childNodes[j].cloneNode(true) );
  20. }
  21. oPullquote.appendChild(oPullquoteP);
  22. // Insert the blockquote element before the span element's parent element
  23. oElement.parentNode.parentNode.insertBefore( oPullquote,oElement.parentNode );
  24. }
  25. }
  26. }
  27. };
  28. // addEvent function from http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html
  29. function addEvent(obj, type, fn) {
  30. if (obj.addEventListener)
  31. obj.addEventListener( type, fn, false );
  32. else if (obj.attachEvent)
  33. {
  34. obj["e"+type+fn] = fn;
  35. obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
  36. obj.attachEvent( "on"+type, obj[type+fn] );
  37. }
  38. }
  39. addEvent(window, 'load',pullquote.init);

If you are already using an addEvent() function, use that and remove the one that is included with this script.

Yes, I’m using innerHTML, but only because I couldn’t find a nice DOM based function that does the job of copying the contents of the pullquote span, including any child elements. Using cloneNode copies the span element as well, and I don’t want that. If anyone is aware of a DOM replacement for innerHTML that does what I want, please let me know. If not, maybe it’s about time for someone to create one.

Update (2006-09-19): The script now uses the DOM instead. I based my change on the snippets provided by several people (Dan, Lachlan, Rowan). The loop that is needed is much simpler than I thought it would be when I first created the script. I guess my brain was in its overcomplicating mode.

The script does make a couple of assumptions about the markup that you should be aware of. First, it inserts the blockquote element before the span element’s parent element without first checking what type of element it is. This will lead to invalid markup being created if you add a pullquote span inside an inline element or a list item, for example. Second, it uses document.createElement, which will not work in documents served as application/xhtml+xml. If you need it to work in that situation, Simon Willison describes a solution in Javascript, the DOM and application/xhtml.

With the necessary HTML in place, the pullquote needs a bit of styling. If you want to be able to decide on a quote-by-quote basis whether it should be floated left or right, you could add an extra class name. I decided to float the pullquotes left by default, and that any pullquotes that also have the class name “alt” should be floated right:

  1. blockquote.pullquote {
  2. float:left;
  3. width:10em;
  4. margin:0.25em 0.75em 0.25em 0;
  5. padding:0.5em;
  6. border:3px double #ccc;
  7. border-width:3px 0;
  8. color:#333;
  9. background:transparent;
  10. font:italic 1.3em/1.3 Georgia;
  11. }
  12. blockquote.alt {
  13. float:right;
  14. margin:0.25em 0 0.25em 0.75em;
  15. }
  16. .pullquote p {
  17. margin:0;
  18. text-align:center;
  19. }
  20. .pullquote p:first-letter {text-transform:uppercase}

And there you go. Automatic pullquotes with a minimum amount of extra markup.

Update (2006-10-21): There are at least two people who have created Wordpress plugins that use similar scripts. Viper007Bond’s plugin is described in Javascript Pullquotes and Stephen Rider’s in Wordpress Plugin: Javascript Pull-Quotes.

Posted on September 18, 2006 in CSS, JavaScript

Comments

  1. Nice. I tried a similar approach myself, but found that all too often I wanted the pull quote text to be slightly different from the text in the article. For example, where I may use a pronoun that makes sense in the context of the article, I needed to use the regular noun in the pullquote. Things like that. So I went to adding a “pull quote” field on my blog entry object in my database and entering the text there (which is then automatically wrapped in a blockquote and so forth).

    But your method is definitely simpler, so if it works for you, that’s awesome. Way to go.

  2. Wrapping the text I want processed between an html comment pair and using server side scripting to deal with it works for me.

    I’d noticed the pullquotes in your recent posts and wondered if they were a new feature of the software you use? Interesting to read it’s your own code and how your approach is totally different to mine :-)

  3. This seems like a nice DOM version of innerHTML:

    pullquote.CopyNode = function(aOriginalNode,aNewNode){
      for(var i=0;i<;aOriginalNode.childNodes.length;i++){
        aNewNode.appendChild(aOriginalNode.childNodes[i].cloneNode(true));
      }
    }
    
    pullquote.CopyNode(oElement,oPullquote);
    
  4. It’s a shame you’re using innerHTML just because you can’t find the DOM equivelent. I don’t mean to start up a innerHTML vs DOM discussion here, but if it’s there and it’s quicker (and fully supported) why not take advantage of it?

  5. I found it a bit slow to appear - presumably the fetching of the js file was delayed for some reason. I spent some seconds thinking “why doesn’t he show an example?!” until “Using Javascript is fine for me” popped up as a pullquote.

  6. September 18, 2006 by Roger Johansson (Author comment)

    Dan: Thanks, I’ll try that.

    Sam: I did, didn’t I? ;-) I would rather use DOM methods though.

    Mark: That’s caused by the gravatars. The script doesn’t kick in until they have all loaded, and as you noticed that takes far too long. I don’t think the gravatars will be staying unless there is a way to speed up loading.

  7. Roger,

    A couple of things. Firstly, you might want to look at triggering earlier than on the load event, if it’s causing problems to wait for images to load. See Dean’s http://dean.edwards.name/weblog/2005/09/busted/ for more.

    Secondly, \b in regexps means “a word break”, so /\bpullquote\b/ is a slightly cleaner regexp than the one you have.

    Nice script, though. I may steal it ;)

  8. September 19, 2006 by Roger Johansson (Author comment)

    Stuart: I’ll have a look at Dean’s article. For now I’ve disabled the gravatars (well, set them all to display the default image).

    About the regexp, I used to use \b for things like this but ran into problems with class names containing hyphens (since hyphen is a word boundary).

    Go ahead and steal the script if you find it useful ;-).

  9. Ah, hyphens. I avoid that by never, ever, ever, ever using a hyphen in a classname, because I can never remember whether they’re valid or not ;) I was a bit surprised that you weren’t using \b, I admit.

  10. The generic way to replicate this use of innerHTML using DOM2 methods is to create a DocumentFragment and then clone each of the child nodes from the element and append them to the fragment. You can then do whatever you like with that new fragment.

  11. Great to see you explaining how to do this! Always meant to do that myself when Digital Web redesigned in 2004, as we did a very similar thing.

    Like Dan suggested, we used cloneNode instead of innerHTML and it’s worked quite well — you can view how we did it in the simple little script

    (An example implementation can be found in articles like “Scope in JavaScript”)

    Another difference is a bit of a design one: we have a fixed placement for the pullquote (before the fifth paragraph). This allows it to appear in a consistent location, and also prevents the pullquote text from being beside its source (which can seem repetitive).

  12. Here’s a working, general purpose function for cloning the child nodes of an element.

    Node.prototype.cloneChildNodes = function() {
      var df = document.createDocumentFragment();
      for (var i = 0; i < this.childNodes.length; i++) {
        df.appendChild(this.childNodes[i].cloneNode(true));
      }
      return df;
    }
    

    Of course, that won’t work in IE (or any other UA that doesn’t properly support DOM2), but it might be possible to work around that somehow.

    For the load time problem, you’d need to capture the DOMContentLoaded event instead. That also isn’t supported in IE, but IE supports the defer attribute on script elements instead.

  13. Nice! Really nice! One thought, why not use PHPs DOM extension instead? It would remove any incompatibilities.

    As for cloning an elements children, this is your best bet, and it should work in IE too: http://pixelcarnage.net/Garbage/copyChildren.html

    Also, just look at this add, which was below the article: http://pixelcarnage.net/Garbage/WeXHTML.png

  14. Very nice, Roger!

    I’m wondering by the way, how the different ‘cloneChildren’ methods presented in the comments fit into Quirksmode.org’s benchmark tables. It’s worth some testing, because I too, sometimes use innerHTML, for practically the same reason you did.

  15. Or you could try to load the gravatars with javascript … just a thought. :)

  16. September 19, 2006 by Gerben

    I found just a small error in the example code. You forgot the class-attribute that is also coppied by the JS:

    <blockquote **class="pullquote"**><p>
    

    further not only document.createElement, but also .innerHTML will not work in documents served as application/xhtml+xml

    If you just want to extract the plain text use something like this:

    function extractText(node) {
        if ( node.nodeType == 3 ) //TEXT_NODE
            return node.nodeValue;
    
        if ( node.nodeType == 8 ) // COMMENT_NODE
            return '';
    
        var text = '';    
        if ( node.hasChildNodes() ) {
            for ( var i=0; i<node.childNodes.length; i++ )
                text += extractText(node.childNodes[i]);
        }
        return text;
    }
    
    //usage in your code:
    oQuoteContent = extractText(oElement);
    
  17. I don’t mean to blashpeme, but why not just use a javascript library to help save code/time?

    Using jQuery: $(document).ready(function() { $('.pullquote').each(function() { $(this.parentNode).before('<blockquote class="pullquote"><p>' + $(this).html() + <\/p><\/blockquote>'); }); });

    It’s worked for me in the past, and it truly does save you a ton of time.

  18. Hey, where’d my Markdown go? :)

  19. Same thing using lowpro:

    var pullquotes = Behavior.create({ initialize : function() { var quote = $blockquote({ class : ‘pullquote’ }, $p(this.element.innerHTML) ); this.element.parentNode.previousElement().appendChild(quote); } });

    Event.addBehavior({ ‘span.pullquote’ : pullquotes });

  20. @Michael and Andri:

    Using a library might save time, but definitely not code.

    Methods like “addBehavior()”, “$()”, “each()” or “Behavior.create()” all have to be included in your file and since you didn’t write them yourself, you won’t know how many lines of (redundant) code you’re actually using till you check :)

  21. September 19, 2006 by Roger Johansson (Author comment)

    Craig: I also considered placing the pullquot in other locations but ended up doing it this way for now.

    Lachlan, Rowan: Thanks for those snippets. I have updated the script to use the DOM now. I made it overly complicated when I was creating the script so I missed the simple solution.

    Mats: Hmm. I’ll take a look at loading the Gravatars with JavaScript. For now I’m leaving them disabled since the speed boost when I turned them off was significant.

    Gerben: Thanks, I’ve fixed that error. I considered just extracting the plain text but thought it would be nice if any emphasis etc was also copied to the pullquote.

    Michael, Andri: Sure I could have used a JavaScript library, but I don’t see the benefit for something as simple as this. And I like to know what my scripts do, so I tend to stay away from libraries.

  22. This scipt is exactly what I was looking for.

    Could you give an example of using the alt class? It sounds like you are saying to do something like the following:

    my pullqoute text is here.

    Is that valid? I tried it anyways and it isn’t working… so what’s the answer?

  23. I’m not especially good at javascript… could you provide a working demo like you did with “CSS Teaser Box” and the like?

    Thank you very much! I appreciate it!

  24. When I try creating more than one pullquote on a page the script works on the first instance but completely ignores the second.

    Example: http://whitehorsemedia.com/articles/artDetails.cfm?artID=76

  25. Nice, although I may be the only one who thinks pullquotes should be marked up as HTML…

    I say this because when reading or scanning a page (whether it’s web or print), my eye is usually drawn to pullquotes first. I get the summary of what the text is about, or a highlight of the most interesting parts of the text, then I read the article.

    So it seems to make sense that you would take the same treatment in the HTML. I love the no hassle way of getting about it all; I just don’t think it’s fair to use pullquotes only as a visual feature and not make them accessible to others.

    P.S. I swear I’m not a semantic purist or anything. It’s just my two cents. ;)

  26. September 20, 2006 by Roger Johansson (Author comment)

    Alex: Just look at this page - it contains two pullquotes :-).

    Aaron: Yes, I just noticed that too. It seems that the DOM method for copying the contents does not work properly after all. I reverted to innerHTML until I have time to find a DOM solution that works properly.

    Richard: You do have a point, but I think this is useful in cases where marking up pullquotes in the HTML is unwanted or impractical.

  27. I really hope someone would be able to figure the DOM replace for the innerHTML. I think this is just great especially for myself who designs more than understands the logic in programming. :)

    cheers.

  28. September 21, 2006 by Roger Johansson (Author comment)

    Ok, the DOM method works. I just made a silly mistake in the loop, using the same counter variable as in the outer loop. *slaps forehead*

  29. Roger, I’m guessing you don’t need this check anymore, correct?

    Line 4:

    || typeof document.getElementsByTagName("head")[0].innerHTML == "undefined"
    
  30. That’s a beautiful concept! One more reason to love scripting on the client side.

  31. September 21, 2006 by Roger Johansson (Author comment)

    Richard: That is correct. Thanks for reminding me!

    Dr Nic: Thanks :-).

  32. will this work on a blogger blog?

  33. This is a bit nit-picky, but… the “var j” declaration is contained within another for loop, which is redeclaring the same variable over and over (does not adhere to strict JavaScript standards).

    It would be best if the logic were contained in another function (which incidentally would have avoided the “same counter variable” issue ;-) or just declaring the variable once, but earlier in the init function.

  34. September 21, 2006 by Roger Johansson (Author comment)

    Chaim: It shoulöd, yes. I’m not familiar enough with Blogger to tell you how to apply it though.

    Dan: No problem - relevant nitpicking is good, and I should have seen that myself :-). I moved the variable declarations for both loops to line 5.

  35. I tried to improve this implementation by making a pair of changes:

    Article and example

    It’s in catalan. These are the changes in english:

    1. The code is more semantic. It uses strong/em instead of span.

    2. You can highlight the pullquote source by “hovering” on pullquote. It helps a lot when you are attracted by the pullquote and you want to read its continuation.

  36. This is great. I was thinking I like the idea of pullquotes and had them on my blog at one time, but typing out spans/blockquotes with the content again was tedious.

    I’m working on another blog and this will certainly be useful. :)

    Thanks for sharing.

  37. September 25, 2006 by Gordon

    New to this, so, where do I put the js file and how is it called from within the html ?

    Any help would be much appreciated.

  38. September 25, 2006 by Gordon

    Forget my previous post. Figured it out.

    Great stuff !

  39. There is nothing wrong with document.createElement() using in XHTML documents served as application/xhtml+xml. Only document.write() does not work.

  40. September 25, 2006 by Roger Johansson (Author comment)

    Francesc: I considered using em or strong, but decided that in most cases I do not want the text used for the pullquote to be emphasised. Changing the script to work with any element might not be a bad idea though.

    The highlighting you added looks like it could be useful. Nice!

    Jonathan: As far as I know using createElement() with XML is deprecated and does not work in all browsers that support application/xhtml+xml. I could be wrong though, so if you have a link to a document that clarifies this, please post it.

  41. Amazing.

    ..primarily because I’ve been learning DOM scripting recently, and had plans to do exactly this, using exactly the same method — putting text in a span and having javascript turn that into a pullquote. I was even thinking I would end up using innerhtml because I couldn’t figure how to do that easily with the DOM. I laughed when I read that part… :)

    At any rate, this is very, very cool. I’ll use this for sure, and if I tinker any improvements in, I’ll send them your way. (My first idea is to take un-capitalized first letters and capitalize them inside brackets, so that quotes starting in the middle of a sentence get [C]apitalized properly. A variation of that could add elipses to beginning or end as appropriate if the quote is not a complete sentence.

    Jeff Harrell, through whom I found this page, says he wouldn’t use this because his pull quotes are frequently somewhat different than the exact quote. I’m sure this could be worked out as well by allowing an optionsl “quote text” attribute in the Span tag. Maybe an optional alt? I’d have to dig and figure out which attributes are legal within a span and what might be appropriate to use.

    Like this: <span class=”pullquote” alt=”This is a pull quote.”>This, along with an extra long wordy subclause, is a pull quote.</span>

    Of course, that doesn’t validate, dang it. Thus the need for a bit of experimenting…

  42. September 25, 2006 by Roger Johansson (Author comment)

    Stephen: Hehe, well when I found out how to do it without innerHTML it was a lot easier than I thought it would be.

    I use CSS to take care of capitalisation… err I see now that I forgot to add that rule to the CSS in the article. I’ll add that right away. Still, there are probably neat ways of doing that in the script.

    Using an attribute to hold the pullquote text… hmm. Maybe. The title attribute would be the most appropriate one to use in that case.

  43. I agree on appropriateness, but I hate the idea of the text showing as a “tiptext” if the reader mouses over the text, thus my desire for an alternate.

    Off the cuff, the only validating alternate I can come up with would be to put in a “fake” javascript in an onclick, like this:

    onclick=”dummy(‘This is a pull quote.’)”

    The page would have to actually have a does-nothing “dummy()” function, just in case somebody clicks on your span for some reason, and you would use the pullquote script to parse that bit of text out of the onclick attribute.

    A bit goofy, but the only way I can think of that a) validates, and b) doesn’t actually change the behavior or appearance of the text in the span. (It might also require an additional line or two of CSS to keep the pointer from changing when moused over)

    I seem to come across a lot of cases where it would be nice to have some sort of “extra information” attribute for scripting purposes. Since in this case it’s for use with javascript anyway, maybe putting it in a javascript attribute is not so inappropriate after all….

  44. For excluding sections of a pullquote, why not this:

    <p>This is a paragraph. <span class="pullquote">This<del>, but not this,</del> is a pullquote.</span></p>

    I’d say that works. Of course, you’d need a CSS rule to make sure .pullquote del {} looked normal and not, well, deleted. If you’re against using <del> for excluded text, why not just throw in more spans?

    <p>This is a paragraph. <span class="pullquote">This<span class="exclude">, but not this,</span> is a pullquote.</span></p>

    Then, of course, add some magic to the script to ignore content in those tags (check tagName or className in your makeshift .innerHTML routine).

  45. I may be missing the point here - and excuse me if I am. But why use all that javascript? If you’re marking up your content with a then why not do all the hard work with CSS which’ll load faster and be easier to change later on?

  46. September 27, 2006 by Roger Johansson (Author comment)

    Stephen: I guess that could do it, but it would also increase the amount of work required to add a pullquote.

    Aaron: Using del is not an option since that would mess with any user agents that actually use the del element. Not to mention what it would look like with CSS off.

    Using extra spans… yeah maybe. But a lot more work, and what if you want to add a few words. I think if you want pullquotes that don’t exist in the text you might as well add them to the markup.

    Katy: Not sure how you would let CSS alone do this. Sure, you could float or position the span, but that would also remove it from the text. Or am I misunderstanding you?

  47. Ah, I see - silly me! I didn’t realise you weren’t referencing the text within the PullQuote twice and instead stripping out the content between the span tags - that’ll teach me to look at the source code!

  48. Nice one!

    (And I think I’ll start using that addEvent script too… ;-)

  49. I LOVE IT :) just added it to my blog.

  50. Ok so maybe it didn’t work like i thought. I tried to add it to my wp blog. And it’s not repeating the text. I added the js file to 3 different areas trying to get it to work. the js file dir, my theme dir, and the public_html dir

  51. Heather: it works just fine in WordPress, you just have to edit your theme, call the CSS and Javscript files correctly, etc. ;)

    If that sounds like too much work to you (or you don’t know how to do it), I’ve written a plugin though that makes it easy to integrate this into WordPress blogs. Just upload and activate. :)

  52. Yea I got your great little plugin… thanks i think i just wasn’t thinking straight :)

  53. Hi Roger, a quick Google search for the term “pullquote” brought this up. Looks like it’s been done before with a very similar technique. Still, nice work.

  54. Nice article. This is a possible alternative to innerHTML And this is another scripted solution to create pullquotes

  55. Thanks a lot for this script. It’s a breeze to implement and it works wonderfully. Unobtrusive, that is. Cheers. ;-)

  56. This is incredibly useful. I’m putting it on my system right away. Thanks a bunch!

  57. This is very usefull!

    Thanks for sharing, Roger!

  58. …of course you could’ve just improved upon this script I did 3 years ago. ;)

    EM to BLOCKQUOTE

  59. Roger, I have used this on a site I helped build recently. Not verbatim, but in principle. As a self contained piece it is built very well. Since you are using object literal notation, you have added the ‘addEvent’ method inside of the pullquote object. For those who have other javascript functions to use on their site, it would be more beneficial for them to add the script to their previous library and use a consistent ‘addEvent’ method to call their methods.

    So, maybe a slight suggestion of moving the addEvent method outside of the pullquote object as it shouldn’t really be bound to that object (even for a standalone script).

    I also use other scripts for opening new windows and the like, and they all use a consistent addEvent method to invoke.

    Thoughts? Maybe I am missing something (I am no javascript expert) as to why it was built this way?

    I really love the scripts. Works like a charm!

  60. November 7, 2006 by Roger Johansson (Author comment)

    Nate: I put the addEvent() function inside the pullquote object for convenience and to make it fully self-contained, but I see your point. I’ll move it and make a note that people can remove it completely if they are using another addEvent() function.

  61. I made a more semantic version of this idea. Does not use Javascript - a pure CSS/(X)HTML implementation.

    http://binnyva. blogspot .com/2006/09/sementic-pullquotes.html

  62. November 8, 2006 by Roger Johansson (Author comment)

    Binny: My article explains why I didn’t want to use the approach you describe, and why I do not see a problem with using JavaScript for this. The markup you use (blockquote + p) is exactly what this script creates. As for SEO, some argue that repeating the text could work against you.

  63. Heres my K-I-S-S take on a purely (X)HTML, CSS, semantic, and XHTML 1.0 Strict Validating way to create pullquotes.

    http://www. askapache .com/2006/css/pullquotes-using-css-and_or-javascript.html

    Great article and I really like the look of your end result, and the change from the outdated innerHTML method. When you can eliminate js, doit. NOTE: Im not anti-js, just a minimalist.

  64. Talking about webstandards and validity of XHTML, etc., on these blogs I always see (whether in the article or in the comments) something like this: “Using JavaScript for this is fine to me” or “Interesting to read it’s your own code and how your approach is totally different to mine”

    Sorry, but you can say “different from” or “different than” but NEVER “different to.” Please use valid Standards Compliant English!! And you can’t say something “is fine to me” but have to say either that it “seems fine to me” or “is fine with me.” That way you can master Forward Compatibility and Backwards Compatibility at once. That is, after all, actually more important than (or should I say to) Standards Compliant XHTML.

  65. November 17, 2006 by Roger Johansson (Author comment)

    jk: Thanks for pointing out those grammar issues. English is not my native language, so mistakes like that are bound to happen from time to time.

  66. Hi, I was working on something similar back in ‘04. You might find my trick of using META tags to tack on an attribution line of interest. Feel free to use it…

  67. Thanks for the tip. A great quick and simple solution.

  68. Just a thought: we could set the title attribute to the alternate quote, then tell the script to display the alternate quote if the title is set, couldn’t we? Or would that be considered “duplicate content” as well?

  69. January 29, 2007 by Roger Johansson (Author comment)

    Seyora: Interesting idea. It would work, but might look confusing to someone hovering their mouse over the span element. And you’d still have to manually enter the pullquote text a second time. If the alternate quote differs a lot from the span element’s content, the question is if perhaps seeing that text should not only be reserved for users with JavaScript support, i.e. perhaps it has become “real” content.

  70. In answer to the previous question about Blogger, I just integrated the pullquote code to my blogger blog with little problem. The steps are as you would imagine. Include a link to js source file in the HEAD section of the blogger template. You should reference the location of the .js file using its full URL so it will still work if someone views and individual post. Then add the necessary style elements to style section in the header of your template. Add the new span’s to your blog and republish. Works a treat, thanks Roger.

  71. Thank you for this side

  72. Interesting approaches. :)

    Here’s what I thought of last summer, and just got around to posting: CSS Pull Quotes

    It’s a bit different in approach to the other ones I’ve seen — it uses the CSS :before pseudo-element to generate the content of the pull quote.

  73. Roger, thanks for the great resource and keep up the excellent work.

    We recently implemented pull-quotes on the Gustavus Adolphus College website based on your code here. Our pull-quote solution adds a couple of features and uses Ben Nolan’s Behaviour.

    Perhaps you and your readers will find it useful.

  74. I’m not a big fan of javascrip but now I’m more convinced that I should use it. Thanks for the great resource.

  75. Roger and Seyora — Look at my WordPress Plugin (you link it at the end of your post) for an alternate text solution. (oh, and thanks for the link! :-) )

    I put the alt text in an HTML comment within the span.

    Doesn’t work in Safari, because of a bug in that browser’s JavaScript implementation, but otherwise works great — and you can do it so the pull-quote simply doesn’t appear in Safari.

    Here’s my plugin again: http://striderweb.com/nerdaphernalia/features/wp-javascript-pull-quotes/

Comments are disabled for this post (read why), but if you have spotted an error or have additional info that you think should be in this post, feel free to contact me.