23.2. Generated ContentGenerated content refers to content that is not in the document tree, yet is inserted in the page when it is displayed in a browser window, printed on paper, projected on a screen, read aurally, or otherwise delivered. Generated content may be specified text, images, or other media (or even the values of attributes) added before or after an element. It could be used to insert the name of the person making an edit after deleted text (del element). Used together with media-specific style sheets, generated content could be used to write out the URL after links only when the document is printed, or to say "end of table" at the end of a long table only when the document is read aurally. There are also several properties that control counters, the mechanisms that keep track of the numbering for ordered list. Used together with generated text, it is possible to insert the word "Section" before each automatically numbered section heading. Allowing the user agent to automatically insert labels and numbers makes it easier to reorganize and relabel long documents because the numbers don't need to be edited manually in the source.
23.2.1. Inserting Generated ContentGenerated content is specified in the style sheet with the :before and :after pseudoelements (pseudoelements are discussed in Chapter 17). The :before selector inserts content (most commonly, but not limited to, text characters, an image, or quotation marks) immediately before the targeted element. The :after pseudoelement inserts the generated content just after the targeted element. Both pseudoelements are used in conjunction with the content property, which is used to specify where the generated content is to be inserted.
Values:normal | [ <string> | <uri> | <counter> | attr(<identifier>) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit Initial value:normal Applies to::before and :after pseudoelements Inherited:No The values for content fall into three broad categories: counters, quotation marks, and "whatever." Counters and quotation marks are discussed in upcoming sections. This section takes on "whatever," which more formally refers to character strings, URIs, and attribute values. The simplest example of generated text is to insert a string of text before or after an element. In this example, initials are inserted after each del element (indicating deleted text) to show who made the change. The resulting page is shown in Figure 23-5. del:before { content: "[JNR] "; } del { text-decoration: line-through; border: solid 1px; padding: 2px; } <p>Praesent tincidunt aliquet urna. vel consectetuer velit tellus a quam. <del>Vestibulum rutrum,</del> magna at tempor aliquet, pede mi imperdiet purus, Vivamus eleifend. Fusce bibendum. Nam molestie dictum sem.</p> Figure 23-5. Inserting text before an elementYou can tell from the border applied to the del element that the generated content is included in the content area for the element. It also inherits whatever styles are applied to the targeted element, such as line-through in the example. There are a few syntax requirements when inserting text strings:
It is also possible to use the value of an element's attribute as the generated text by specifying attr(attribute-name) in the value of the content property. One very practical use is to display the URL for links when the document is printed so the reader can follow up on linked resources later. The styles in this example appear in a style sheet that gets used only when the document prints (print style sheets are discussed in detail in Chapter 36). The markup is also provided. a {text-decoration: none; a[href]:after {content: " (" attr(href) ")";} <p>Read my <a href="http://www.oreilly.com">book</a>.</p> <p>Visit my <a href="http://www.jenville.com">site</a>.</p> <p>Visit my <a href="http://www.littlechair.com">other site</a>.</p> The a[href] attribute selector applies the rule only to anchors that have the href attribute and not to named anchors used to identify document fragments. The value of the content property directs the user agent to generate this content after the a element:
When the document is printed, the URL will be written out, as shown in Figure 23-6. Figure 23-6. Inserting the attribute value of href23.2.2. Quotation MarksThe content property also provides a way to insert quotation marks automatically before and after an element using the open-quote, close-quote, no-open-quote, and no-close-quote values. They are designed to work in tandem with the quotes property, which is used to specify which style of quotation marks to use before and after elements. It will be helpful to cover the quotes property first, then demonstrate the content values mentioned earlier.
Values:[<string><string> ]+ | none | inherit Initial value:Depends on user agent Applies to:All elements Inherited:Yes The quotes property allows authors to specify which characters to use as quotation marks before and after elements. This may be useful for delivering documents with different styles of quotation marks based on audience (and style sheet) without having to go back and edit the document. The value of quotes is one or more pairs of character strings. The first value is applied at the beginning of the quote, and the last value is applied at the close of the quote. This example specifies standard English double quotes at the open and close of a quote element. q {quotes: '"' '"'; } Additional pairs specify quotation styles for each consecutive nesting level, as shown in this style rule. Notice that the quotation marks that enclose the provided values must not match the specified quotation character (in other words, when specifying a single quote, use double quotes, and vice versa). q {quotes: '"' '"' "'" "'"; } The double and single quotes specified in this example render as the straight up-and-down ASCII characters. For curly quotes and other more sophisticated quotation characters, the characters must be escaped. In style sheets, characters are escaped with a backslash (\) preceding the hexadecimal Unicode code point (number). The (X)HTML method of escaping characters (&#nnn;) is not valid in style sheets. Character escaping is discussed further in Chapter 6. This example specifies curly double quotes before and after quotations. q {quotes: '\201C' '\201D'; } Table 23-2 lists the Unicode equivalents for common quotation characters.
Once the quotation mark characters have been specified, the content property with the open-quote and close-quote keyword values applies the quotation marks at the beginning and end of the quote. q {quotes: '\201C' '\201D'; } q:before { content: open-quote; } q:after { content: close-quote; } The standard treatment for long quotations that span several paragraphs is to omit the closing quotation mark at the ends of paragraphs (except the final paragraph of the quotation). The no-close-quote value allows you to specify that the quotation mark should be omitted from the end of the element, but it closes the quotation such that the proper nesting levels are preserved. When using the no-close-quote value, you must specifically add a quote to the last paragraph in the quote. Similarly, the no-open-quote value maintains the nesting level as though there were a quotation mark there, but it suppresses the display of the quotation character. 23.2.3. Automatic Numbering and CountersIf you have ever used an ordered list in a web page, then you have some basic experience with counters. The CSS 2.1 specification provides properties that allow counters to be added to any element, not just lists. With these tools, you could automatically number the headings in a document and never need to edit the source when new headings are inserted. Unfortunately, as of this writing, CSS counters are only supported by Opera Versions 5 and higher (a very small slice of web traffic). For that reason, this section provides only a brief introduction to the properties and how they are used. For more information, see the CSS 2.1 specification online (www.w3.org/TR/CSS21/generate.html). Once again, Cascading Style Sheets: The Definitive Guide by Eric Meyer (O'Reilly) provides an excellent tutorial on using counters . Automatic numbering is controlled by the counter-reset and the counter-increment properties used in conjunction with the content property for generated content. counter-reset establishes a starting point for the numbering.
Values:[<identifier> <integer>? ]+ | none | inherit Initial value:Depends on user agent Applies to:All elements Inherited:No The value of the counter-reset property is an identifier (a label set by the author such as "chapter" or "section") and an optional number that serves as the starting number. The default is zero (0), so simply declaring an identifier for counter-reset sets it to 0. Any integer may be specified as the starting number, including negative values. In this simple example, a "chapter" counter is established and starts at 3. h1 {counter-reset: Chapter 3; } Now that a starting point has been established, the counter-increment property is used to indicate that an element triggers the counter to go up.
Values:[<identifier> <integer>? ]+ | none | inherit Initial value:Depends on user agent Applies to:All elements Inherited:No The value of counter-increment provides the name of the identifier (such as "chapter" or "section") and an optional number that serves as the increment amount. The default is 1, so each instance of the element adds 1 to the counter unless it is specified otherwise. It is possible to specify negative values to make the counter count backward. In this example, the "chapter" counter from the previous example is given the default counter increment of 1. h1 {counter-increment: chapter; } This is the same as specifying h1 {counter-increment: chapter 1; } These counter functions are useful only when used with the counter( ) and counters( ) values of the content property. The provided values for counter( ) are the identifier name and an optional style (one of the list-style-type values such as upper-alpha). The counter style is decimal (1, 2, 3, etc.) by default. In this example, the content property is used to insert the automatic counter and the colon character (:) followed by a space before each h2 element in a document. h2:before {counter(section) ": " counter-increment: section; } /* defaults to 1 */ The counters( ) function is used to specify counters that are several levels deep (e.g., 1.0, 1.1., 1.2., 1.3., 2.0, 2.1., 2.1.1, 2.1.2, 2.1.3., and so on) without needing to specify counter rules for each nesting level individually. The hitch is that they must all be given the same identifier name. It is a good idea to provide a separator character such as a period or a comma to visually separate the string of counters. Consider for a moment what happens when you put an ordered list inside an ordered list in HTML. By default, the nested ordered list starts counting at "1" by default. That is because lists are self-nesting. When the user agent detects a new nesting level (or "scope," to use the lingo), the counters( ) function knows to trigger the appropriate counter in the string. This example creates a nested-counter style that counts sections and two levels of subsections (as listed above). ol {counter-reset: ordered;} ol li:before {counter-increment: ordered; content: counters(ordered, ".");} The counting mechanisms provided by CSS 2.1 are much more powerful than the tiny glimpse provided in this section. One day, when browsers catch up in support, they'll be a useful tool for content handling. |