Block quotes are great. I don’t mean they’re great for indenting content – that would be an abuse of the browser’s default styling. I mean they’re great for semantically marking up a chunk of text that is being quoted verbatim. They’re especially useful in blog posts.
<blockquote>
<p>Progressive Enhancement, as a label for a strategy for Web design,
was coined by Steven Champeon in a series of articles and presentations
for Webmonkey and the SxSW Interactive conference.</p>
</blockquote>
Notice that you can’t just put the quoted text directly between the <blockquote> tags. In order for your markup to be valid, block quotes may only contain block-level elements such as paragraphs.
There is an optional cite attribute that you can place in the opening <blockquote> tag. This should contain a URL containing the original text you are quoting:
<blockquote cite="http://en.wikipedia.org/wiki/Progressive_Enhancement">
<p>Progressive Enhancement, as a label for a strategy for Web design,
was coined by Steven Champeon in a series of articles and presentations
for Webmonkey and the SxSW Interactive conference.</p>
</blockquote>
Great! Except… the default behavior in most browsers is to completely ignore the cite attribute. Even though it contains important and useful information, the URL in the cite attribute is hidden.
You could simply duplicate the information with a hyperlink at the end of the quoted text:
<blockquote cite="http://en.wikipedia.org/wiki/Progressive_Enhancement">
<p>Progressive Enhancement, as a label for a strategy for Web design,
was coined by Steven Champeon in a series of articles and presentations
for Webmonkey and the SxSW Interactive conference.</p>
<p class="attribution">
<a href="http://en.wikipedia.org/wiki/Progressive_Enhancement">source</a>
</p>
</blockquote>
But somehow it feels wrong to have to write out the same URL twice every time you want to quote something. It could also get very tedious if you have a lot of quotes.
Well, “tedious” is no problem to a programming language, so why not use a sprinkling of DOM Scripting? Here’s a plan for generating an attribution link for every block quote with a cite attribute:
- Write a function called prepareBlockquotes.
- Begin by making sure the browser understands the methods you will be using.
- Get all the
blockquoteelements in the document. - Start looping through each one.
- Get the value of the
citeattribute. - If the value is empty, continue on to the next iteration of the loop.
- Create a paragraph.
- Create a link.
- Give the paragraph a class of “attribution”.
- Give the link an
hrefattribute with the value from theciteattribute. - Place the text “source” inside the link.
- Place the link inside the paragraph.
- Place the paragraph inside the block quote.
- Close the for loop.
- Close the function.
Here’s how that translates to JavaScript:
function prepareBlockquotes() {
if (!document.getElementsByTagName || !document.createElement || !document.appendChild) return;
var quotes = document.getElementsByTagName("blockquote");
for (var i=0; i<quotes.length; i++) {
var source = quotes[i].getAttribute("cite");
if (!source) continue;
var para = document.createElement("p");
var link = document.createElement("a");
para.className = "attribution";
link.setAttribute("href",source);
link.appendChild(document.createTextNode("source"));
para.appendChild(link);
quotes[i].appendChild(para);
}
}
Now all you need to do is trigger that function when the document has loaded:
window.onload = prepareBlockquotes;
Better yet, use Simon Willison’s handy addLoadEvent function to queue this function up with any others you might want to execute when the page loads.
That’s it. All you need to do is save this function in a JavaScript file and reference that file from the head of your document using <script> tags.
You can style the attribution link using CSS. It might look good aligned to the right with a smaller font size.
If you’re looking for something to do to keep you busy this Christmas, I’m sure that this function could be greatly improved. Here are a few ideas to get you started:
- Should the text inside the generated link be the URL itself?
- If the block quote has a
titleattribute, how would you take its value and use it as the text inside the generated link? - Should the attribution paragraph be placed outside the block quote? If so, how would you that (remember, there is an
insertBeforemethod but noinsertAfter)? - Can you think of other instances of useful information that’s locked away inside attributes? Access keys? Abbreviations?
About the author
Jeremy Keith is an Irish web developer living in Brighton, England where he works with Clearleft. He is joint leader of the WaSP DOM Scripting Task Force and he has written a book about DOM Scripting. He likes music, food, and liquid layouts. All he wants for Christmas is universal support for max-width.


