CSS Generated Content Properties

2008 Oct 23


Property Values Initial Value Applies to Inherited
content normal | [ <string> | <uri> | <counter> | attr(<identifier>) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit normal :before and :after pseduo classes no
quotes [<string><string>?]+ | none | inherit not defined all elements no
counter-reset [<identifier><integer>?]+ | none | inherit not defined all elements yes
counter-increment [<identifier><integer>?]+ | none | inherit not defined all elements no

To insert generated content at the beginning or end of an element's content, use the :before and :after pseduo classes. For example:

CSS+HTML Results
p.copyr { font-size: 7pt; text-align: center; }
p.copyr:before { content: "(C) Copyright "; }
p.copyr:after { content: 
   " Imagine Inc. All rights reserved."; }
...
<p class=copyr>2008-2009</p>

2008-2009

Support for entities in generated content, e.g. &copy; as ©, is poor at the present.
IE does not currently support generate content at all.
Positioning is not available for generated content.

Generated content can only be sucessfully made block-level if the element it is associated with is block-level (otherwise the display property is reset to inline).

The CSS way of representing a newline in a <string> is \A (unicode linefeed), but not many browsers support this yet. A \ followed by a newline is a way to continue a long line on the next line to fold it to the window or screen, e.g.:

li:before { content: "Here is a line continued \
on the next line." }

content

The attr() value enables putting a specified attribute value in the content. A non existent attribute results in an empty string. Any markup in this value string is not interpreted it is placed literaly as is.

CSS+HTML Results
em:after { content: " {" attr(class) "}"; }
...
<em class=zzz>foo</em>
foo

The content could contain hexadecimal escape sequences:

CSS+HTML Results
span.esc:before { content: "\00BB \00A9  "; }
...
<span class=esc>foo</span>
foo

But naturally IE does not support this!


quotes

This property specifies the pattern and nesting used with quotes. The actual quote marks are inserted with content property values of open-quote and close-quote. The value no-open-quote decrements the quotation nesting count with out putting a quote mark (as is done sometimes typographically when multi-paragraph quotes are done.

CSS+HTML Results
blockquote { quotes: '"' '"' "'" "'"; }
blockquote p:before { content: open-quote; }
blockquote p:after { content: no-close-quote; }
blockquote p.last:after { content: close-quote; }
...
<blockquote>
<p>First.</p>
<p>Middle.</p>
<p class=last>Last.</p>
</blockquote>

First.

Middle.

Last.

Perhaps the main advantage of this mechanism is the ease of changing to language dependent quotes.


counter-reset
counter-increment

To implement counters the ability to initialize (or reset) and increment named counters with different values is given. A counter identifier is a name given by the document creator. The action of reseting (or incrementing) a counter (e.g. in a chapter) creates and initializes it. The default initial value is 0, and the default increment value is 1, but can be any explicit value. Negative values have no defined meaning for non numerical styles. Unfortunately most browsers do not do counters correctly - as you can see in the example below.

CSS+HTML Results
body { counter-reset: L1; }
h1.L1:before { counter-reset: L2;
               counter-increment: L1; 
               content: counter(L1) " "; }
h2.L2:before { counter-reset: L3;
               counter-increment: L2; 
               content: counter(L1) "." 
                        counters(L2) " "; }
h3.L3:before { counter-reset: L4;
               counter-increment: L3; 
               content: counter(L1) "." 
                        counters(L2) "." 
                        counters(L3) " "; }
h4.L4:before { counter-reset: L5;
               counter-increment: L4; 
               content: counter(L1) "." 
                        counters(L2) "."
                        counters(L3) "." 
                        counters(L4) " "; }
...

One

One.One

One.Two

Two

Two.One

Two.One.One

Two.Two

Two.Two.Two

Two.Two.Two.One

Three