Sometimes, text needs to be added that is not in the original source. Examples are texts like "Figure 7" or "Chapter XI," quote marks that are automatically inserted around citations, but also the list bullets and numbers of the previous section. List bullets and numbers are the most common and are the easiest to specify. Numbering for list items is implicit: There is no explicit mention of a counter in the style sheet. But sometimes, the list-style properties are not enough (for example, when lists must be numbered as A1, A2, etc.). For those cases, CSS provides explicit counters. The same explicit counters are also used to number chapters, sections, figures, tables, and so on. Fixed texts, such as the word "Figure" in "Figure 7," can be inserted together with the counters, or even on their own. A typical case is the insertion of the word "Note:" in front of all paragraphs that constitute notes. Quotation marks are a special case. Although it is possible to just insert quote marks as fixed texts, in many cases, it is desirable to use different quote marks based on whether the quote is nested inside some other quote or not. CSS has a property quotes that automatically track the nesting level of quotations and inserts the quote marks for that level. The :Before and :After Pseudo-Elements and the Content PropertyOne example where you might want to use the style sheet to insert text is in the case of notes. Say you have a paragraph with class "note" that looks like this in the source document: ... <P >Steps 22 to 24 should be repeated for each B-channel. ... The way this should look in the formatted output is like this:
The text "Note:" is inserted at the start, and "[end of note]" at the end. Here are the style rules to achieve this: P.note:before { content: "Note: "; font-weight: bold } P.note:after { content: " [end of note]" } :before and :after are pseudo-elements. They refer to "elements" that do not exist in the source document. You can think of them as elements that, had they existed, would have been just after the start tag and just before the end tag: <P > <:before>Note: </:before> Steps 22 to 24 should be repeated for each B-channel. <:after> [end of note]</:after> </P> The content property specifies the text that is in the pseudo-element. This property can only occur in rules for the :before and :after pseudo-elements because all other elements already have content.
The initial value of the content property is normal, which means that the corresponding pseudo-element contains no content so no box is generated. The property only becomes interesting when the values is set to a sequence of text strings and/or counters and/or quote marks. For example: BLOCKQUOTE:before { content: open-quote "quote " counter(bq) ". " } BLOCKQUOTE:after { content: close-quote } The next sections explain the keywords for the quote marks and the counters. The :before and :after pseudo-elements are inline elements by default. They are put just before the first content of the element, or just after the last content. But sometimes, you may want to put them on a separate line, in a block of their own. If their parent element is a block element, the :before and :after pseudo-elements may themselves also be block elements. That is done with the display property. For example, to end an HTML document with the words "The End" centered on a line by themselves, all that is required is BODY:after { content: "The End"; display: block; text-align: center; margin-top: 1em } The margin-top is thrown in to add a little space between the last line of the document and the words "The End." Generating Quote Marks
The simplest way to add quotes elements, such as BLOCKQUOTE and Q, is with a rule like Q:before {content: '"'}. However, most designers want to change the double quotes to single quotes if the Q occurs inside another citation. You can usually do that with contextual selectors (Q Q:after {...}), but CSS2 has an easier solution. The solution has two parts. The first part is to declare all the quote marks you want to use at each nested level of quotations. A good place to put them is on the BODY element in HTML, or on the document's root element in XML-based documents: BODY { quotes: '"' '"' "«" "»" } This defines that the sequence of quote marks for progressively nested levels of quotations is "..." for the first citation and «...» for the second level of quotations and beyond. After declaring the quotes, all that remains is to write the rules that say which elements get quotes, without saying which quotes, because that will be automatically handled: BLOCKQUOTE:before, Q:before { content: open-quote } BLOCKQUOTE:after, Q:after { content: close-quote } Now a BLOCKQUOTE that is not inside another BLOCKQUOTE gets the "..." quotes, and if a Q or another BLOCKQUOTE occurs inside it, it automatically gets the «...» quotes because the browser counts how many quotes have been opened. If you look closely at the rule for the quotes property in the previous example, you probably find that your keyboard does not have all the necessary keys. The program that you use to type in the style sheets may have special functions for generating them, but if it doesn't, there are other ways to put them in the style sheet. For example, even the simplest text editor allows you to write the rule like this: BODY { quotes: '\201C' '\201D' '\2018' '\2019' '\2039' '\203A' } It may not be immediately clear that \201C is the left double quotation mark ("), but when you are in a bind, this may be the only way out. Table 6.1 shows the most common quote marks and their hex-codes.
Most programs give you the straight quote marks ("..." and '...') when you type the corresponding keys on the keyboard. But look carefully because some programs interpret the keys differently. Different typographic traditions prefer different quotation marks. Here are some examples in different languages, using the quotes from Table 6.1. English: When I read: "The double angle quotation marks are also called 'guillemets'," I knew that they must be French. BODY { quotes: '"' '"' ''' ''' } Dutch: In een geschiedenisboek las ik: ,,Van Speyk wilde van overgeven niet horen. 'Dan liever de lucht in,' zei hij." BODY { quotes: ',,' '"' ''' ''' } German: Er sagte: >Wie wär's mit » Gutentag«?< BODY { quotes: '>' '<' '»' '«' } French: Dans un interview, Emmanuel a expliqué: « Je ne peux pas dire "Oui, je sais comment cela ce passe." Tout cela est ecrit. » BODY { quotes: '«' '»' '"' '"' } In high-quality French typesetting, the guillemets and the single angle marks have half a space between them and the quoted words. The hex-code for a "thin space" (which is half the width of a normal space) is 2009, so you can make French graphic designers happy if you change that last example to the following: BODY { quotes: '«\2009' '\2009»' '"' '"' } In fact, if you look closely, you can see that the French example actually did use this rule; for French, it just looks better. If the half space is not supported by your software, the French will be almost as happy with a non-breaking space: BODY { quotes: '«\A0' '\A0»' '"' '"' } A final note about the "thin space," for people interested in the details. Typography is always a bit more subtle than you think, and the thin space isn't exactly equal to half a normal space, or at least not always, although it is close enough for our purposes. On most systems, a thin space is equal to 1/6 of an em, which works out to be close to half of a normal space for most fonts. But, it depends a bit on the font. For proportional fonts, the normal space is usually between 0.30 and 0.36em (so the thin space is between 46 and 56 percent of the normal space), but for monospace fonts, a space may be as wide as 0.5em (and a thin space is thus no more than 33 percent of a normal space). CountersIf the numbering provided by the list-style property is not enough, you have to resort to explicit counters. For numbering chapter and section titles or tables, there is no other way. Three things can happen to counters: They are used somewhere, they are incremented, or they are reset to zero. Using counters is only possible in the content property. For example, to number notes, you could do the following: P.note:before { content: "Note " counter(note) ". " } This inserts the fixed texts "Note" and "." before every note paragraph, with the value of the "note" counter in between. For incrementing counters, there is the counter-increment property. So, if the note counter must be incremented every time there is a note paragraph, the rule would be as follows: P.note { counter-increment: note } This is enough to number all notes in the document. But sometimes, the style calls for a more sophisticated way of numbering (for example, if notes must be numbered within chapters only). Then, every new chapter must reset the counter to zero. If we assume that chapters start with an H1 element, this rule suffices: H1 { counter-reset: note }
counter-increment and counter-reset become more difficult if more than one counter needs to be incremented or reset. For example, if the H1 element resets not only the note counter, but also the counter for subsections and for figures, the rule would have to be similar to this: H1 { counter-reset: note subsection figure } This means you have to be careful when cascading several style sheets together. If one rule said h1 {counter-reset: figure} and later on, there is a style rule H1 {counter-reset: note}, the value of the counter-reset property will be just note, and the figure counter will not be reset. Here is an example that numbers chapters and sections as 1., 1.1, 1.2, ... 2., 2.1, etc.:
The style rules that produce this are as follows: H1:before { content: counter(chapter) ". "; counter-reset: section; counter-increment: chapter } H2:before { content: counter(chapter) "." counter(section); counter-reset: subsection; counter-increment: section } H3:before { content: counter(chapter) "." counter(section) "." counter(subsection); counter-increment: subsection } Styles for CountersBy default, counters are shown as decimal numbers: 1, 2, 3, .... But, just like list numbers, counters can also use roman numerals, letters, or various non-Western numbering styles. This style is indicated by adding a style keyword after the counter name: counter(chapter, upper-roman) This produces chapter numbers I, II, III, IV, .... All the styles that are available for list-style can also be used inside counter. For example, if the appendices of an article have to be numbered "Appendix A," "Appendix B," "Appendix C," etc. and the appendices all start with <H1 >, this rule makes that possible: H1.appendix:before { content: "Appendix " counter(app, upper-alpha) " "; counter-increment: app } Self-Nesting CountersNumbering schemes such as 1, 1.1, 1.2, 1.2.1, ... are common. To number the section headings in HTML this way is not difficult. There will be a counter associated with each of H1, H2, H3, to H6. But sometimes, things have to be numbered that can nest to arbitrary depth. In HTML, H6 is as far as you can go with subsections, but lists, for example, can nest to any depth, and all of them are called OL and LI. CSS handles that by automatically creating a new counter when an element resets a counter that is already in use. For example, to create lists that look like this:
and that can go on to any depth, it is enough to create one counter, say item-nr, and reset it on every OL element. The first OL creates the first item-nr, the second OL creates a new item-nr, etc. Each counter can only be used on element at the same depth on the document tree, or deeper, than the element that reset it. Therefore, the last item in this list uses the counter created by the topmost OL; all the others are "out of scope." But, how do you insert the number 1.1 into the formatted output? A declaration like content: counter(item-nr) "." counter(item-nr) does not work, because both counters refer to the same instance of the "item-nr" counter. Instead, CSS provides a variation of the counter function, spelled counters with an "s." The correct rule, then, is as follows: LI:before { content: counters(item-nr, "."); counter-increment: item-nr } OL { counter-reset: item-nr } The second argument of counters is the fixed text to put between the numbers. At the first level, the number will be 1, at the second, 1.1, at the third, 1.1.1, etc. Of course, counters also accept a style argument. If the numbers should be C.B.D, or III.II.IV, the value becomes counters(item-nr, ".", upper-alpha) or counters(item-nr, ".", upper-roman). |