Comments
05/12/2005
Is the cite attribute appropriate to use as a semantic hook for the “posted by…” footer often following a comment on a blog? This page’s example (as well as all others I’ve seen) use it to reference text quoted from an external page, but it always bugs me that I’ve not semantically linked the poster’s name with what they’ve said on my site’s coments… Any thoughts?
05/12/2005
Well, it looks a lot like Dunstan Orchard experiments with blockquotes but still useful ;-)
05/12/2005
JB: Maybe add a
titleattribute to theblockquotetag?http://learningforlife.fsu.edu/webmaster/references/xhtml/tags/text/blockquote.cfm#attributes
05/12/2005
OT, but the tab order down here is weird.
To the point. As for the third question (“how would I do that?”):
quote.nextSibling ? quote.nextSibling.insertBefore(cite) : quote.parentNode.appendChild(cite);
To this date, I just use CSS2 generated content for displaying the value of the cite attribute. I don’t make links out of it, partly because on the site where I do this I try to avoid JavaScript even when it’d enhance usability (such as the ability to click or at list copy the link in Mozilla), partly because it’s not always a link – I use the cite attribute for whatever source attribution fits.
05/12/2005
What a great idea! I’ve been using blockquotes on a fair few of my latest projects and it always seemed strange that the browser did nothing with the cite property.
BTW, wouldn’t the text in the cite link be better presented with a name or title for the source, for example, “Source: Progressive Enhancement – Wikipedia, the free encyclopedia”?
05/12/2005
CornedBee: You’re almost there, but the syntax for insertBefore is actually more complex than that (unnecessarily so in my opinion). But your thinking is spot on: use either insertBefore (if the quote has a nextSibling) or appendChild (if the quote is the lastChild).
Si: Yes, a more descriptive link text would be good. That was why I suggested reusing a quote’s title attribute, if one exists.
05/12/2005
I always refused to search for the meaning of blockquote, but today I’ve learned it unintentionaly. Thank you for this explanation!
05/12/2005
What about user agents that don’t support JavaScript? (Oh, come on, you knew someone was going to ask.)
05/12/2005
Kerri – there’s no problem if the UA doesn’t support JavaScript, or if JavaScript is turned off. The
blockquoteis still shown as normal, and the source information is still there in theciteattribute.The whole point of unobtrusive scripting techniques is that if there’s no scripting support available the user still has a fully functional page with all the information available to them. They just don’t get any little extras.
05/12/2005
I see what you mean, CornedBee, about the tabindex being wrong, it tabs from the label (http://) to the “back to home page link” in the header.
Hmm, I wonder how much of the content which I brough in book-form will appear for free (so soon) after it was published?
The third example which uses class=”attribution”, should be using the cite ELEMENT, and is exactly how I markup my blockquotes already. It might be tedious (not really) to add it manually, but I think it’s important information for the user, regardless of JavaScript. I see a blockquote in an interesting article, I might want to read that site or article.
05/12/2005
Slightly OT but in your third code block, you use < p class="attribution" > ... < /p > but shouldn’t you use the < cite > tag?
Very cool script, thanks.
05/12/2005
Wild idea (well maybe not that wild), but what about turning this into a Greasemonkey script? It is, after all, an attempt to alter the default UI that your browser provides, isn’t it? Hence, a developer shouldn’t necessarily have to account for such preferences. Additionally, there are no doubt a number of sites who may prefer not to display the source (for whatever reason), and a Greasemonkey script would make this preference available to the viewer. Just a thought.
Great article, though, Jeremy. Well done.
05/12/2005
Aww yea. Well written in Jeremy fashion. addLoadEvent prevails, and we’ve got a handy new function to handle our blockquotes.
This is great man. Always lookin’ for ways to help us become lazier. I love it.
05/12/2005
That´s great, except for the fact that it´s totally insane to have to script all kinds of workarounds for shitty browsers to even use correct markup, im seriously thinking about going back to tables
05/12/2005
This is useful, although far from new for anyone who’s been reading about unobtrusive Javascript techniques. Simon Willison published an article about this on Sitepoint two years ago this month.
—Scott05/12/2005
Jules: You’re quite right. The cite element would be perfect in this context. cite contains a citation or a reference to other sources
Jonathon: Turning this into a greasemonkey script sounds like a great idea! Actually, it probably wouldn’t be that hard to turn into a regular bookmarklet so even non-Firefox uses could enjoy it.
David: I have no idea what on earth you are getting at. What have tables got to do with anything in this example?!
Scott: I never claimed this was anything new. Here’s a quote for you to attribute: There is nothing new under the sun. ;-)
06/12/2005
> It might be tedious (not really) to add it manually
Phil Ringnalda calls that markupsturbation. I thought it was appropriate, anyway.
06/12/2005
Jeremy Keith: The
citeelement is not for quotes. ;-)06/12/2005
Jeremy, this is the kind of small, useful enhancement for which I love JavaScript and the DOM. In response to a couple of your points:
“Should the text inside the generated link be the URL itself?”
“If the block quote has a title attribute, how would you take its value and use it as the text inside the generated link?”
Using either the URL or the value of a title attribute would be better. Imagine a page with many blockquote elements, each with their own cite attribute citing a different source: then there would be many instances where the same link text (“source” in your example) points to different URLs. This would be bad from an accessibility point of view: think how the Links List would sound in a screen reader (“Source”, “Source”, “Source”, “Source”... with no context).
“Should the attribution paragraph be placed outside the block quote?”
It would be better if it were outside. First, because the attribution is not part of the quotation. Second, in a Note following section 9.2.2, the HTML 4.01 specification says that user agents should not insert quotation marks in the default style for the blockquote element. However, it also recommends that “style sheet implementations provide a mechanism for inserting quotation marks before and after a quotation delimited by BLOCKQUOTE”. If such an implementation were available and used, then the attribution paragraph would appear before the closing quotation mark, which would look wrong presentationally in addition to being wrong semantically.
CornedBee: I understand your reasoning in using the cite attribute for whatever source attribution fits, even when it is not a link. Indeed, it would seem to me more sensible that the cite attribute could be used that way. However, HTML 4.01 at section 9.2.2 states specifically that the value of the cite attribute is a URI—so technically, anything that is not a URI is not a valid value for cite.
07/12/2005
Why use an “attribution” paragraph when you can use an ADDRESS element?
09/12/2005
Nice one Jeremy.
There’s also a fun way to do it using generated content in CSS. True, you can’t link it, it is unselectable and it (say it with me now) doesn’t work in IE, but it requires no JS. For example, check out these blockquotes (about 2/3 the way down the page).
10/12/2005
this technique improve SEO ?
see ya !
11/12/2005
William,
This technique does not produce better or worse SEO. It’s a usability and possible accessibility enhancement.
14/12/2005
This will work:
quote.insertBefore(cite, quote.nextSibling);http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-952280727
Specifically: If refChild is null, insert newChild at the end of the list of children. So insertBefore works like appendChild when the second argument is null. Very useful :)
14/12/2005
oops, make that: quote.parentNode.insertBefore(cite, quote.nextSibling);
16/12/2005
Jules: While yes, he should use the cite tag instead of using the class method, cite is not a block level element, so he’ll have to create the link, insert that into a cite tag and then insert that into a paragraph tag.
27/12/2005
Well Done Jeremy Again! Keep churning it out regardless of were it comes from. Love the book by the way.
Commenting is closed for this article.