CSS quotes and the content property

If there’s one thing I enjoy more than learning new stuff, it is learning new stuff about something that I thought I had boxed off already. The CSS2 ‘quotes’ property pretty much fits that bill.

Here’s the rub if (like me) this is a property that you’re unfamiliar with:

Major browsers will prepend and append quotation marks to the `<q>` element via the CSS ::before and ::after pseudo-elements. This is pre-programmed into the user-agent style sheet, and a quick inspection via Firebug or whichever dev tools you prefer will reveal the following…

[css]
q::before {
content:open-quote;
}
q::after {
content:close-quote;
}
[/css]

I frequently use the ::before and ::after pseudo-elements to help keep my HTML light when marking up some of the more elaborate designs that are passed my way, normally using ASCII or text strings in the content property. This is the first time (as far as I can recall) that I’ve come across the use of what is essentially a predefined variable within the CSS language. The variable itself is pre-defined by the user-agent (you’ll notice that Firefox uses slightly different ‘open-quote’ and ‘close-quote’ symbols to Safari / Chrome.

Should you wish to override the browser default, you can do so either by changing the ‘content’ property of each individual ::before and ::after declaration, or you can use the ‘quotes’ property of the ‘parent’ (? I’m not sure that this is the correct term ?) element.

The quotes property

The specification for the quotes property goes into great detail on how this may be used to employ different symbols across different languages or different levels of nested quotes, but the basic use would be to declare the ‘open-quote’ value and the ‘close-quote’ value, separated by spaces, as the value of the ‘quotes’ property as follows:

[css]
q {
quotes: ‘“’ ‘”’;
}
[/css]

Whichever values you define will be used in place of the User-Agent defined symbols throughout your document.

Taking it a little further

This technique does not only have to be applied to <q> elements. It appears that any element can take a ‘quotes’ property, which can subsequently be called in its own ::before or ::after pseudo-elements.

For example, consider the following, using CSS3 attribute selectors :

[css]
[cite^="http://blog.neilpie.co.uk"]{
quotes: ‘As I have said on my weblog: “’ ‘”’;
}
[cite^="http://blog.neilpie.co.uk"]::before {
content: open-quote;
}
[/css]

What we are doing here is prepending any element with the ‘cite’ attribute starting with ‘http://blog.neilpie.co.uk’ – i.e. anything that cites this blog as its source – with an ‘open-quote’ value of ‘As I have said on my weblog: “’.

By writing this CSS rule without an element selector, it automatically applies to any element with a matching ‘cite’ attribute – so will also include <blockquote> elements. If we only wanted to match q elements, then we likely wouldn’t need the ::before declaration, because this would already be defined in the user-agent style sheet. Do note that while the ‘cite’ attribute is only valid on a <q> or <blockquote> element, the CSS rules here would also apply to any other element matching the rule.

Taking it a little too far?

It occurs to me that being able to predefine these ::before and ::after content strings could be used outside of the context of quotes, and leant on for use in some elaborate CSS, enabling an element of DRY programming in CSS. The problem is that it feels just a little bit dirty to me to do so at this point. I intend to explore the ‘content’ property further before drawing any conclusions, as there are other possible values that it can take outside of ‘open-quote’, ‘close-quote’ and strings – including the intriguing ‘attr(X)’ – any of which could turn out to be extremely useful to this end.

Leave a Reply

Your email address will not be published. Required fields are marked *