Title: CSS Generated Content Module Level 3 Status: ED Work Status: Exploring Shortname: css-content Level: 3 Group: csswg TR: https://www.w3.org/TR/css3-content/ ED: https://drafts.csswg.org/css-content/ Previous Version: https://www.w3.org/TR/2016/WD-css-content-3-20160602/ Editor: Elika J. Etemad / fantasai, W3C Invited Expert, http://fantasai.inkedblade.net/contact, w3cid 35400 Editor: Dave Cramer, Hachette Livre, dauwhe@gmail.com, w3cid 65283 Former Editor: Håkon Wium Lie, Opera Software, howcome@opera.com Former Editor: Ian Hickson, Google, ian@hixie.ch Ignored Terms:, leader(), string(), target-counter(), target-counters(), target-text() Abstract: This CSS3 Module describes how to insert content in a document. Link Defaults: css2 (type) , css-display-3 (value) inline Status Text: This is a very rough draft, and is not ready for implementation. Default Highlight: css
h1::before { content: counter(section) ": "; }
chapter { counter-increment: chapter; } chapter > title::before { content: "Chapter " counter(chapter) "\A"; }
/* Replace <logo> elements with the site's logo, using a format * supported by the UA */ logo { content: url(logo.mov), url(logo.mng), url(logo.png), none; } /* Replace <figure> elements with the referenced document, or, * failing that, with either the contents of the alt attribute or the * contents of the element itself if there is no alt attribute */ figure[alt] { content: attr(href, url), attr(alt); } figure:not([alt]) { content: attr(href, url), contents; }
Name: content Value: normal | none | [ <> | < > ] [/ < > ]? Initial: normal Applies To: all elements, tree-abiding pseudo-elements, and page margin boxes Inherited: no Percentages: n/a Computed Value: See prose below Animation type: discrete
User Agents are expected to support this property on all media, including non-visual ones.
The 'content' property dictates what is rendered inside an element or pseudo-element. For elements, it has only one purpose: specifying that the element renders as normal, or replacing the element with an image (and possibly some associated "alt text"). For pseudo-elements and margin boxes, it is more powerful. It controls whether the element renders at all, can replace the element with an image, or replace it with arbitrary inline content (text and images).<Makes the element or pseudo-element a replaced element, filled with the specified <>
[ <Replaces the element's contents with one or more anonymous inline boxes corresponding to the specified values, in the order specified. Its normal contents are suppressed and do not generate boxes, as if they were ''display: none''. Each value contributes an inline box to the element's contents. For <> | contents | < > | < > | <> | < > ]+
.new::before { content: url(./img/star.png) / "New!"; /* or a localized attribute from the DOM: attr("data-alt") */ }
.expandable::before { content: "\25BA" / ""; /* a.k.a. ► */ /* aria-expanded="false" already in DOM, so this pseudo-element is decorative */ }
"First Second"
(with a single visible space between the two words).
foo { content: normal; } /* this is the initial value */ foo::after { content: contents; }...the element's 'content' property would compute to ''content/contents'' and the after pseudo element would have no contents (equivalent to ''content/none'') and thus would not appear.
foo { content: none; } foo::after { content: contents; }But in this example, the ::after pseudo-element will contain the contents of the foo element.
q
element,
used to delimit quotations.
The ''quotes'' property,
in conjunction with the various ''*-quote'' values of the 'content' property,
can be used to properly style such quotations.
Name: quotes Value: none | [ <> < > ]+ Initial: depends on user agent Applies To: all elements Inherited: yes Percentages: n/a Computed Value: the keyword ''quotes/none'' or a list, each item a pair of string values Animation type: discrete
User Agents are expected to support this property on all media, including non-visual ones.
Issue: The previous ED had an initial value of ''text'', which was an error. [[CSS21]] has initial value of "depends on user agent". Do we use<>= open-quote | close-quote | no-open-quote | no-close-quote
blockquote
, and inserts a single closing quote at the end:
blockquote p:before { content: open-quote } blockquote p:after { content: no-close-quote } blockquote p:last-child::after { content: close-quote }
The device of the order of the garter is “Honi soit qui mal y pense.”English inside French:
Il disait: « Il faut mettre l’action en ‹ fast forward ›. »A style sheet like the following will set the 'quotes' property so that ''open-quote'' and ''close-quote'' will work correctly on all elements. These rules are for documents that contain only English, French, or both. One rule is needed for every additional language. Note the use of the child combinator (">") to set quotes on elements based on the language of the surrounding text:
:lang(fr) > * { quotes: "\00AB\2005" "\2005\00BB" "\2039\2005" "\2005\203A" } :lang(en) > * { quotes: "\201C" "\201D" "\2018" "\2019" }The quotation marks are shown here in a form that most people will be able to type. If you can type them directly, they will look like this:
:lang(fr) > * { quotes: "« " " »" "‹ " " ›" } :lang(en) > * { quotes: "“" "”" "‘" "’" }
/* Specify pairs of quotes for two levels in two languages */ :lang(en) > q { quotes: '"' '"' "'" "'" } :lang(no) > q { quotes: "«" "»" "’" "’" } /* Insert quotes before and after Q element content */ q::before { content: open-quote } q::after { content: close-quote }to the following HTML fragment:
<html lang="en"> <head> <title>Quotes</title> </head> <body> <p><q>Quote me!</q></p> </body> </html>would allow a user agent to produce:
"Quote me!"while this HTML fragment:
<html lang="no"> <head> <title>Quotes</title> </head> <body> <p><q>Trøndere gråter når <q>Vinsjan på kaia</q> blir deklamert.</q></p> </body> </html>would produce:
«Trøndere gråter når ’Vinsjan på kaia’ blir deklamert.»
leader() = leader( <Three keywords are shorthand values for common strings:> ) < > = dotted | solid | space | <>
ol.toc a::after { content: leader('.') target-counter(attr(href), page); } <h1>Table of Contents</h1> <ol class="toc"> <li><a href="#chapter1">Loomings</a></li> <li><a href="#chapter2">The Carpet-Bag</a></li> <li><a href="#chapter3">The Spouter-Inn</a></li> </ol>This might result in:
Table of Contents 1. Loomings.....................1 2. The Carpet-Bag...............9 3. The Spouter-Inn.............13
BBBBBBBBBB BBB2. The leader string consists of one or more glyphs, and is thus an inline box. A leader is a row of these boxes, drawn from the end edge to the start edge, where only those boxes not overlaid by the before or after content. On this line, draw the leader string, starting from the end edge, repeating as many times as possible until reaching the start edge.
BBBBBBBBBB ..........3. Draw the before and after content on top of the leader. If any part of the before content or after content overlaps a glyph in a leader string box, that glyph is not displayed.
BBBBBBBBBB BBB....AAA4. If one full copy of the leader string is not visible:
BBBBBBB BBBBBBAInsert a line break after the before content, draw the leader on the next line, and draw the after content on top, and hide any leader strings that are not fully displayed.
BBBBBBB BBBBBB ......AIssue: what to do if after content is wider than the line box? Issue: Leaders don't quite work in table layouts. How can we fix this?
<See sections below for details on each of these.> = <> | < > | < >
target-counter() = target-counter( [ <The ''target-counter()'' function retrieves the value of the innermost counter with a given name. The required arguments are the url of the target and the name of the counter. An optional counter-style argument can be used to format the result. These functions only take a fragment URL which points to a location in the current document. If there’s no fragment, if the ID referenced isn't there, or if the URL points to an outside document, the user agent must treat that as an error. Issue: what should error handling be? Issue: restrict syntactically to local references for now.> | < > ] , < > , < >? )
…which will be discussed on page <a href="#chapter4_sec2"></a>.CSS:
a::after { content: target-counter(attr(href url), page) }Result:
…which will be discussed on page 137.
<nav> <ol> <li class="frontmatter"><a href="#pref_01">Preface</a></li> <li class="frontmatter"><a href="#intr_01">Introduction</a></li> <li class="bodymatter"><a href="#chap_01">Chapter One</a></li> </ol> </nav>CSS:
.frontmatter a::after { content: leader('.') target-counter(attr(href url), page, lower-roman) } .bodymatter a::after { content: leader('.') target-counter(attr(href url), page, decimal) }Result:
Preface.............vii Introduction.........xi Chapter One...........1
target-counters() = target-counters( [ <> | < > ] , < > , < > , < >? )
I have not found a compelling example for target-counters() yet.Issue: found a compelling example, in CSS specs. Do something.
target-text() = target-text( [ <Issue: A simpler syntax has been proposed by fantasai: http://lists.w3.org/Archives/Public/www-style/2012Feb/0745.html> | < > ] , [ content | before | after | first-letter ]? )
…which will be discussed <a href="#chapter_h1_1">later</a>. a::after { content: ", in the chapter entitled " target-text(attr(href url)) }Result: …which will be discussed later, in the chapter entitled Loomings.
meta[author] { string-set: author attr(author); } head > title { string-set: title contents; } @page:left { @top { text-align: left; vertical-align: middle; content: string(title); } } @page:right { @top { text-align: right; vertical-align: middle; content: string(author); } }
Name: string-set Value: none | [ <> < >+ ]# Initial: none Applies to: all elements, but not pseudo-elements Inherited: no Percentages: N/A Computed value: the keyword ''string-set/none'' or a list, each item an identifier paired with a list of string values Animation type: discrete
User Agents are expected to support this property on all media, including non-visual ones.
The 'string-set' property copies the text content of an element into a ''named string'', which functions as a variable. The text content of this named string can be retrieved using the ''string()'' function. Since these variables may change on a given page, an optional second value for the ''string()'' function allows authors to choose which value on a page is used.[ <> <>+ ]#
H1 { string-set: chapter contents; }When an H1 element is encountered, the ''chapter'' string is set to the element's textual contents, and the previous value of ''chapter'', if any, is overwritten.
string() = string( <The ''string()'' function is used to copy the value of a named string to the document, via the 'content' property. This function requires one argument, the name of the named string. Since the value of a named string may change several times on a page (as multiple elements defining the string can appear) an optional second argument indicates which value of the named string should be used. The second argument of the ''string()'' function is one of the following keywords:> , [ first | start | last | first-except ]? )
@page { size: 15cm 10cm; margin: 1.5cm; @top-left { content: "first: " string(heading, first); } @top-center { content: "start: " string(heading, start); } @top-right { content: "last: " string(heading, last); } } h2 { string-set: heading content() }The following figures show the first, start, and last assignments of the “heading” string on various pages.
content() = content( [ text | before | after | first-letter | marker ]? )
<h1>Loomings</h1>CSS:
h1::before { content: 'Chapter ' counter(chapter); } h1 { string-set: header content(before) ':' content(text); } h1::after { content: '.'; }The value of the named string “header” will be “Chapter 1: Loomings”.
<section title="Loomings">CSS:
section { string-set: header attr(title) }The value of the “header” string will be “Loomings”.
Name: bookmark-level Value: none | <> Initial: none Applies to: all elements Inherited: no Percentages: N/A Computed value: the keyword ''bookmark-level/none'' or the specified integer Animation type: by computed value type
section h1 { bookmark-level: 1; } section section h1 { bookmark-level: 2; } section section section h1 { bookmark-level: 3; }
display: none
?
Name: bookmark-label Value: <> Initial: content(text) Applies to: all elements Inherited: no Percentages: N/A Computed value: specified value Animation type: discrete
<h1>Loomings</h1>CSS:
h1 { bookmark-label: content(text); bookmark-level: 1; }The bookmark label will be “Loomings”.
Name: bookmark-state Value: open | closed Initial: open Applies to: block-level elements Inherited: no Percentages: N/A Computed value: specified keyword Animation type: discrete
::alternate
pseudo-element and the pending
value of the 'content' property.
* Examples of Norwegian and French quotation marks no longer use plus signs and semicolons as delimiters.
* Dave Cramer added as co-editor. Ian Hickson and Håkon Wium Lie are now former editors.
* Moved effects of style containement on properties of this specification from the css-contain specification to this one,
due to their respective maturity.