This all came about because I started to think about about how to handle footnotes. I actually had gotten to the point where I was about to make a post to www-style back in February with a proposal. Then I realized how it might be generalized with only a few changes to my original idea. Those changes yielded increased functionality beyond just footnotes. Just when I was about ready to post again, Ian gave us a hint of what was to come with the CSS3 Generated and Replaced Content Module. Now that the working draft has been released, and I’ve had time to digest it, I’m ready to present my proposal.
You will find herein both the bare bones of my proposal as well as examples of how it could be used. Examples include endnotes, footnotes, a table of contents, and for lack of a better term: sticky notes. The basic functionality has been gained by adding values to existing CSS2 properties. Two new properties and eleven new pseudoelements are provided to provide fine-grained control of the presention.
This propoosal is not an alternative to the CSS3 Generated and Replaced Content Module. For one thing, many things that it does are not addressed in this proposal. While both address the issue of the footnotes, they do so in different ways and with different agendas.
This proposal provides two basic mechanisms: referrals and context lists. Referrals are a method of transferring the content of one element to another element. Context Lists are a method of displaying referred content only when its reference point is in the current viewport.
The central idea here is that there ought to be a way for an element to be in two places at once.
To handle footnotes properly requires a mechanism to connect the footnote reference and the footnote itself.
This requires affecting the document flow and changing it from being the same as the document structure.
In plain HTML without any CSS, the document flow and the document structure are one and the same.
In CSS 1, the display
property allowed an element to be removed from the document flow.
Begining with CSS 2, the position
property allowed for changes to the document flow beyond removal.
Referrals add a mechanism to attach the flow of an element onto that of another element
as if it were a child element of that other element.
::nth-referral(an+b)
pseudo-elementName: | ::nth-referral(an+b) |
---|---|
Initial Content: |
The content of an element attached to the parent element thru the use of the
referral(x) function.
|
Applies to: | All elements that are the target of a referral(x) function. |
Initial CSS values: |
Those of the attached element except for the position property which is changed to relative .
(See the description of the referral(x) function for details.)
|
See the :nth-child(an+b)
pseduo-class for a details on how the argument works.
This pseudo-element selects from the elements attached to the parent element.
For example ::nth-referral(3n)
matches the content from every third appendage of any element.
::nth-last-referral(an+b)
pseudo-element
This is to ::nth-referral(an+b)
as :nth-last-child(an+b)
is to :nth-child(an+b)
.
::first-referral
pseudo-element
This is to ::nth-referral(an+b)
as :first-child
is to :nth-child(an+b)
.
::last-referral
pseudo-element
This is to ::nth-referral(an+b)
as :last-child
is to :nth-child(an+b)
.
::only-referral
pseudo-element
This is to ::nth-referral(an+b)
as :only-child
is to :nth-child(an+b)
.
::reference
pseudo-elementName: | ::reference |
||||||
---|---|---|---|---|---|---|---|
Initial Content: | If the display-role of the parent element is list-item ,
then the initial content is that of the ::marker pseudo-element.
Otherwise, the initial content is empty. |
||||||
Applies to: | All elements with a position of referral(x) . |
||||||
Initial CSS values: |
Same as parent except for display-model , display-role , and position .
|
The ::reference
pseduo-element is the content that is left behind in the location
in the normal flow where the element would have been had its position
been static
.
reference-index
propertyName: | reference-index |
---|---|
Value: | <integer> |
Initial: | 0 |
Applies to: |
All elements with a position of
referral(x) .
|
Inherited: | no |
Percentages: | N/A |
Media: | All |
Computed value: | specified value (except for initial and inherit ) |
The reference-index
property is used to specify the order
that elements attached to another via a position
of referral(x)
are appended.
An attached element with a reference-index
of 0 is appended last.
All other attached elements are appended in the order of their reference-index
beginning with the lowest reference-index
.
If multiple elements are attached to the same element, the order of appending is the same as their occurence in the document.
reference-link
propertyName: | reference-link |
---|---|
Value: | none | both | to-ref | from-ref |
Initial: | none |
Applies to: | All elements with a position of referral(x) . |
Inherited: | no |
Percentages: | N/A |
Media: | Any interactive media |
Computed value: | specified value (except for initial and inherit ) |
This property controls the creation of links between an element and
its ::reference
pseudo-element.
If the value of this property is both
or to-ref
,
then a DOMActivate event
reaching the element on the bubbling phase causes the viewport of the document to change (if necessary)
to place the ::reference
pseudo-element in the viewport.
The event is not propogated further.
If the value of this property is both
or from-ref
then a DOMActivate event
reaching the ::reference
pseudo-element on the bubbling phase
causes the viewport of the document change (if necessary) to place the element in the viewport.
The event is not propogated further.
If a user agent supports XHTML hyperlinks, then the method(s) of causing the DOMActivate event to be triggered should be the same as the method(s) activating a hyperlink in XHTML.
referral(x)
functionName: | referral(x) |
---|---|
Argument: | <idref> | attr(x)
|
Applies to: |
The position property of any element (but not any pseudo-element).
|
This function is added to the allowable values of the position
property.
The argument of the referral(x)
function should resolve to an IDREF as defined in XML.
It can either be given directly, or it can be an attribute specified by the attr(x)
function.
(Note: It is not a requirement that the attribute be of type IDREF.)
If the ID referenced by the argument of the referral(x)
function is not present in the document,
then the rule should be considered invalid and ignored.
Here is what happens when the rule is valid:
[1]
The element and all of its children is removed from the normal flow.
[2]
The ::reference
pseduo-element associated with the element is placed into the normal flow in place of the element and its children.
[3]
The content of the element is appended to the element specified by the argument of the referral(x)
function,
as if it were a child of that element with a position
property of relative
.
[4]
If the contents of multiple elements are appended to the same element,
then they are appended in the order described in definition of the reference-index
property.
Note that it is possible for an infinite loop of links to be established via the referral(x)
function.
User agents implementing referral(x)
must be able to detect such loops and stop them.
All such elements are effectively removed from the document flow and are not displayed.
This is equivalent to all of them having a display
value of none
,
except that the ::reference
pseudo-elements are still part of the document flow.
User agents implementing references may provide a mechanism,
whereby the content of elements removed from the document flow because of such infinite links can be accessed.
User agents that implement the reference-link
property
should have the method used to link from the ::reference
pseudo-element
provide access to the parent element if they provide any access.
For such things as endnotes or a table of contents, referrals as defined above are sufficient.
However, to implement footnotes, it is necessary to also have a methos of only showing the referrals
whose ::reference
pseudo-elements are in the current viewport or page,
and a mechanism for dealing with the overflow if the chosen area is unable to show all the referrals.
I call the method presented here context lists, altho I’d gladly entertain any idea for a better name.
To properly implement footnotes, I also found it necessary to add additional value to the overflow property.
context-list
valueName: | context-list |
---|---|
Applies to: |
The display and display-role properties of any element (but not any pseudo-element).
|
The CSS rule display:context-list
is shorthand for the CSS rules display-model:block-inside
and display-role:context-list
.
The CSS rule display-role:context-list
is similar
to the CSS rule display-role:list
except that only some of the referrals are visible.
The referrals that are to be visible are those whose ::reference
pseudo-element are displayed in the current viewport.
::nth-context(an+b)
pseudo-elementName: | ::nth-context(an+b) |
---|---|
Initial Content: |
The content of an element attached to the parent element thru the use of the
referral(x) function.
|
Applies to: | All elements that are the target of a referral(x) function. |
Initial CSS values: |
Those of the attached element except for the position property which is changed to relative .
(See the description of the referral(x) function for details.)
|
See the :nth-child(an+b)
pseduo-class for a details on how the argument works.
If the parent element has a display-role
of context-list
,
this pseudo-element selects from the elements attached to the parent element which have
a ::reference
pseudo-element displayed in the current viewport.
In the case of paged media,
the viewport is the page and it is possible that attached elements will overflow to the next page.
In such a case, ::nth-context(1)
refers to the first attached element displayed on the current page,
even if it has overflowed from a previous page.
If the parent element does not have a display-role
of context-list
,
then ::nth-context(an+b)
is equivalent to
::nth-referral(an+b)
.
::nth-last-context(an+b)
pseudo-element
This is to ::nth-context(an+b)
as :nth-last-child(an+b)
is to :nth-child(an+b)
.
::first-context
pseudo-element
This is to ::nth-context(an+b)
as :first-child
is to :nth-child(an+b)
.
::last-context
pseudo-element
This is to ::nth-context(an+b)
as :last-child
is to :nth-child(an+b)
.
::only-context
pseudo-element
This is to ::nth-context(an+b)
as :only-child
is to :nth-child(an+b)
.
page-break
valueName: | page-break |
---|---|
Applies to: |
The overflow and overflow-y properties of any element.
|
The CSS rule overflow:page-break
is shorthand
for the pair of CSS rules overflow-x:initial
and overflow-y:page-break
.
In most circumstances overflow-y:page-break
has the same effect as overflow-y:scroll
.
The only difference in behavior occurs when the element has position:fixed
and the medium is a paged media.
In that case, any overflow is sent to the same containing box, but on the next page.
Note that the traditional behavior that occurs when printing XHTML documents can be expressed via the CSS rule set
body {overflow-y:page-break}
.
This is a serendipitous side effect of adding this value.
Here I intended to give five examples, showing how in theory, endnotes, section notes, footnotes, a table of contents and sticky notes could be implemented using the ideas in this proposal. However, I onl;y have one example, the simplest one, endnotes, done. Since the Generated and Replaced Content Module has come out, I had the problem do I send this out now, or do I wait until I have my examples all done. I chose to send out what I already had available.
common.css
:
.cl {display:context-list}
.ref {
display:list-item;
list-style-type:numeric;
}
This is the simplest of the five examples and hence is the one I’ve chosen to present first.
<html><head>
<title>Endnote Example</title>
<link> rel="Stylesheet" href="common.css">
<style>
.ref {position:referral(endnotes)}
</style>
</head><body>
<h1>Endnote Example</h1>
<p>
Blah blah blah blah blah.
Bleh Bleh bleh bleh bleh.<b class="ref">Blih Blih.</b>
Bloh Bloh bloh bloh bloh.<i class="ref">Bluh Bluh.</i>
</p>
<div id="endnotes">
Endnotes
</div>
</body></html>
Blah blah blah blah blah. Bleh Bleh bleh bleh bleh,1. Bloh Bloh bloh bloh bloh.2.
::nth-referral(an+<b and related pseudo-elements to enable fine tuned access to the referrals.
Are they really needed or is there a simpler way of providing styling based on the order in which content is appended?
reference-index
property really needed?
It's simple enough to define, but I haven't been able to come up with a good use case for it.
I don't need it for any of my examples.
move-to
property in the Generated and Replaced Content Module working draft?