-
Notifications
You must be signed in to change notification settings - Fork 709
/
Copy pathOverview.src.html
944 lines (879 loc) · 42.3 KB
/
Overview.src.html
1
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"> <head profile="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> <script defer="defer" src="css-pseudochildren_files/annotate.js" type="text/javascript"></script> <link rel="stylesheet" type="text/css" href="../shared/style/default.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 rel="stylesheet" type="text/css" href="http://www.w3.org/StyleSheets/TR/w3c-unofficial.css"> </head> <body class="example"><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: </dt> <dd>TBD </dd> <dt>Latest version: </dt> <dd>27 August 2012 </dd> <dt>Previous version: </dt> <dd>TBD </dd> <dt>Editors: </dt> <dd class="vcard"><span class="fn">Daniel Glazman</span>, on behalf of <span class="org">Adobe Systems, Inc.</span></dd> <dd class="vcard"><span class="fn">Alan Stearns</span>, <span class="org">Adobe Systems, Inc.</span>, <span class= "email">stearns@adobe.com</span></dd> <dt>Issues List: </dt> <dd>TBD </dd> <dt>Discussion: </dt> <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>" </dd> </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.</p> <hr title="Separator for header"> </div> <details class=obsolete 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> </p> </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.</p> <h2 class="no-num no-toc" id="table-of-contents">Table of contents</h2> <!--begin-toc--><!--end-toc--> <h2 id="pseudo-elements">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> <p>Pseudo-elements can be placed anywhere relatively to the element creating them although the state of the art currently allows only the following :</p> <ul> <li>inside the element and before the element's content</li> <li>inside the element and after the element's content</li> <li>inside the element's contents at any depth</li> </ul> <p></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> <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 [[CSS1]] and 2 [[CSS21]] (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. </p> <h3 id="first-line">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. </p> <div class="example"> <p>CSS example:</p> <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> <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.</p> </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 [[HTML5]] paragraph such as: </p> <pre><P>This is a somewhat long HTML paragraph that will be broken into several lines. The first line will be identifiedby a fictional tag sequence. The other lines will be treated as ordinary lines in the paragraph.</P></pre> <p>the lines of which happen to be broken as follows: </p> <pre>THIS IS A SOMEWHAT LONG HTML PARAGRAPH THATwill be broken into several lines. The firstline will be identified by a fictional tag sequence. The other lines will be treated as ordinary 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. </p> <pre><P><b><P::first-line></b> This is a somewhat long HTML paragraph that <b></P::first-line></b> will be broken into severallines. The first line will be identified by a fictional tag sequence. The other lines will be treated as ordinary lines in the paragraph.</P></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: </p> <pre><P><b><SPAN class="test"></b> This is a somewhat long HTMLparagraph that will be broken into severallines.<b></SPAN></b> The first line will be identifiedby a fictional tag sequence. The other lines will be treated as ordinary lines in the paragraph.</P></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>. </p> <pre><P><P::first-line><b><SPAN class="test"></b> This is asomewhat long HTMLparagraph that will <b></SPAN></b></P::first-line><b><SPAN class="test"></b> bebroken into severallines.<b></SPAN></b> The first line will be identifiedby a fictional tag sequence. The other lineswill be treated as ordinary lines in the paragraph.</P></pre> <h4 id="first-formatted-line"><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> <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><DIV><P>This line...</P></DIV></code> is the first line of the <code>P</code> (assuming that both <code>P</code> and <code>DIV</code> are block-level). </p> <p>The first line of a table-cell or inline-block cannot be the first formatted line of an ancestor element. Thus, in <code><DIV><P STYLE="display: inline-block">Hello<BR>Goodbye</P> etcetera</DIV></code> the first formatted line of the <code>DIV </code> is not the line "Hello". </p> <p class="note"><span class="note-prefix">Note </span> Note that the first line of the <code>p</code> in this fragment: <code><p><br>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> <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 </p> <pre><DIV> <P>First paragraph</P> <P>Second paragraph</P></DIV></pre> <p>is </p> <pre><DIV> <P><DIV::first-line><P::first-line>First paragraph</P::first-line></DIV::first-line></P> <P><P::first-line>Second paragraph</P::first-line></P></DIV></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> <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.) </p> <h3 id="first-letter">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> <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. [[!UNICODE]] </p> <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"></p> </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> <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. [[UAX29]] </p> <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><p>'<em>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> <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). </p> <div class="example"> <p>Example:</p> <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>’.</p> <pre>p { color: red; font-size: 12pt }p::first-letter { color: green; font-size: 200% }p::first-line { color: blue }<P>Some text that ends up on two lines</P></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:</p> <pre><P><P::first-line><P::first-letter> S </P::first-letter>ome text that </P::first-line> ends up on two lines </P></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>.</p> </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><p><br>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." </p> <h4 id="application-in-css">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> <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. </p> <div class="example"> <p>Example:</p> <p>The fictional tag sequence for this HTML fragment: </p> <pre><div><p>The first text.</pre> <p>is: </p> <pre><div><p><div::first-letter><p::first-letter>T</...></...>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><DIV><P STYLE="display: inline-block">Hello<BR>Goodbye</P> etcetera</DIV></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> <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. </p> <div class="example"> <p>Example:</p> <p>After the rule <code>p::before {content: "Note: "}</code>, the selector <code>p::first-letter</code> matches the "N" of "Note".</p> </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. </p> <div class="example"> <p>Example:</p> <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>: </p> <pre>p { line-height: 1.1 }p::first-letter { font-size: 3em; font-weight: normal }span { font-weight: bold }...<p><span>Het hemelsche</span> gerecht heeft zich ten lange lesten<br>Erbarremt over my en mijn benaeuwde vesten<br>En arme burgery, en op mijn volcx gebed<br>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"> </p> </div> </div> <div class="example"> <p>The following CSS will make a drop cap initial letter span about two lines:</p> <pre><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"><HTML> <HEAD> <TITLE>Drop cap initial letter</TITLE> <STYLE type="text/css"> P { font-size: 12pt; line-height: 1.2 } P::first-letter { font-size: 200%; font-weight: bold; float: left } SPAN { text-transform: uppercase } </STYLE> </HEAD> <BODY> <P><SPAN>The first</SPAN> few words of an article in The Economist.</P> </BODY></HTML></pre> <p>This example might be formatted as follows:</p> <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"></p> </div> <p>The <span class="index-inst" id="fictional-tag-sequence0" title="fictional tag sequence">fictional tag sequence</span> is:</p> <pre><P><SPAN><P::first-letter>T</P::first-letter>he first</SPAN> few words of an article in the Economist.</P></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.</p> </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. </p> <h3 id="gen-content">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 [[!CSS21]]. </p> <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></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 '<a href="http://www.w3.org/TR/CSS2/generate.html#content">content</a>' property and the '<a href="http://www.w3.org/TR/css3-regions/#the-flow-from-property"><span class="property">flow-from</span></a>' property [[CSS3-REGIONS]] are not both 'none'.</p> <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.</p> </div> <h4 id="ordinal-before-and-after">Multiple ::before and ::after pseudo-elements using ordinals</span></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.</p> <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.</p> </div> <p>The ordinal 1 has a special meaning:<code> </code></p> <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> <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.</li> </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:</p> <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:</p> <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> <p>This effect: <img src="images/quote-arrow.png"> can be achieved with this code: </p><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;} <div>I'm talking about CSS Pseudo-elements.</div></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> <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()</code> pseudo-elements can be used.</p> <img src="images/multiple-styles.png"><pre>blockquote::before { content: "“";} blockquote::after { content: "”";} blockquote::after(2) { content: " - " attr(data-author); font: normal 0.8em sans-serif;} <blockquote data-author="Mark Twain">The funniest things are the forbidden.</blockquote></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.</p> </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> <p>If one stylesheet uses a single <code>::before(10) {}</code> rule, then another stylesheet gets the option to</p> <ul> <li>Add to or redefine that rule</li> <li>Add an additional pseudo-element before that one with <code>::before(5) {}</code></li> <li>Add an additional pseudo-element after that one with <code>::before(15) {}</code></li> </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> <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.</p><pre><style> #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; } </style><article> <h1>Introduction</h1> <p>This is an example ...</p> <h2>More Details</h2> <p>This illustrates ...</p> <p>Then, the example ...</p> <p>Finally, this ...</p></article><div id="grid"> <div id="boxA"></div></div></pre> </div> <div class="issue"> <p>Several choices of syntax for declaring multiple ::before and ::after pseudo-elements have been considered.</p> <ul> <li>Brackets - <code>::before[2]</code> <ul>Benefits <li>Can reserve bracket syntax for ordinals</li> <li>Could be appended to an otherwise-parenthesized pseudo <code>::hypothetical(args)[ordinal]</code></li> </ul> <ul>Drawbacks <li>Looks too much like attribute selectors</li> </ul> </li> <li>Add a generic ordinal syntax - ::pseudo(before, 2) <ul>Benefits <li>Easily extensible to addition pseudos</li> <li>Parallel to ::nth-pseudo() syntax</li> </ul> <ul>Drawbacks <li>Only used for ::before and ::after so far</li> <li>More to type</li> </ul> </li> <li>Parentheses - <code>::before(2)</code> <ul>Benefits <li>No attribute selector confusion</li> <li>Previous attempts have used this syntax</li> </ul> <ul>Drawbacks <li>Perhaps harder to distinguish ordinal from index?</li> </ul> </li> </ul> </div> <div class="issue"> <p>We arbitrarily chose the order here. Pseudo-elements could be ordered differently, for example as in:<br> </p><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</p><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.</p> </div> <h4>The ::nth-before(), ::nth-after(), ::nth-last-before() and ::nth-last-after() pseudo-elements</h3> <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:</p> <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></li> </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>.</p> </div> <div class="issue"> <p>Is ::nth-before(n) to access all ::before pseudo-elements enough of an override mechanism?</p> </div> <div class="example"> <p>Let's reuse the example in Example 8 above and let's show the indices:</p> <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 'content' and 'flow-from'properties do not apply to them.</p> <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>.</p> <h2>Additions to the CSS Object Model</h2> <p>Pseudo-elements should be reachable by script, stylable from script, and available as event targets.</p> <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.</p> <h3>Interface CSSPseudoElement</h3> <p>The <code>CSSPseudoElement</code> interface allows pseudo-elements to be styleable from script and makes them event targets.</p> <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.</p> </div> <pre class="idl">interface CSSPseudoElement {<br> readonly attribute unsigned long <ahref="#dom-csspseudochild-ordinal">ordinal</a>;<br> // the ordinal of a column is its index<br> readonly attribute DOMString <ahref="#dom-csspseudochild-type">type</a>;<br> readonly attribute <ahref="http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration">CSSStyleDeclaration</a> <ahref="#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> <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:</p> <dl> <dt>‘before’</dt> <dd>The pseudo-element was created before the element's contents</dd> <dt>‘after’</dt> <dd>The pseudo-element was created after the element's contents</dd> <dt>‘letter’</dt> <dd>The pseudo-element is the first letter of the element; the only valid ordinal is 1.</dd> <dt>‘line’</dt> <dd>The pseudo-element is the first line of the element; the only valid ordinal is 1.</dd> <dt>‘column’</dt> <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.</dd> </dl> <p><a name="dom-csspseudochild-style"></a>The <code><strong><em>style</em></strong></code> attribute is a <code>CSSStyleDeclaration</code> [[!CSSOM]] 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> <p>The <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget"><code>EventTarget</code></a> interface [[!DOM-LEVEL-2-EVENTS]] must be implemented by all instances of <code>CSSPseudoElement</code> in an in implementation which supports the current specification.</p> <h3>Interface CSSPseudoElementList</h3> <p>The <code>CSSPseudoElementList</code> represents an ordered collection of <code> CSSPseudoElement</code> instances.</p> <pre class="idl">interface CSSPseudoElementList {<br> readonly attribute unsigned long <ahref="#dom-csspseudochildlist-length">length</a>;<br> CSSPseudoElement <ahref="#dom-csspseudochildlist-item">item</a>(unsigned long index);<br> CSSPseudoElement <ahref="#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> <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> <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.</p> <h3>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:</p> <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.</p> <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: </p> <blockquote>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><!--normative--><h3 class="no-num" id="other-references">Other references</h3><!--informative--><h2 class="no-num" id="index">Index</h2><!--index--><!--<h2 class="no-num" id="property-index">Property index</h2>--><!-- properties --> </body></html><!-- Keep this comment at the end of the fileLocal variables:mode: sgmlsgml-declaration:"~/SGML/HTML4.decl"sgml-default-doctype-name:"html"sgml-minimize-attributes:tsgml-nofill-elements:("pre" "style" "br")sgml-live-element-indicator:tsgml-omittag:nilsgml-shorttag:nilsgml-namecase-general:tsgml-general-insert-case:lowersgml-always-quote-attributes:tsgml-indent-step:nilsgml-indent-data:tsgml-parent-document:nilsgml-exposed-tags:nilsgml-local-catalogs:nilsgml-local-ecat-files:nilEnd:-->