8000 csswg-drafts/css-pseudo/Overview.html at 3b96cae635cdcc9f519806bcb65e09e6934f38c3 · w3c/csswg-drafts · GitHub
Skip to content

Latest commit

 

History

History
1297 lines (1032 loc) · 47.2 KB

File metadata and controls

1297 lines (1032 loc) · 47.2 KB
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang=en>
<head
profile="http://dublincore.org/documents/2008/08/04/dc-html/ http://www.w3.org/2006/03/hcard">
<meta content="text/html; charset=UTF-8" http-equiv=Content-Type>
<title>CSS Pseudo-elements Module Level 4</title>
<link href="http://purl.org/dc/terms/" rel=schema.dcterms>
<link href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright"
rel=dcterms.rights>
<meta content="CSS Pseudo-elements Module Level 4" name=dcterms.title>
<meta content=text name=dcterms.type>
<meta content=2014-02-03 name=dcterms.date>
<meta content="Daniel Glazman" name=dcterms.creator>
<meta content="Alan Stearns" name=dcterms.creator>
<meta content=W3C name=dcterms.publisher>
<meta content="http://dev.w3.org/csswg/copyright-documents/"
name=dcterms.identifier>
<script defer=defer src="css-pseudochildren_files/annotate.js"
type="text/javascript"></script>
<link href="../shared/style/default.css" rel=stylesheet type="text/css">
<link href="http://dev.w3.org/csswg/shared/style/alternate-spec-style.css"
id=st rel=stylesheet title="alternate spec style" type="text/css">
<link href="http://www.w3.org/StyleSheets/TR/w3c-unofficial.css"
rel=stylesheet type="text/css">
<body class=example>
<p><br>
<div class=head id=div-head>
<h1 id=css-pseudochildren-module>CSS Pseudo-elements Module Level 4</h1>
<h2 class="no-num no-toc" id=longstatus-date>22 June 2012</h2>
<dl>
<dt>This version:
<dd>TBD
<dt>Latest version:
<dd>27 August 2012
<dt>Previous version:
<dd>TBD
<dt>Editors:
<dd class=vcard><span class=fn>Daniel Glazman</span>, on behalf of <span
class=org>Adobe Systems, Inc.</span>
<dd class=vcard><span class=fn>Alan Stearns</span>, <span class=org>Adobe
Systems, Inc.</span>, <span class=email>stearns@adobe.com</span>
<dt>Issues List:
<dd>TBD
<dt>Discussion:
<dd><a
href="http://lists.w3.org/Archives/Public/www-style/">www-style@w3.org</a>
with subject line "<code>[css4-pseudo] message topic</code>"
</dl>
<p class=copyright><a
href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright"
rel=license>Copyright</a> © 2012 <a href="http://www.w3.org/"><abbr
title="World Wide Web Consortium">W3C</abbr></a><sup>®</sup> (<a
href="http://www.csail.mit.edu/"><abbr
title="Massachusetts Institute of Technology">MIT</abbr></a>, <a
href="http://www.ercim.eu/"><abbr
title="European Research Consortium for Informatics and Mathematics">ERCIM</abbr></a>,
<a href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved. W3C <a
href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
<a
href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>
and <a
href="http://www.w3.org/Consortium/Legal/copyright-documents">document
use</a> rules apply.
<hr title="Separator for header">
</div>
<details class=annoying-warning open=open> <summary>Not Ready For
Implementation</summary>
<p> This spec is not yet ready for implementation. It exists in this
repository to record the ideas and promote discussion.
<p> Before attempting to implement this spec, please contact the CSSWG at
www-style@w3.org.
</details>
<h2 class="no-num no-toc" id=abstract>Abstract</h2>
<div>
<p>This document extracts the notion of pseudo-elements from the Selectors
3 specification and proposes to extend it to be able to create and style
an arbitrary number of pseudo-elements <em>before</em>, <em>after</em> an
element.<br>
</div>
<h2 class="no-num no-toc" id=status-of-this-document>Status of this
document</h2>
<p>This document is a submission by Adobe Systems Inc. to the CSS Working
Group for discussion.
<h2 class="no-num no-toc" id=table-of-contents>Table of contents</h2>
<!--begin-toc-->
<ul class=toc>
<li><a href="#pseudo-elements"><span class=secno>1.
</span>Pseudo-elements</a>
<ul class=toc>
<li><a href="#first-line"><span class=secno>1.1. </span>The ::first-line
pseudo-element</a>
<ul class=toc>
<li><a href="#first-formatted-line"><span class=secno>1.1.1.
</span>First formatted line definition in CSS</a>
</ul>
<li><a href="#first-letter"><span class=secno>1.2. </span>The
::first-letter pseudo-element</a>
<ul class=toc>
<li><a href="#application-in-css"><span class=secno>1.2.1.
</span>Application in CSS</a>
</ul>
<li><a href="#gen-content"><span class=secno>1.3. </span>The ::before
and ::after pseudo-elements</a>
<ul class=toc>
<li><a href="#ordinal-before-and-after"><span class=secno>1.3.1.
</span>Multiple ::before and ::after pseudo-elements using
ordinals</a>
<li><a href="#the-nth-before-nth-after-nth-last-before"><span
class=secno>1.3.2. </span>The ::nth-before(), ::nth-after(),
::nth-last-before() and ::nth-last-after() pseudo-elements </a>
</ul>
</ul>
<li><a href="#additions-to-the-css-object-model"><span class=secno>2.
</span>Additions to the CSS Object Model</a>
<ul class=toc>
<li><a href="#interface-csspseudoelement"><span class=secno>2.1.
</span>Interface CSSPseudoElement</a>
<li><a href="#interface-csspseudoelementlist"><span class=secno>2.2.
</span>Interface CSSPseudoElementList</a>
<li><a href="#addition-to-the-window"><span class=secno>2.3.
</span>Addition to the window</a>
</ul>
<li class=no-num><a href="#ACKS">Acknowledgements</a>
<li class=no-num><a href="#references"> References</a>
<ul class=toc>
<li class=no-num><a href="#normative-references"> Normative
references</a>
<li class=no-num><a href="#other-references"> Other references</a>
</ul>
<li class=no-num><a href="#index"> Index</a>
</ul>
<!--end-toc-->
<h2 id=pseudo-elements><span class=secno>1. </span>Pseudo-elements</h2>
<p>Pseudo-elements create abstractions about the document tree beyond those
specified by the document language. For instance, document languages do
not offer mechanisms to access the first letter or first line of an
element's content. Pseudo-elements allow authors to refer to this
otherwise inaccessible information. Pseudo-elements may also provide
authors a way to refer to content that does not exist in the source
document (e.g., the <code>::before</code> and <code>::after</code>
pseudo-elements give access to generated content). <br>
<p>Pseudo-elements can be placed anywhere relatively to the element
creating them although the state of the art currently allows only the
following :
<ul>
<li>inside the element and before the element's content
<li>inside the element and after the element's content
<li>inside the element's contents at any depth
</ul>
<p>
<p>The notation for a pseudo-element is made of two colons
(<code>::</code>) followed by the name of the pseudo-element, possibly
immediately followed by a block of parenthesis containing comma-separated
arguments.<br>
<p>For compatibility with existing style sheets, user agents must also
accept the previous one-colon notation for pseudo-elements introduced in
CSS levels 1 <a href="#ref-CSS1" rel=biblioentry>[CSS1]<!--{{CSS1}}--></a>
and 2 <a href="#ref-CSS21" rel=biblioentry>[CSS21]<!--{{CSS21}}--></a>
(namely <code>:first-line</code>, <code>:first-letter</code>,
<code>:before</code> and <code>:after</code>). This compatibility is not
allowed for the new pseudo-elements introduced in this specification.
<h3 id=first-line><span class=secno>1.1. </span>The ::first-line
pseudo-element</h3>
<p>The <code>::first-line</code> pseudo-element describes the contents of
the first formatted line of an element.
<div class=example>
<p>CSS example:
<pre>p::first-line { text-transform: uppercase }</pre>
<p>The above rule means "change the letters of the first line of every
<code>p</code> element to uppercase".
<p>The selector <code>p::first-line</code> does not match any real
document element. It does match a pseudo-element that conforming user
agents will insert at the beginning of every <code>p</code> element.
</div>
<p>Note that the length of the first line depends on a number of factors,
including the width of the page, the font size, etc. Thus, an ordinary
HTML <a href="#ref-HTML5" rel=biblioentry>[HTML5]<!--{{HTML5}}--></a>
paragraph such as:
<pre>&lt;P&gt;This is a somewhat long HTMLparagraph that will be broken into severallines. The first line will be identifiedby a fictional tag sequence. The other lineswill be treated as ordinary lines in theparagraph.&lt;/P&gt;</pre>
<p>the lines of which happen to be broken as follows:
<pre>THIS IS A SOMEWHAT LONG HTML PARAGRAPH THATwill be broken into several lines. The firstline will be identified by a fictional tagsequence. The other lines will be treated asordinary lines in the paragraph.</pre>
<p>This paragraph might be "rewritten" by user agents to include the
<em>fictional tag sequence</em> for <code>::first-line</code>. This
fictional tag sequence helps to show how properties are inherited.
<pre>&lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTMLparagraph that <b>&lt;/P::first-line&gt;</b> will be broken into severallines. The first line will be identifiedby a fictional tag sequence. The other lineswill be treated as ordinary lines in theparagraph.&lt;/P&gt;</pre>
<p>If a pseudo-element breaks up a real element, the desired effect can
often be described by a fictional tag sequence that closes and then
re-opens the element. Thus, if we mark up the previous paragraph with a
<code>span</code> element:
<pre>&lt;P&gt;<b>&lt;SPAN class="test"&gt;</b> This is a somewhat long HTMLparagraph that will be broken into severallines.<b>&lt;/SPAN&gt;</b> The first line will be identifiedby a fictional tag sequence. The other lineswill be treated as ordinary lines in theparagraph.&lt;/P&gt;</pre>
<p>the user agent could simulate start and end tags for <code>span</code>
when inserting the fictional tag sequence for <code>::first-line</code>.
<pre>&lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> This is asomewhat long HTMLparagraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> bebroken into severallines.<b>&lt;/SPAN&gt;</b> The first line will be identifiedby a fictional tag sequence. The other lineswill be treated as ordinary lines in theparagraph.&lt;/P&gt;</pre>
<h4 id=first-formatted-line><span class=secno>1.1.1. </span><dfn
id=first-formatted-line0>First formatted line</dfn> definition in CSS</h4>
<p>In CSS, the <code>::first-line</code> pseudo-element can only have an
effect when attached to a block-like container such as a block box,
inline-block, table-caption, or table-cell.
<p>The first formatted line of an element may occur inside a block-level
descendant in the same flow (i.e., a block-level descendant that is not
out-of-flow due to floating or positioning). For example, the first line
of the <code>DIV</code> in <code>&lt;DIV&gt;&lt;P&gt;This
line...&lt;/P&gt;&lt;/DIV&gt;</code> is the first line of the
<code>P</code> (assuming that both <code>P</code> and <code>DIV</code> are
block-level).
<p>The first line of a table-cell or inline-block cannot be the first
formatted line of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
STYLE="display: inline-block"&gt;Hello&lt;BR&gt;Goodbye&lt;/P&gt;
etcetera&lt;/DIV&gt;</code> the first formatted line of the <code>DIV
</code> is not the line "Hello".
<p class=note><span class=note-prefix>Note </span> Note that the first
line of the <code>p</code> in this fragment:
<code>&lt;p&gt;&lt;br&gt;First...</code> doesn't contain any letters
(assuming the default style for <code>br</code>). The word "First" is not
on the first formatted line.
<p>A User-Agent should act as if the fictional start tags of the
<code>::first-line</code> pseudo-elements were nested just inside the
innermost enclosing block-level element. (Since CSS1 and CSS2 were silent
on this case, authors should not rely on this behavior.) For example, the
fictional tag sequence for
<pre>&lt;DIV&gt; &lt;P&gt;First paragraph&lt;/P&gt; &lt;P&gt;Second paragraph&lt;/P&gt;&lt;/DIV&gt;</pre>
<p>is
<pre>&lt;DIV&gt; &lt;P&gt;&lt;DIV::first-line&gt;&lt;P::first-line&gt;First paragraph&lt;/P::first-line&gt;&lt;/DIV::first-line&gt;&lt;/P&gt; &lt;P&gt;&lt;P::first-line&gt;Second paragraph&lt;/P::first-line&gt;&lt;/P&gt;&lt;/DIV&gt;</pre>
<p>The <code>::first-line</code> pseudo-element is similar to an
inline-level element, but with certain restrictions. The following CSS
properties apply to a <code>::first-line</code> pseudo-element: font
properties, color property, background properties, ‘<code
class=property>word-spacing</code>’, ‘<code
class=property>letter-spacing</code>’, ‘<code
class=property>text-decoration</code>’, ‘<code
class=property>vertical-align</code>’, ‘<code
class=property>text-transform</code>’, ‘<code
class=property>line-height</code>’. User-Agents may apply other
properties as well.
<p>During CSS inheritance, the portion of a child element that occurs on
the first line only inherits properties applicable to the
<code>::first-line</code> pseudo-element from the
<code>::first-line</code> pseudo-element. For all other properties
inheritence is from the non-pseudo-element parent of the first line pseudo
element. (The portion of a child element that does not occur on the first
line always inherits from the parent of that child.)
<h3 id=first-letter><span class=secno>1.2. </span>The ::first-letter
pseudo-element</h3>
<p>The <code>::first-letter</code> pseudo-element represents the first
letter of an element, if it is not preceded by any other content (such as
images or inline tables) on its line. The ::first-letter pseudo-element
may be used for "initial caps" and "drop caps", which are common
typographical effects.
<p>Punctuation (i.e, characters defined in Unicode in the "open" (Ps),
"close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po) punctuation
classes), that precedes or follows the first letter should be included. <a
href="#ref-UNICODE" rel=biblioentry>[UNICODE]<!--{{!UNICODE}}--></a>
<div class=figure>
<p><img alt="Quotes that precede the first letter should be included."
src="http://www.w3.org/TR/selectors/first-letter2.png">
</div>
<p>The <code>::first-letter</code> also applies if the first letter is in
fact a digit, e.g., the "6" in "67 million dollars is a lot of money."
<p class=note><span class=note-prefix>Note </span> In some cases the
<code>::first-letter</code> pseudo-element should include more than just
the first non-punctuation character on a line. For example, combining
characters must be kept with their base character. Additionally, some
languages may have specific rules about how to treat certain letter
combinations. The User-Agent definition of <code>::first-letter</code>
should include at least the default grapheme cluster as defined by UAX29
and may include more than that as appropriate. In Dutch, for example, if
the letter combination "ij" appears at the beginning of an element, both
letters should be considered within the <code>::first-letter</code>
pseudo-element. <a href="#ref-UAX29"
rel=biblioentry>[UAX29]<!--{{UAX29}}--></a>
<p>If the letters that would form the <code>::first-letter</code> are not
in the same element, such as "‘<code class=css>T" in
<code>&lt;p&gt;'&lt;em&gt;T...</code>, the User-Agent may create a
<code>::first-letter</code> pseudo-element from one of the elements, both
elements, or simply not create a pseudo-element.</code>
<p>Similarly, if the first letter(s) of the block are not at the start of
the line (for example due to bidirectional reordering), then the
User-Agent need not create the pseudo-element(s).
<div class=example>
<p>Example:
<p><a name=overlapping-example></a>The following CSS and HTML example
illustrates how overlapping pseudo-elements may interact. The first
letter of each P element will be green with a font size of ’24pt'. The
rest of the first formatted line will be ‘<code
class=property>blue</code>’ while the rest of the paragraph will be
‘<code class=property>red</code>’.
<pre>p { color: red; font-size: 12pt }p::first-letter { color: green; font-size: 200% }p::first-line { color: blue }&lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</pre>
<p>Assuming that a line break will occur before the word "ends", the <span
class=index-inst id=fictional-tag-sequence
title="fictional tag sequence">fictional tag sequence</span> for this
fragment might be:
<pre>&lt;P&gt;&lt;P::first-line&gt;&lt;P::first-letter&gt;S&lt;/P::first-letter&gt;ome text that&lt;/P::first-line&gt;ends up on two lines&lt;/P&gt;</pre>
<p>Note that the <code>::first-letter</code> element is inside the
<code>::first-line</code> element. Properties set on
<code>::first-line</code> are inherited by <code>::first-letter</code>,
but are overridden if the same property is set on
<code>::first-letter</code>.
</div>
<p>The first letter must occur on the <a href="#first-formatted-line">first
formatted line.</a> For example, in this HTML fragment:
<code>&lt;p&gt;&lt;br&gt;First...</code> the first line doesn't contain
any letters and <code>::first-letter</code> doesn't match anything
(assuming the default style for <code>br</code> in HTML 4). In particular,
it does not match the "F" of "First."
<h4 id=application-in-css><span class=secno>1.2.1. </span>Application in
CSS</h4>
<p>In CSS, the <code>::first-letter</code> pseudo-element applies to
block-like containers such as block, list-item, table-cell, table-caption,
and inline-block elements. <span class=note><strong>Note:</strong> A
future version of this specification may allow this pseudo-element to
apply to more display types.</span>
<p>The <code>::first-letter</code> pseudo-element can be used with all such
elements that contain text, or that have a descendant in the same flow
that contains text. A User-Agent should act as if the fictional start tag
of the ::first-letter pseudo-element is just before the first text of the
element, even if that first text is in a descendant.
<div class=example>
<p>Example:
<p>The fictional tag sequence for this HTML fragment:
<pre>&lt;div&gt;&lt;p&gt;The first text.</pre>
<p>is:
<pre>&lt;div&gt;&lt;p&gt;&lt;div::first-letter&gt;&lt;p::first-letter&gt;T&lt;/...&gt;&lt;/...&gt;he first text.</pre>
</div>
<p>In CSS the first letter of a table-cell or inline-block cannot be the
first letter of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
STYLE="display: inline-block"&gt;Hello&lt;BR&gt;Goodbye&lt;/P&gt;
etcetera&lt;/DIV&gt;</code> the first letter of the <code>DIV</code> is
not the letter "H". In fact, the <code>DIV</code> doesn't have a first
letter.
<p>If an element is a list item (‘<code class=css>display:
list-item</code>’), the <code>::first-letter</code> applies to the first
letter in the principal box after the marker. User-Agents may ignore
<code>::first-letter</code> on list items with ‘<code
class=css>list-style-position: inside</code>’. If an element has
<code>::before</code> or <code>::after</code> content, the
<code>::first-letter</code> applies to the first letter of the element
<em>including</em> that content.
<div class=example>
<p>Example:
<p>After the rule <code>p::before {content: "Note: "}</code>, the selector
<code>p::first-letter</code> matches the "N" of "Note".
</div>
<p>In CSS a ::first-line pseudo-element is similar to an inline-level
element if its ‘<code class=property>float</code>’ property is
‘<code class=property>none</code>’; otherwise, it is similar to a
floated element. The following properties that apply to
<code>::first-letter</code> pseudo-elements: font properties, ‘<code
class=property>text-decoration</code>’, ‘<code
class=property>text-transform</code>’, ‘<code
class=property>letter-spacing</code>’, ‘<code
class=property>word-spacing</code>’ (when appropriate), ‘<code
class=property>line-height</code>’, ‘<code
class=property>float</code>’, ‘<code
class=property>vertical-align</code>’ (only if ‘<code
class=property>float</code>’ is ‘<code class=property>none</code>’),
margin properties, padding properties, border properties, color property,
background properties. User-Agents may apply other properties as well. To
allow User-Agents to render a typographically correct drop cap or initial
cap, the User-Agent may choose a line-height, width and height based on
the shape of the letter, unlike for normal elements.
<div class=example>
<p>Example:
<p>This CSS and HTML example shows a possible rendering of an initial cap.
Note that the ‘<code class=property>line-height</code>’ that is
inherited by the <code>::first-letter</code> pseudo-element is 1.1, but
the User-Agent in this example has computed the height of the first
letter differently, so that it doesn't cause any unnecessary space
between the first two lines. Also note that the fictional start tag of
the first letter is inside the <span>span</span>, and thus the font
weight of the first letter is normal, not bold as the <span>span</span>:
<pre>p { line-height: 1.1 }p::first-letter { font-size: 3em; font-weight: normal }span { font-weight: bold }...&lt;p&gt;&lt;span&gt;Het hemelsche&lt;/span&gt; gerecht heeft zich ten lange lesten&lt;br&gt;Erbarremt over my en mijn benaeuwde vesten&lt;br&gt;En arme burgery, en op mijn volcx gebed&lt;br&gt;En dagelix geschrey de bange stad ontzet.</pre>
<div class=figure>
<p><img alt="Image illustrating the ::first-letter pseudo-element"
src="http://www.w3.org/TR/selectors/initial-cap.png">
</div>
</div>
<div class=example>
<p>The following CSS will make a drop cap initial letter span about two
lines:
<pre>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"&gt;&lt;HTML&gt; &lt;HEAD&gt; &lt;TITLE&gt;Drop cap initial letter&lt;/TITLE&gt; &lt;STYLE type="text/css"&gt; P { font-size: 12pt; line-height: 1.2 } P::first-letter { font-size: 200%; font-weight: bold; float: left } SPAN { text-transform: uppercase } &lt;/STYLE&gt; &lt;/HEAD&gt; &lt;BODY&gt; &lt;P&gt;&lt;SPAN&gt;The first&lt;/SPAN&gt; few words of an article in The Economist.&lt;/P&gt; &lt;/BODY&gt;&lt;/HTML&gt;</pre>
<p>This example might be formatted as follows:
<div class=figure>
<p><img
alt="Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements"
src="http://www.w3.org/TR/selectors/first-letter.png">
</div>
<p>The <span class=index-inst id=fictional-tag-sequence0
title="fictional tag sequence">fictional tag sequence</span> is:
<pre>&lt;P&gt;&lt;SPAN&gt;&lt;P::first-letter&gt;T&lt;/P::first-letter&gt;he first&lt;/SPAN&gt;few words of an article in the Economist.&lt;/P&gt;</pre>
<p>Note that the <code>::first-letter</code> pseudo-element tags abut the
content (i.e., the initial character), while the ::first-line
pseudo-element start tag is inserted right after the start tag of the
block element.
</div>
<p>In order to achieve traditional drop caps formatting, user agents may
approximate font sizes, for example to align baselines. Also, the glyph
outline may be taken into account when formatting.
<h3 id=gen-content><span class=secno>1.3. </span>The ::before and ::after
pseudo-elements</h3>
<p>The <code>::before</code> and <code>::after</code> pseudo-elements can
be used to describe generated content before or after an element's
content. They are explained in CSS 2.1 <a href="#ref-CSS21"
rel=biblioentry>[CSS21]<!--{{!CSS21}}--></a>.
<p>When the <code>::first-letter</code> and <code>::first-line</code>
pseudo-elements are applied to an element having content generated using
<code>::before</code> or <code>::after</code> pseudo-elements, they apply
to the first letter or line of the element including the generated
content.
<p>
<p>A <a href="http://www.w3.org/TR/CSS2/syndata.html#rule-sets">CSS
rule</a> using <code>::before</code> or <code>::after</code> creates a
pseudo-element only if the <a
href="http://www.w3.org/TR/CSS2/cascade.html#computed-value">computed
values</a> of the ‘<code class=css><a
href="http://www.w3.org/TR/CSS2/generate.html#content">content</a></code>’
property and the ‘<code class=css><a
href="http://www.w3.org/TR/css3-regions/#the-flow-from-property"><span
class=property>flow-from</span></a></code>’ property <a
href="#ref-CSS3-REGIONS"
rel=biblioentry>[CSS3-REGIONS]<!--{{CSS3-REGIONS}}--></a> are not both
‘<code class=property>none</code>’.
<div class=issue>
<p>There are a11y issues with ::before and ::after pseudo-elements and
generated content that were raised in the discussion of the following
sections.
</div>
<h4 id=ordinal-before-and-after><span class=secno>1.3.1. </span>Multiple
::before and ::after pseudo-elements using ordinals</h4>
<p>More than one ::before or ::after pseudo-element can be created or
accessed by adding a positive integer called the <strong>ordinal</strong>
in parentheses.
<div class=issue>
<p>Using ordinals solves issues of insertion order, but does not provide a
meaningful name for a particular ::before or ::after element. A named
psuedo-element could provide better meaning, at the expense of ordering.
</div>
<p>The ordinal 1 has a special meaning:<code> </code>
<ul>
<li><code>::before(1)</code> and <a
href="http://www.w3.org/TR/CSS2/generate.html#before-after-content"><code>::before</code></a>
are strictly equivalent
<li><code>::after(1)</code> and <a
href="http://www.w3.org/TR/CSS2/generate.html#before-after-content"><code>::after</code></a>
are also strictly equivalent.
</ul>
<p><code>::before()</code> and <code>::after()</code> pseudo-elements are
ordered by increasing ordinal from the nearest element's contents
boundaries. For example:
<div class=example>
<p>Let's take the example of a div element creating two ::before
pseudo-elements at ordinals 1 and 4, and three ::after pseudo-elements at
ordinals 1, 5 and 8. The rules would look like this:
<pre>div::before(1) {}div::before(4) {}div::after(1) {}div::after(5) {}div::after(8) {} </pre>
The pseudo-elements and the contents of the element are then ordered in
this way:
<pre>-- element's boundary -- [ ordinal 4, before ] [ ::before, ordinal 1, before ] -- element's contents boundary -- -- element's contents boundary -- [ ::after, ordinal 1, after ] [ ordinal 5, after ] [ ordinal 8, after ]-- element's boundary -- </pre>
</div>
<div class=example>
<p>One use of multiple <code>::before</code> and <code>::after</code>
elements is to mix generated content with graphical effects.
Pseudo-elements are used in quotes both for adding quotation marks in
generated content OR for drawing a speech bubble arrow. With multiple
<code>::before</code> and <code>::after</code> elements you can get both.
<p>This effect: <img src="images/quote-arrow.png"> can be achieved with
this code:
<pre>div::before { content: "“";}div::after { content: "”";}div::after(2) { content: "."; position: absolute; bottom: -10px; right: 20%; border-left: 10px solid transparent; border-right: 10px solid transparent; border-top: 10px solid #111; width: 0; height: 0;}div{ position: relative; float: left; background: #111; padding: 1em; border-radius: 1em; color: white;}&lt;div&gt;I'm talking about CSS Pseudo-elements.&lt;/div&gt;</pre>
<p>And if you have a single quote from multiple speakers, more arrows can
be added by adding more <code>::after()</code> pseudo-elements: <img
src="images/multiple-arrows.png">
<p>In general, there's no longer a limitation to two instances for
whatever a <code>::before</code> or <code>::after</code> pseudo-element
can be used (generated content, graphic effects, clearfix, etc.).
</div>
<div class=example>
<p>Another use of multiple <code>::before</code> and <code>::after</code>
pseudo-elements is to change the style of pieces of generated content. If
a citation appended to a quote should be in a different font than the
quotation mark, two ::after() pseudo-elements can be used.</p>
<img src="images/multiple-styles.png">
<p 8231 re>blockquote::before { content: "“";}blockquote::after { content: "”";}blockquote::after(2) { content: " - " attr(data-author); font: normal 0.8em sans-serif;}&lt;blockquote data-author="Mark Twain"&gt;The funniest things are the forbidden.&lt;/blockquote&gt;</pre>
</div>
<div class=issue>
<p>An issue has been raised on the previous example, questioning whether
using attr(data-author) in this way is appropriate for use in an example.
</div>
<div class=example>
<p>A use for ordinals is to allow muliple stylesheets to add their own
<code>::before</code> and <code>::after</code> pseudo-elements and
coordinate insertion positions.
<p>If one stylesheet uses a single <code>::before(10) {}</code> rule, then
another stylesheet gets the option to
<ul>
<li>Add to or redefine that rule
<li>Add an additional pseudo-element before that one with
<code>::before(5) {}</code>
<li>Add an additional pseudo-element after that one with
<code>::before(15) {}</code>
</ul>
</div>
<div class=example>
<p>Pseudo-elements can be used to generate boxes in CSS for a <a
href="http://dev.w3.org/csswg/css3-regions/#region-chain">region
chain</a>. Allowing more than two such boxes per element could allow the
main CSS Regions <a
href="http://dev.w3.org/csswg/css3-regions/#named-flows-and-regions">example</a>
to be <a
href="http://dev.w3.org/csswg/css3-regions/#intro-example-code">written</a>
without empty divs for the regions in the markup.
<p>Region chains with a fixed number of regions (usually with an
auto-height region at the end of the chain) can be defined entirely in
CSS using multiple pseudo-elements.
<pre>&lt;style&gt; #grid { width: 80vw; height: 60vw; grid-template: "aaa.d" "....d" "bbb.d" "....d" "ccc.d"; grid-rows: 52% 4% 20% 4% 20%; grid-columns: 30% 5% 30% 5% 30%; } #grid::before(2) { grid-cell: a; } #grid::before { grid-cell: b; } #boxA { grid-cell: c; } #grid::after { grid-cell: d; } #body::after { width: 80vw; } #grid::before { column-count: 2; } article { flow-into: article_flow; } #grid::before(2), #grid::before, #grid::after, #body::after { flow-from: article_flow; }&lt;/style&gt;&lt;article&gt; &lt;h1&gt;Introduction&lt;/h1&gt; &lt;p&gt;This is an example ...&lt;/p&gt; &lt;h2&gt;More Details&lt;/h2&gt; &lt;p&gt;This illustrates ...&lt;/p&gt; &lt;p&gt;Then, the example ...&lt;/p&gt; &lt;p&gt;Finally, this ...&lt;/p&gt;&lt;/article&gt;&lt;div id="grid"&gt; &lt;div id="boxA"&gt;&lt;/div&gt;&lt;/div&gt;</pre>
</div>
<div class=issue>
<p>Several choices of syntax for declaring multiple ::before and ::after
pseudo-elements have been considered.
<ul>
<li>Brackets - <code>::before[2]</code>
<ul></ul>
<p>Benefits
<li>Can reserve bracket syntax for ordinals
<li>Could be appended to an otherwise-parenthesized pseudo
<code>::hypothetical(args)[ordinal]</code>
</ul>
<ul></ul>
<p>Drawbacks
<ul>
<li>Looks too much like attribute selectors
</ul>
<ul>
<li>Add a generic ordinal syntax - ::pseudo(before, 2)
<ul></ul>
<p>Benefits
<li>Easily extensible to addition pseudos
<li>Parallel to ::nth-pseudo() syntax
</ul>
<ul></ul>
<p>Drawbacks
<ul>
<li>Only used for ::before and ::after so far
<li>More to type
</ul>
<ul>
<li>Parentheses - <code>::before(2)</code>
<ul></ul>
<p>Benefits
<li>No attribute selector confusion
<li>Previous attempts have used this syntax
</ul>
<ul></ul>
<p>Drawbacks
<ul>
<li>Perhaps harder to distinguish ordinal from index?
</ul>
</div>
<div class=issue>
<p>We arbitrarily chose the order here. Pseudo-elements could be ordered
differently, for example as in:<br>
<pre>-- element's boundary -- [ ::before, ordinal 1, before ] [ ordinal 4, before ] -- element's contents boundary -- -- element's contents boundary -- [ ordinal 8, after ] [ ordinal 5, after ] [ ::after, ordinal 1, after ]-- element's boundary --</pre>
<p>or
<pre>-- element's boundary -- [ ::before, ordinal 1, before ] [ ordinal 4, before ] -- element's contents boundary -- -- element's contents boundary -- [ ::after, ordinal 1, after ] [ ordinal 5, after ] [ ordinal 8, after ]-- element's boundary --</pre>
<p>We expect to resolve this issue with the CSS Working Group.
</div>
<h4 id=the-nth-before-nth-after-nth-last-before><span class=secno>1.3.2.
</span>The ::nth-before(), ::nth-after(), ::nth-last-before() and
::nth-last-after() pseudo-elements</h4>
<p>The new <code>::nth-before()</code>, <code>::nth-after()</code>,
<code>::nth-last-before()</code> and <code>::nth-last-after()</code>
pseudo-elements select ::before and ::after pseudo-elements based on
indices, not ordinals. They all take a single mandatory argument:
<ol>
<li>a mandatory <strong>index</strong> in the form of <a
href="http://www.w3.org/TR/css3-selectors/#nth-child-pseudo">an
<code>an+b</code> syntax or the <code>odd</code> or <code>even</code>
keywords</a>
</ol>
<div class=issue>
<p>Extensions to selector syntax may allow pseudo-classes after a
pseudo-element. In that case, the syntax in this section could change to
something like <code>::before:nth()</code>, <code>::after:nth()</code>,
<code>::before:nth-last()</code> and <code>::after:nth-last()</code>.
</div>
<div class=issue>
<p>Is ::nth-before(n) to access all ::before pseudo-elements enough of an
override mechanism?
</div>
<div class=example>
<p>Let's reuse the example in Example 8 above and let's show the indices:
<pre>-- element's boundary -- [ ordinal 4, before, nth index 2, last-nth index 1 ] [ ::before, ordinal 1, before, nth index 1, last-nth index 2 ] -- element's contents boundary -- -- element's contents boundary -- [ ::after, ordinal 1, after, nth index 1, last-nth index 3 ] [ ordinal 5, after, nth index 2, last-nth index 2 ] [ ordinal 8, after, nth index 3, last-nth index 1 ]-- element's boundary -- </pre>
</div>
<p><code>::nth-*()</code> syntax cannot create a new pseudo-element and the
‘<code class=property>content</code>’ and ‘<code
class=property>flow-from</code>’properties do not apply to them.
<p>They are allowed as the second parameter of
<code>ViewCSS.getComputedStyle()</code> if and only if the index parameter
can select only one pseudo-element: for instance <code>12</code> or
<code>0n+5</code>.
<h2 id=additions-to-the-css-object-model><span class=secno>2.
</span>Additions to the CSS Object Model</h2>
<p>Pseudo-elements should be reachable by script, stylable from script, and
available as event targets.
<p class=note><span class=note-prefix>Note </span>We may extend this
section in the future to allow creation of pseudo-elements from script.
<h3 id=interface-csspseudoelement><span class=secno>2.1. </span>Interface
CSSPseudoElement</h3>
<p>The <code>CSSPseudoElement</code> interface allows pseudo-elements to be
styleable from script and makes them event targets.
<div class=issue>
<p>The approach in this draft is to start with a bare minimum for the
CSSPseudoElement interface and build up from there. Another more radical
approach could take everything that's common between a pseudo-element and
a node and create a new base class for both Node and CSSPseudoElement.
</div>
<pre
class=idl>interface CSSPseudoElement {<br> readonly attribute unsigned long <a
href="#dom-csspseudochild-ordinal">ordinal</a>;<br> // the ordinal of a column is its index<br> readonly attribute DOMString <a
href="#dom-csspseudochild-type">type</a>;<br> readonly attribute <a
href="http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration">CSSStyleDeclaration</a> <a
href="#dom-csspseudochild-style">style</a>;<br>};<br><br>CSSPseudoElement implements EventTarget;<br></pre>
<p><a name=dom-csspseudochild-ordinal></a>The
<code><strong><em>ordinal</em></strong></code> attribute represents the
ordinal of the pseudo-element for the object's type. It is a strictly
positive integer. The value <code>1</code> for the <code>before</code> 
(or <code>after</code>, <code>letter</code> and <code>line</code>) types
represents the <code>::before</code> (or <code>::after</code>,
<code>::first-letter</code> and <code>::first-line</code>)
pseudo-elements.
<p><a name=dom-csspseudochild-type></a>The
<code><strong><em>type</em></strong></code> attribute is a string
representing the type of the pseudo-element. This can be one of the
following values:
<dl>
<dt>‘before’
<dd>The pseudo-element was created before the element's contents
<dt>‘after’
<dd>The pseudo-element was created after the element's contents
<dt>‘letter’
<dd>The pseudo-element is the first letter of the element; the only valid
ordinal is 1.
<dt>‘line’
<dd>The pseudo-element is the first line of the element; the only valid
ordinal is 1.
<dt>‘column’
<dd>The pseudo-element is a column created by the element through the CSS
Multi-column Layout Module. In that case its
<code><strong><em>ordinal</em></strong></code> is the index of column in
the collection of columns created by the element.
</dl>
<p><a name=dom-csspseudochild-style></a>The
<code><strong><em>style</em></strong></code> attribute is a
<code>CSSStyleDeclaration</code> <a href="#ref-CSSOM"
rel=biblioentry>[CSSOM]<!--{{!CSSOM}}--></a> allowing to set directly
style information (inline styles) onto the pseudo-element. Inline styles
on a <code>CSSPseudoElement</code> have precedence over all style rules
styling that pseudo-element.
<p>The <a
href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget"><code>EventTarget</code></a>
interface <a href="#ref-DOM-LEVEL-2-EVENTS"
rel=biblioentry>[DOM-LEVEL-2-EVENTS]<!--{{!DOM-LEVEL-2-EVENTS}}--></a>
must be implemented by all instances of <code>CSSPseudoElement</code> in
an in implementation which supports the current specification.
<h3 id=interface-csspseudoelementlist><span class=secno>2.2.
</span>Interface CSSPseudoElemen C0A8 tList</h3>
<p>The <code>CSSPseudoElementList</code> represents an ordered collection
of <code> CSSPseudoElement</code> instances.
<pre
class=idl>interface CSSPseudoElementList {<br> readonly attribute unsigned long <a
href="#dom-csspseudochildlist-length">length</a>;<br> CSSPseudoElement <a
href="#dom-csspseudochildlist-item">item</a>(unsigned long index);<br> CSSPseudoElement <a
href="#dom-csspseudochildlist-getbyordinalandtype">getByOrdinalAndType</a>(unsigned long ordinal,<br> DOMString type);<br> // replies null if no pseudo-element does not exist for<br> // the requested ordinal and type<br>};</pre>
<p><a name=dom-csspseudochildlist-length></a>The
<code><strong><em>length</em></strong></code> attribute represents the
number of <code>CSSPseudoElement</code> in the collection or zero if it is
empty.
<p><a name=dom-csspseudochildlist-item></a>The method
<code><strong><em>item()</em></strong></code> is used to retrieve a
<code>CSSPseudo</code><code>Element</code> by index. It takes one
parameter being the requested index into the collection. Its return value
is the <code>CSSPseudo</code><code>Element</code> at the requested index
in the collection or null if that is not a valid index.
<p><a name=dom-csspseudochildlist-getbyordinalandtype></a>The method
<code><strong><em>getByOrdinalAndType()</em></strong></code> is used to
retrieve a <code>CSSPseudo</code><code>Element</code> by its ordinal and
type. It takes two parameters: first, the requested ordinal; second a
type. Its return value is the <code>CSSPseudo</code><code>Element</code>
at the requested index in the collection or null if there is no
<code>CSSPseudo</code><code>Element</code> in the collection for that
index and type.
<h3 id=addition-to-the-window><span class=secno>2.3. </span>Addition to the
window</h3>
<p>A new method is added to the <code>Window</code> interface to retrieve
pseudo-elements created by a given element for a given type:
<pre class=idl>partial interface Window {<br> CSSPseudoElementList <a
href="#dom-window-getpseudochildren">getPseudoElements</a>(Element elt,<br> DOMString type);<br>};</pre>
<p><a name=dom-window-getpseudochildren></a>The method
<code>getPseudoElements()</code> is used to retrieve all
<code>CSSPseudoElement</code> instances created by the element
<code>elt</code> for the type <code>type</code>. Its return value is a
<code>CSSPseudoElementList</code>, potentially empty if no pseudo-element
exists for the given element and the given type.
<h2 class=no-num id=ACKS>Acknowledgements</h2>
<p>The editors would like to thank the following individuals for their
contributions, either during the conception of the specification or during
its development and specification review process:
<blockquote>
<p>Tab Atkins, Razvan Caliman, Chris Coyier, Anders Grimsrud, Vincent
Hardy and the CSS Working Group members.
</blockquote>
<h2 class=no-num id=references> References</h2>
<h3 class=no-num id=normative-references> Normative references</h3>
<!--begin-normative-->
<!-- Sorted by label -->
<dl class=bibliography>
<dd style="display: none"><!-- keeps the doc valid if the DL is empty -->
<!---->
<dt id=ref-CSS21>[CSS21]
<dd>Bert Bos; et al. <a
href="http://www.w3.org/TR/2011/REC-CSS2-20110607"><cite>Cascading Style
Sheets Level 2 Revision 1 (CSS 2.1) Specification.</cite></a> 7 June
2011. W3C Recommendation. URL: <a
href="http://www.w3.org/TR/2011/REC-CSS2-20110607">http://www.w3.org/TR/2011/REC-CSS2-20110607</a>
</dd>
<!---->
<dt id=ref-CSSOM>[CSSOM]
<dd>Simon Pieters; Glenn Adams. <a
href="http://www.w3.org/TR/2013/WD-cssom-20131205/"><cite>CSS Object
Model (CSSOM).</cite></a> 5 December 2013. W3C Working Draft. (Work in
progress.) URL: <a
href="http://www.w3.org/TR/2013/WD-cssom-20131205/">http://www.w3.org/TR/2013/WD-cssom-20131205/</a>
</dd>
<!---->
<dt id=ref-DOM-LEVEL-2-EVENTS>[DOM-LEVEL-2-EVENTS]
<dd>Tom Pixley. <a
href="http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113"><cite>Document
Object Model (DOM) Level 2 Events Specification.</cite></a> 13 November
2000. W3C Recommendation. URL: <a
href="http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113">http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113</a>
</dd>
<!---->
<dt id=ref-UNICODE>[UNICODE]
<dd>The Unicode Consortium. <a
href="http://www.unicode.org/standard/versions/enumeratedversions.html"><cite>The
Unicode Standard.</cite></a> 2012. Defined by: The Unicode Standard,
Version 6.2.0 (Mountain View, CA: The Unicode Consortium, 2012. ISBN
978-1-936213-07-8), as updated from time to time by the publication of
new versions URL: <a
href="http://www.unicode.org/standard/versions/enumeratedversions.html">http://www.unicode.org/standard/versions/enumeratedversions.html</a>
</dd>
<!---->
</dl>
<!--end-normative-->
<h3 class=no-num id=other-references> Other references</h3>
<!--begin-informative-->
<!-- Sorted by label -->
<dl class=bibliography>
<dd style="display: none"><!-- keeps the doc valid if the DL is empty -->
<!---->
<dt id=ref-CSS1>[CSS1]
<dd>Håkon Wium Lie; Bert Bos. <a
href="http://www.w3.org/TR/2008/REC-CSS1-20080411"><cite>Cascading Style
Sheets (CSS1) Level 1 Specification.</cite></a> 11 April 2008. W3C
Recommendation. URL: <a
href="http://www.w3.org/TR/2008/REC-CSS1-20080411">http://www.w3.org/TR/2008/REC-CSS1-20080411</a>
</dd>
<!---->
<dt id=ref-CSS3-REGIONS>[CSS3-REGIONS]
<dd>Vincent Hardy; Rossen Atanassov; Alan Stearns. <a
href="http://www.w3.org/TR/2013/WD-css3-regions-20130528/"><cite>CSS
Regions Module Level 1.</cite></a> 28 May 2013. W3C Working Draft. (Work