DOM Scripting Your Way to Better Blockquotes
This article first appeared in 24 Ways, the online advent calendar for geeks.
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
blockquote
elements in the document. - Start looping through each one.
- Get the value of the
cite
attribute. - 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
href
attribute with the value from thecite
attribute. - 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.>
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
title
attribute, 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
insertBefore
method but noinsertAfter
)? - Can you think of other instances of useful information that’s locked away inside attributes? Access keys? Abbreviations?