Styling the blockquote element
I wanted to add opening and closing quotes to the blockquote
element on this site using stylesheets, where: (a) n paragraphs would be enclosed by a single pair, (b) the closing mark immediately follows the last word of the quotation, and (c) the marks use a different size, colour, typeface and baseline position than the body text:
Examples of fluid block quotation marks
Here is some sample markup:
<blockquote>
<p>This paragraph is the first child of the blockquote.</p>
<p>This paragraph is the last child of the blockquote.</p>
</blockquote>
To get the result I wanted I had to rely on some CSS properties that aren’t (yet?) supported in all browsers. Still, the end result works in recent versions of Camino, Firefox, Safari, Opera (almost), OmniWeb (almost), and IE 6 and 7 using Dean Edwards’ IE7.js, if scripting is enabled. Here’s the relevant CSS:
blockquote > *:first-child {
text-indent:-14px;
}
blockquote > *:first-child:before {
background:url(images/left-quote.png) no-repeat 100% 30%;
content:"\00A0";
padding:2em;
padding-left:0;
}
blockquote > *:last-child:after {
background:url(images/right-quote.png) no-repeat 10% 70%;
content:"\00A0";
padding:2em;
}
* html blockquote * {text-indent:-6px;} /* fix IE6 */
The two larger rules target the area immediately before the first child element (a p
in the example above) of the blockquote, and immediately after the last child element (also a p
), respectively. This method uses images of quotation marks to render the opening and closing symbols, and the images are applied as backgrounds to invisible generated content. Background image positioning made it easy to fine-tune the location of the marks.
It turns out that all of the browsers I tested support background images on generated content, but the catch is that Safari and OmniWeb don’t seem to treat a regular space character (either Unicode character 0020 or a literal space) as, well, content. No content, no background image. The trick turned out to be to use a more obscure non-visible character, in this case the “no-break space” (00A0).
Finally, the topmost rule pulls the first line to the left, and the last rule is a kludge for IE6 that overrides this behaviour. When the first line has a negative indent IE6 cuts off the overhanging part of the image. (Writing that out I just realised that I didn’t try overflow:visible
.)
I did wonder if the same effect could be achieved using quotes as generated content and styling those, instead of invisible content with background images. I hit a wall on the first attempt, but I came really close in the Gecko browsers and Safari with this alternative:
blockquote > *:first-child {
text-indent:-16px;
}
blockquote > *:first-child:before {
color:#CCC;
content:"\201C";
font:italic bold 4em Garamond,Times,"Times New Roman",serif;
line-height:1px;
padding-right:.2em;
vertical-align:-1500%;
}
blockquote > *:last-child:after {
color:#CCC;
content:"\201D";
font:italic bold 4em Garamond,Times,"Times New Roman",serif;
line-height:1px;
margin-left:-.05em;
vertical-align:-2700%;
}
* html blockquote * {text-indent:-6px;} /* fix IE6 */
The main problem was that in pulling the opening quote down as low as it is I couldn’t prevent a larger line height on the first line in Opera. The bottom margin of the blockquote was also a bit taller than I wanted in several browsers because of a similar effect with the closing quote. I started reading the CSS spec on Line height calculations, but it got late and my eyes were stinging and… I’ll get back to it.
Lastly, I said “almost” for Opera and OmniWeb because their current versions don’t support last-child
, so there’s no closing quote for these. Opera 9.5 will fix this; not sure about OmniWeb. But if you use either of these now you should see the one-quote effect, and I’m happy to say I’m in good company there.
Update: I changed Zero to One-Eighty’s blockquote style in December, 2008, but the screenshot above shows what they looked like when I wrote this post.