CSS2 Properties - Generated content
A D V E R T I S E M E N T
Generated content
There are three principal types of content; firstly, replaced content,
secondly non-replaced content, and thirdly non-replaced content. Here is an
illustration of each in HTML.
<P>
Some non-replaced content - directly used
</P>
<IMG src="green.gif"> <!-- Some replaced content - the IMG
reference is replaced by an image. -->
<LI>
Some non-replaced content that will be preceded by some generated content - the
list marker.
</LI>
Generated content thus includes such things as list item markers in HTML.
HTML only includes very basic generated content, but CSS provides a much richer
array of properties to specify generated content.
:Before and :after pseudo-elementsTypically, generated content consists of putting a piece of content before or
after an element (e.g., a list marker before a list item). To cater for this,
CSS provides the :before and :after pseudo-elements. For example, P:before
{content: "J"} specifies that P elements should be preceded by a J.
In addition to specifying the content that precedes or follows an element,
the :before and :after selectors are also used to specify the formatting of that
content; for example, P:before {content: "J"; color: red} would make the 'J'
before the element red.
It should be noted that for the purposes of first line and first letter,
before is assumed to be the start of the element.
Note that :before and :after inherit style from the element itself so if the
element is red then its generated content will also be read.
Subsequent elements consider generated content to be part of the element.
Thus:
<P>
The <SPAN></SPAN> sat on the log.
</P>
SPAN:after {content: "dog"}
Would be rendered in exactly the same way as:
<P>
The dog sat on the log.
</P>
Valid values for display on :before and :after
If the element to which :before or :after is
applied is a block-level (i.e., table, list-item, compact, run-in or block)
element, display may be set to none, inline,
block, or marker. Any other value for display
will be reset to block.
Inline elements may only have display set to none or
inline, with other values reset to inline.
Compact elements with generated content
- A compact element that has an inline :before or :after takes it into
account when the size of the element's box is considered, and it is included
in the same block box as the element.
DIV:after {display:
inline;
/* Assuming a width of 30% */}
DIV {display: compact;
/* Assuming a width of 30% */}
P {margin-left: 50%}
<DIV>
</DIV>
<P>
In this example, the DIV has a width of 60%, and therefore cannot fit
- A compact element that has a block :before pseudo-element has the
pseudo-element formatted as a block above the element.
DIV:before {display: block;
width: 30%}
DIV {display: compact;
/* Assuming a width of 30% */}
P {margin-left: 50%}
<DIV>
</DIV>
<P>
In this example, the DIV has a width of 30%, and therefore fits.
- A compact element that has an block :after pseudo-element has the two
elements formatted as separate block elements.
DIV:after
{display: block;
width: 30%}
DIV {display: compact;
/* Assuming a width of 30% */}
P {margin-left: 50%}
<DIV>
</DIV>
<P>
In this example, the DIV has a width of 30%, and therefore fits.
- Where an element following a compact element has a block :before, the
compact element considers the :before pseudo-element.
DIV
{display: compact;
/* Assuming a width of 30% */}
P:before {display: block;
margin-left: 50%}
<DIV>
</DIV>
<P>
In this example, the DIV has a width of 30%, and therefore fits.
- Where an element following a compact element has an inline :before, the
formatting of the compact element depends on display of the element to which
the :before is attached.
DIV {display: compact;
/* Assuming a width of 30% */}
P:before {content: url(green.gif);
display: inline;
width: 30%}
P {margin-left: 50%}
<DIV>
</DIV>
<P>
In this example, since the :before content is inline, it is positioned
inside the P, and there is therefore enough room for the DIV.
Counter functionsAlthough we have already seen that CSS can generate content that is always
the same, it also provides the ability for counter functions. Essentially these
are the same as list items except they allow for more advanced numbering
schemes.
There are basically five issues relating to counters:
- The name of the counter function - used to identify the counter so that
references can be made to it.
- The increment of the counter - is it 1, 2, 3 or 1, 7, 13?
- The initial value of the counter - is it 1, 2, 3 or 126, 127, 128?
- The trigger to reset the counter to its initial value.
- The way in which the counter is formatted - is it 1, 2, 3 or i, ii, iii?
1. Naming counter functions
In order to refer to counter functions, you specify something like P
{content: counter(myCounter)}. Note that counter names are, as with all CSS,
case-insensitive.
2. Incrementing counter functions
In order to specify the increment of a counter function, you use the
counter-increment property. This property specifies the increment of a counter
on encountering an instance of an element. The initial value is 'none', so
initially no element increments a counter.
To specify an increment, you declare the name of the counter function
followed by the increment (which can be any integer). For example, H1
{counter-increment: HeadingCounter 1}. If the increment is omitted, 1 is
assumed, so H1 {counter-increment: HeadingCounter} is also valid.
If you wish to specify that an element should increment more than one counter
function, simply separate them with spaces. For example, H1 {counter-increment:
HeadingCounter 10 HeadingCounter2}.
Counter-increment is not inherited. It applies to all elements.
Note that counter values are used after any increment specified for
that element.
3. Initial values and counter resets
To specify the element that resets a counter function, the counter-reset
property is used.
It follows an identical syntax to counter-increment. It is used
to reset the given counter to the given number (if a number is omitted, 0 is
assumed).
Counter-reset is not inherited. Its initial value is 'none'. It applies to
all elements.
Here's an example: H1 {counter-reset: counter1 counter2 -26} (this would
reset counter1 to 0 and counter2 to -26).
Like counter-increment, counter-reset may only be set to integer values.
Note that counter values are used after any reset specified for that
element, and that counters are incremented after they have been reset. Thus
H1:before {counter-reset: counter; counter-increment: counter; content:
counter(counter)} would result in 1 since it would first be reset, then
incremented, and then finally used.
The effect of descendant elements on counter-reset
Counter-reset only affects sibling and descendant elements. For example:
OL {counter-reset: licounter}
LI {content: counter(licounter);
counter-increment: licounter}
<OL> - licounter reset to 0
<LI> - licounter incremented to 1
<LI> - licounter incremented to 2
<LI> - licounter incremented to 3
<LI> - licounter incremented to 4
<OL> - licounter reset to 0, but since counter-reset only affects siblings and
descendants, this won't affect the old counter
<LI> - licounter incremented to 1
</OL>
<LI> - licounter incremented to 5
</OL>
4. Counter styles
Once you have a counter function, you will probably want to style it. This is
done using counter(). For example, P:before {content: counter(counter,
lower-alpha); counter-increment: counter} with <P>Hello <P>Hello would be
rendered as:
aHello
bHello
Thus the counter function can be followed by a
list style type, which will convert the integer into a value. Thus if the
counter function was running at 26, z would be rendered. If the list type is
unordered, it will always result in the same thing - content: counter(counter,
disc) would always result in a disc.
contentThis property is used in conjunction with the :before and :after
pseudo-elements to provide generated content.
In its simplest form, content is a string; e.g., :before {content:
"Hello"}, which would cause Hello to appear before every
element.
However, the content can also be set to a keyword, such as open-quote.
Valid values are (one or more of each)
- a string of text enclosed within quote marks (such as content: "My
text")
- an external resource, designated by url(resourcename.type),
e.g., content: url(green.gif)
- a counter function, e.g., content: counter(counterfunct, decimal)
- a compound counter function. Compound counter functions are used for
situations like this:
1.
1.1
1.2
They take the following form - content: counters(mycounter, "string",
type) or content: counters(mycounter, "string"). Essentially, the number
used is the level of the counter - in
<OL>
<LI>
<OL>
<LI>
<OL>
<LI>
</OL>
</OL>
</OL>
, the result would be 1 for the outermost, 1.1 for the next one in, and
1.1.1 for the next one in from that (given content: counters(mycounter,
".")).
- attr(x), where x is the name of the attribute (such as
title in <IMG title="A picture of my zucchini">;
attr(title) would return "A picture of ...")
- open-quote
- close-quote
- no-open-quote
- no-close-quote
Its initial value is "", and it applies only to :before and :after. It is not
inherited.
You can specify several items of content. For example, content: "("
counter(counterfunction, lower-alpha) ".) " would result in (a.) , (b.) , (c.) ,
etc.
The open-quote are used to specify that the language-appropriate quotation
mark should be inserted. For example, Q:before {content: open-quote} Q:after
{content: close-quote}. The appropriate quotation mark can be set using the
quotes property. Since this allows different levels of quotes (e.g., She said,
"He was so rude - he said, 'Go away'"), the purpose of no-open-quote and
no-close-quote is to decrement or increment the quote level without actually
inserting quotes.
For example:
BLOCKQUOTE P:before {content: open-quote}
BLOCKQUOTE P:after {content: no-close-quote}
BLOCKQUOTE P.last:after {content: close-quote}
Given:
<BLOCKQUOTE>
<P>
Some text from a quote.
<P>
Another paragraph from a quote.
<P class="last">
The final paragraph from a quote.
</BLOCKQUOTE>
Would result in:
'Some text from a quote.
'Another paragraph from a quote.
'The final paragraph from a quote.'
Initially, content is "". It is not inherited.
QuotesThis property instructs the web browser on the appropriate method of
displaying the aforementioned open-quote and close-quote,
and can take one of the following values: none (don't render
open-quote and close-quote); one or more sets of quotation
marks, where the first quote mark is the opening quote mark, the second the
closing quote mark; if more than one set of quotes is specified, the first set
applies to the first set of open quote marks, the second to the second set, etc.
The initial value is browser dependent. Quotes is inherited.
For example:
Q {quotes: '"' '"' "'" "'" }
Q:before {content: open-quote}
Q:after {content: close-quote}
MarkersMarkers are used to create effects such as:
- A list item
- A list item
Without them, you could only do something like.
9. A list item
10. A list item
Thus they allow you to line text up correctly. They are specified using
display: marker, and are only valid in association with the :before and :after
pseudo-elements.
In order to this, marker boxes are placed outside the border edge of an
element (i.e., in the element's margin). This means that BODY, LI, OL {margin:
0} would result in the marker boxes being pushed off the left of the canvas.
Marker boxes may not have margins, but they may have padding and borders.
For example:
OL {margin: 0;
background: red;
counter-reset: counterfunc}
LI {margin-left: 5%;
background: green}
LI:before {display: marker;
marker-offset: auto
content: counter(counterfunc);
counter-increment: counterfunc}
Results in a green background for the content of the LI, and red for the
marker, since the marker is placed in LI's margin.
Only block-level elements may have display: marker. Block-level elements are
tables, list-items, block, compact and run-in elements.
Note that when list items have :before set to display, display is set to
block.
Height and alignment of marker boxes
The height of marker boxes is determined by line-height, and the marker box
is taken into consideration for the purposes of calculating the height of the
line box with which it is aligned in the principal box.
If applied on :before, the baseline of the marker is aligned with the
baseline of the first line of content in the principal box. If there is no such
content in the principal box, the top of the marker is aligned with the top of
the principal box.
If applied on :after, the baseline of the marker is aligned with the baseline
of the last line of content in the principal box. If there is no such content in
the principal box, the bottom of the marker is aligned with the bottom of the
principal box.
Inheritance into marker boxes
As with other pseudo-elements, marker box inherit inheritable style; for
example, given:
ELEMENT {color: red;
background: green}
ELEMENT:before {display: marker}
, the marker box would have red text; it would not have a green background,
because backgrounds are not inherited.
List items as markers
Note that list items as specified via the LI element are markers - when you
set ELEMENT {display: list-item}, you are effectively setting ELEMENT {display:
block} ELEMENT:before {display: marker; content: counter(function);
counter-increment: function}.
As a result, elements with display: list-item must have margins in which to
place the counter.
In addition, given LI {background: red}, the marker box will not be red since
background is not inherited. To see whether this is correctly followed in your
browser, have a look at this:
-
A list item
Marker-offset
This property specifies the distance between the border edge of the marker
box and the border edge of the thing that it is marking to be specified.
It can be specified as a length (including negative lengths) or as auto but
not a %. It is not inherited and is intially auto (= UA defined).
|