├── LICENSE
└── Overview.src.html
/LICENSE:
--------------------------------------------------------------------------------
1 | CC0 1.0 Universal
2 |
3 | Statement of Purpose
4 |
5 | The laws of most jurisdictions throughout the world automatically confer
6 | exclusive Copyright and Related Rights (defined below) upon the creator and
7 | subsequent owner(s) (each and all, an "owner") of an original work of
8 | authorship and/or a database (each, a "Work").
9 |
10 | Certain owners wish to permanently relinquish those rights to a Work for the
11 | purpose of contributing to a commons of creative, cultural and scientific
12 | works ("Commons") that the public can reliably and without fear of later
13 | claims of infringement build upon, modify, incorporate in other works, reuse
14 | and redistribute as freely as possible in any form whatsoever and for any
15 | purposes, including without limitation commercial purposes. These owners may
16 | contribute to the Commons to promote the ideal of a free culture and the
17 | further production of creative, cultural and scientific works, or to gain
18 | reputation or greater distribution for their Work in part through the use and
19 | efforts of others.
20 |
21 | For these and/or other purposes and motivations, and without any expectation
22 | of additional consideration or compensation, the person associating CC0 with a
23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
25 | and publicly distribute the Work under its terms, with knowledge of his or her
26 | Copyright and Related Rights in the Work and the meaning and intended legal
27 | effect of CC0 on those rights.
28 |
29 | 1. Copyright and Related Rights. A Work made available under CC0 may be
30 | protected by copyright and related or neighboring rights ("Copyright and
31 | Related Rights"). Copyright and Related Rights include, but are not limited
32 | to, the following:
33 |
34 | i. the right to reproduce, adapt, distribute, perform, display, communicate,
35 | and translate a Work;
36 |
37 | ii. moral rights retained by the original author(s) and/or performer(s);
38 |
39 | iii. publicity and privacy rights pertaining to a person's image or likeness
40 | depicted in a Work;
41 |
42 | iv. rights protecting against unfair competition in regards to a Work,
43 | subject to the limitations in paragraph 4(a), below;
44 |
45 | v. rights protecting the extraction, dissemination, use and reuse of data in
46 | a Work;
47 |
48 | vi. database rights (such as those arising under Directive 96/9/EC of the
49 | European Parliament and of the Council of 11 March 1996 on the legal
50 | protection of databases, and under any national implementation thereof,
51 | including any amended or successor version of such directive); and
52 |
53 | vii. other similar, equivalent or corresponding rights throughout the world
54 | based on applicable law or treaty, and any national implementations thereof.
55 |
56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of,
57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
59 | and Related Rights and associated claims and causes of action, whether now
60 | known or unknown (including existing as well as future claims and causes of
61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum
62 | duration provided by applicable law or treaty (including future time
63 | extensions), (iii) in any current or future medium and for any number of
64 | copies, and (iv) for any purpose whatsoever, including without limitation
65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
66 | the Waiver for the benefit of each member of the public at large and to the
67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver
68 | shall not be subject to revocation, rescission, cancellation, termination, or
69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work
70 | by the public as contemplated by Affirmer's express Statement of Purpose.
71 |
72 | 3. Public License Fallback. Should any part of the Waiver for any reason be
73 | judged legally invalid or ineffective under applicable law, then the Waiver
74 | shall be preserved to the maximum extent permitted taking into account
75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
76 | is so judged Affirmer hereby grants to each affected person a royalty-free,
77 | non transferable, non sublicensable, non exclusive, irrevocable and
78 | unconditional license to exercise Affirmer's Copyright and Related Rights in
79 | the Work (i) in all territories worldwide, (ii) for the maximum duration
80 | provided by applicable law or treaty (including future time extensions), (iii)
81 | in any current or future medium and for any number of copies, and (iv) for any
82 | purpose whatsoever, including without limitation commercial, advertising or
83 | promotional purposes (the "License"). The License shall be deemed effective as
84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the
85 | License for any reason be judged legally invalid or ineffective under
86 | applicable law, such partial invalidity or ineffectiveness shall not
87 | invalidate the remainder of the License, and in such case Affirmer hereby
88 | affirms that he or she will not (i) exercise any of his or her remaining
89 | Copyright and Related Rights in the Work or (ii) assert any associated claims
90 | and causes of action with respect to the Work, in either case contrary to
91 | Affirmer's express Statement of Purpose.
92 |
93 | 4. Limitations and Disclaimers.
94 |
95 | a. No trademark or patent rights held by Affirmer are waived, abandoned,
96 | surrendered, licensed or otherwise affected by this document.
97 |
98 | b. Affirmer offers the Work as-is and makes no representations or warranties
99 | of any kind concerning the Work, express, implied, statutory or otherwise,
100 | including without limitation warranties of title, merchantability, fitness
101 | for a particular purpose, non infringement, or the absence of latent or
102 | other defects, accuracy, or the present or absence of errors, whether or not
103 | discoverable, all to the greatest extent permissible under applicable law.
104 |
105 | c. Affirmer disclaims responsibility for clearing rights of other persons
106 | that may apply to the Work or any use thereof, including without limitation
107 | any person's Copyright and Related Rights in the Work. Further, Affirmer
108 | disclaims responsibility for obtaining any necessary consents, permissions
109 | or other rights required for any use of the Work.
110 |
111 | d. Affirmer understands and acknowledges that Creative Commons is not a
112 | party to this document and has no duty or obligation with respect to this
113 | CC0 or use of the Work.
114 |
115 | For more information, please see
116 |
To the extent possible under law, the editor has waived all copyright and related or neighboring rights to this work. In addition, as of [DATE], the editor has made this specification available under the
50 | Open Web Foundation Agreement Version 1.0, which is available at http://www.openwebfoundation.org/legal/the-owf-1-0-agreements/owfa-1-0.
51 |
52 |
This specification defines features often used when printing books or magazines. Using this functionality, documents written in HTML can be presented in a book-like manner, either on screen or on paper. Real books are being published with functionality described in this specification. 57 | 58 |
This specification is in the process of establishing itself in WHATWG. Most of this specification has been interoperably implemented and is in daily use by publishers. Implementation coverage is documented here. 61 | 62 |
The main goal of this specification is to enable authors to write books in HTML or other markup languages. Book publishing is a craft with long traditions and certain formatting conventions have developed over time. This specification adds functionality to CSS so that style sheets can express commonly used features in printed books, on-screen books, and page description languages. These features are also often used by magazines, in brochures, and in other publications. 70 | 71 | 72 |
All diagrams, examples, and notes in this specification are 75 | non-normative, as are all sections explicitly marked non-normative. 76 | Everything else in this specification is normative. 77 | 78 |
The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and 80 | "OPTIONAL" in the normative parts of this specification are to be 81 | interpreted as described in RFC2119. For readability, these words do 82 | not appear in all uppercase letters in this specification. 83 | RFC2119 84 | 85 |
Conformance requirements phrased as algorithms or specific steps 86 | may be implemented in any manner, so long as the end result is 87 | equivalent. 88 | 89 |
User agents may impose 90 | implementation-specific limits on otherwise unconstrained inputs, 91 | e.g. to prevent denial of service attacks, to guard against running 92 | out of memory, or to work around platform-specific limitations. 93 | 94 | 95 |
A book is a collection of sheets, bound together within covers. 98 | Usually, the sheets are printed paper sheets of a uniform size. The 99 | book format, known as the codex was developed around 2000 100 | years ago and books gradually replaced scrolls, clay tablets and other 101 | competing formats. With the invention of the printing press, books 102 | could be printed and distributed inexpesively. 103 | 104 |
Each sheet of paper has two sides, and most books are have content 105 | on both sides of the sheets. Each side is called a "page". When a book 106 | is opened, two pages are visible; these form one "spread". The main 107 | problem when producing books from web content is to split content into 108 | pages and spreads of certain fixed sizes. This problem is not 109 | addressed by this specification. Instead, this specification describes 110 | how to achieve many of the features printers have developed over the 111 | centuries, e.g, running headers, footnotes, sidenotes, and page 112 | groups. 113 | 114 | 115 |
To aid navigation in printed material, headers and footers are often 118 | printed in the page margins. CSSPAGE describes how to place 119 | headers and footers on a page, but not how to fetch headers and 120 | footers from elements in the document. This specification offers two 121 | ways to achieve this. The first mechanism is named strings 122 | which copies the text (without style, structure, or replaced 123 | content) of an element for later reuse in margin boxes. The second 124 | mechanism is running elements which moves elements 125 | (with style, structure, and replaced content) into a margin box. 126 | 127 | 128 | 129 |
A named string can be thought of as a variable that hold a 146 | string of text. Named strings are created with the 'string-set' 147 | property which copies a string of text into a named string. Only text 148 | is copied; not style, structure, or replaced content. 149 | 150 |
155 | 156 |Consider this code: 159 | 160 |
161 | h1 { string-set: heading content() }
162 |
163 |
164 | Whenever an h1 element is encountered,
165 | its textual content is copied into a named string called
166 | heading. The string can later be retrieved in the 'content'
167 | property:
168 |
169 |
170 | @page { @top-center { content: string(heading) }}
171 |
172 |
173 | | Name: 181 | | string-set 182 | |
| Value: 184 | | [[ <identifier> <content-list>] [, <identifier> <content-list>]* ] | none 185 | |
| Initial: 187 | | none 188 | |
| Applies to: 190 | | all elements 191 | |
| Inherited: 193 | | no 194 | |
| Percentages: 196 | | N/A 197 | |
| Media: 199 | | all 200 | |
| Computed value: 202 | | as specified value 203 | |
The 'string-set' property accepts a comma-separated list of named strings. Each named string is followed by a content list that specifies the text to assign to the named string. Whenever an element with value of 'string-set' different from ''none'' is encountered, the named strings are assigned their respective value. Implementations must keep track of named string assigments on a per-element basis; references to named strings can only be resolved after pagination (see Using named strings below). 206 | 207 |
<content-list> expands to one or more of these values, in any order: 208 | 209 |
The syntax is formally described as: 236 | 237 |
238 | <content-list> = [ <string> | <counter> | [ content( [ before | after | first-letter ] ) ] ]+ 239 |240 | 241 |
Named strings can only hold the result of one assignment; whenever 242 | a new assignment is made to a named string, its old value is replaced. 243 | 244 |
User agents, however, must be able to remember the 245 | several assignments as the ''string()'' functional value 246 | (described below) can refer to different assignments. 247 | 248 |
The scope of a named string is the page of the element to which the 249 | 'string-set' property is attached and subsequent pages. 250 | 251 | 255 | 256 | 257 |
262 | 263 | 264 |
266 | h2 {
267 | string-set: header "Chapter " counter(header) ": " content();
268 | counter-increment: header;
269 | }
270 |
271 | <h2>Europa</h2>
272 |
273 |
274 | Note that the string called "header" is different from the counter with the same name. The above code may result in the string called "header" is set to "Chapter 1: Europa". 275 | 276 |
The textual content of the named string is processed as if 'white-space: normal' has been set. 280 | 281 |
286 | 287 |In this example, the header will consist of three words ("In the beginning") with normal spacing between the words. 289 |
290 | h2 {
291 | string-set: header "In " ' ' content();
292 | }
293 |
294 | <h2> the beginning</h2>
295 |
296 | In this example, the named string called index will hold the first letter of <dt> elements. 301 |
302 | dt { string-set: index content(first-letter) }
303 |
304 | One-letter running headers are often used in dictionaries. 305 |
The textual content is copied regardless of values on other CSS properties. 308 | 309 |
314 | 315 |In this example, the first four declarations have no effect on the on the named string copied in the last declaration: 317 | 318 |
319 | title {
320 | display: none;
321 | content: "foo";
322 | text-transform: uppercase;
323 | text-replace: "foo" "bar";
324 | string-set: title content();
325 | }
326 |
327 | Named strings can be referred to with the ''string()'' value on the 333 | 'content' property. The ''string()'' value has one required argument 334 | (the name of the string), and one optional argument that indicates 335 | which string assignment to use. References to named strings can only 336 | be resolved after pagination. 337 | 338 |
340 | @page { @top-center { content: string(header) }}
341 | @page { @right-middle { content: string(index) }}
342 | @page { @top-left { content: string(entry) }}
343 | h1 { string-set: header "Chapter " counter(chapter) content() }
344 | dt { string-set: index content(first-letter), entry content() }
345 |
346 |
348 |
349 | If the value of the named string is changed by an element on a certain 352 | page, the named string may have several values on that page. In order to specify 353 | which of these values should be used, an optional second argument is accepted 354 | on the ''string()'' value. This argument can have one of four keywords: 355 | 356 |
The syntax of the ''string()'' value is: 368 | 369 |
370 | string( <custom-ident> [ , [ first | start | last | first-except ]]? ) 371 |372 | 373 |
The assignment is considered to take place on the first page where a content box representing the element occurs. If the element does not have any content boxes (e.g., if 'display: none' is set), the assignment is considered to take place on the page where the first content box would have occured if the element had been in the normal flow. 374 | 375 |
In this example, the first term on the page will be shown in the top left corner and the last term on the page will be shown in the top right corner. In top center of the page, the first letter of first term will be shown. 377 |
378 | @page { @top-left { content: string(term, first) }}
379 | @page { @top-right { content: string(term, last) }}
380 | @page { @top-center { content: string(index, first) }}
381 | dt { string-set: index content(first-letter), term content(text) }
382 |
383 | Given this CSS code: 395 | 396 |
397 | h2 { string-set: header content() }
398 |
399 |
400 | The value of the header string 401 | 402 |
| page# | HTML code | first | start | last | first-except 405 | 406 | |
| 1 408 | |
409 | <h1>Continents</h1> 410 | ... 411 | <h2>Africa</h2> 412 | ... 413 | ... 414 |415 | | Africa 416 | | Africa 417 | | Africa 418 | | 419 | 420 | 421 | |
| 2 423 | |
424 | ... 425 | <h2>Americas</h2> 426 | ... 427 | <h2>Asia</h2> 428 | ... 429 |430 | | Americas 431 | | Africa 432 | | Asia 433 | | 434 | 435 | 436 | |
| 3 438 | |
439 | ... 440 | ... 441 | ... 442 | ... 443 |444 | | Asia 445 | | Asia 446 | | Asia 447 | | Asia 448 | 449 | |
| 4 451 | |
452 | <h2>Europe</h2> 453 | ... 454 | <h2>Oceania</h2> 455 | .. 456 | 457 |458 | | Europe 459 | | Europe 460 | | Oceania 461 | | 462 | |
In this example, the term that is being described at the start of the page is shown in the top left header. 469 |
470 | @page { @top-left { content: string(term, start) }}
471 | dt { string-set: term content() }
472 |
473 |
477 | @page { @top-left { content: string(term, first) }}
478 | @page { @top-right { content: string(term, last) }}
479 | @page { @top-center { content: string(index, first) }}
480 | dt { string-set: index content(first-letter), term content(text) }
481 |
482 | In this example, the header in the top center will be blank on pages where 'h1' elements appear. On other pages, the string of the previous 'h1' element will be shown. 488 |
489 | @page { @top-center { content: string(chapter, first-except) }}
490 | h1 { string-set: chapter content() }
491 |
492 | If the named string referred to in a 'string()' value has not been 495 | assigned a value, the empty string is used. 496 | 497 | 498 |
Named strings, as described above, can only hold textual content; any 508 | style, structure or replaced content associated with the element is 509 | ignored. To overcome this limitation, a way of moving elements into 510 | running headers and footers is introduced. 511 | 512 |
Elements that are moved into headers and footers are repeated on 513 | several pages; they are said to be running elements. To 514 | support running elements, a new value – running() – is 515 | introduced on the 'position' property. It has one required argument: 516 | the name by which the running element can be referred to. A running 517 | element is not shown in its natural place; there it is treated as if 518 | 'display: none' had been set. Instead, the running element is 519 | displayed when referred to by the ''element()'' value. 520 | 521 |
Like counters and named strings, the name of a running element is chosen by 522 | the style sheet author, and the names have a separate namespace. A 523 | running element can hold one element, including its pseudo-elements 524 | and its descendants. Whenever a new element is assigned to a running 525 | element, the old element is lost. 526 | 527 |
User agents, however, must be able to remember the 528 | result of more than one assignment as the ''element()'' value 529 | (described below) can refer to different assignments. 530 | 531 |
Running elements inherit through their normal place in the 532 | structure of the document. 533 | 534 | 535 |
537 | title { position: running(header) }
538 | @page { @top-center {
539 | content: element(header) }
540 | }
541 |
542 | Like the ''string()'' value, the ''element()'' value accepts an 559 | optional second argument. The syntax is defined as: 560 | 561 |
562 | element( <custom-ident> [ , [ first | start | last | first-except ]]? ) 563 |564 | 565 |
The keywords have the same meaning as for the ''string()'' value. 566 | 567 |
The ''element()'' value is only allowed on the 'content' property within a margin box. The ''element()'' value cannot be combined with any other values. 568 | 569 |
In this example, the header is hidden from view in all media types 571 | except print. On printed pages, the header is displayed top center on 572 | all pages, except where h1 elements appear. 573 | 574 |
575 | <style>
576 | div.header { display: none }
577 | @media print {
578 | div.header {
579 | display: block;
580 | position: running(header);
581 | }
582 | @page { @top-center { content: element(header, first-except) }}
583 | </style>
584 | ...
585 | <div class="header">Introduction</div>
586 | <h1 class="chapter">An introduction</div>
587 |
588 |
589 | This code illustrates how to change the running header on one page in the middle of a run of pages: 593 | 594 |
595 | ...
596 | <style>
597 | @page { @top-center {
598 | content: element(header, first) }}
599 | .header { position: running(header) }
600 | .once { font-weight: bold }
601 | </style>
602 | ...
603 | <div class="header">Not now</div>
604 | <p>Da di ha di da di ...
605 | <span class="header once">NOW!</span>
606 | <span class="header">Not now</span>
607 | ... da di ha di hum.</p>
608 | ...
609 |
610 |
611 | The header is "Not now" from the outset, due to the "div" element. The
612 | first "span" element changes it to "NOW!" on the page where the
613 | "span" element would have appeared. The second "span" element, which
614 | would have appeared on the same page as the first is not used because the
615 | ''first'' keyword has been specified. However, the second "span"
616 | element still sets the exit value for "header" and this value is
617 | used on subsequent pages.
618 | A leader is a visual pattern that guides the eye. Typically, 632 | leaders are used to visually connect an entry in a list with a 633 | corresponding code. For example, there are often leaders between 634 | titles and page numbers in a table of contents (TOC). Another example 635 | is the phone book where there are leaders between a name and a 636 | telephone number. 637 | 638 |
In CSS3, a leader is composed of series of glyphs through the 639 | ''leader()'' value on the 'content' property. The functional notation 640 | accepts two values. The first describes the glyph pattern that makes up the 641 | leader. The syntax is: 642 | 643 |
644 | leader( [ dotted | solid | space | <string> ] ) 645 |646 | 647 |
Using the keyword values is equivalent to setting a string value. 648 | The table below shows the equivalents: 649 | 650 |
| Keyword | String | Unicode characters 652 | |
|---|---|---|
| leader(dotted) | leader('. ') | \002E \0020 653 | |
| leader(solid) | leader('_') | \005F 654 | |
| leader(space) | leader(' ') | \0020 655 | |
The string inside the parenthesis is called the leader 659 | string. The leader string must be shown in full at least once, 660 | thereby pushing other content to the side (in the writing direction of 661 | the element to which the leader is attached). The leader string 662 | establishes the minimum length of the leader. If there is empty space 663 | on the line, the leader is expanded by repeating it as many times as 664 | possible. The expansion of a leader from its minimum length never 665 | causes line breaks to change. At the end of the leader, a partial 666 | leader string may be shown. 667 | 668 |
Line-breaking characters inside leader strings must be ignored. A list of line-breaking characters are found in 669 | [Unicode 670 | Technical Report #13]. Other white space characters are collapsed according to the values of 671 | white-space properties. A leader consisting only of whitespace 672 | characters is called a whitespace leader. 673 | 674 | 675 |
To determine the length of the leaders, user agents must do the 676 | following for each line where a leader appears: 677 | 678 |
By adding a leader to the ::after pseudo-element, a leader is added after the content of an element: 694 |
695 | h1::after { content: leader(dotted) }
696 |
697 | <h1>Dotted news</h1>
698 |
699 | The formatted result may be: 700 |
701 | |Dotted news...................| 702 |703 |
By setting 'white-space: pre', the white space in the leader string is preserved: 707 |
708 | h1::after {
709 | content: leader(' - ');
710 | white-space: pre;
711 | }
712 | <h1>Dashing news</h1>
713 |
714 | The formatted result may be: 715 |
716 | |Dashing news - - - -| 717 |718 |
If a leader is set on an inline element inside a justified paragraph, there will not be any empty space on the line. Therefore, the leader is shown only once. 723 | 724 |
725 | span::after {
726 | content: leader('...');
727 | }
728 |
729 | <p>A paragraph with a <span>span</span> inside.
730 |
731 |
732 | would be formatted as:
733 |
734 | 735 | A paragraph with a span... inside. 736 |737 | 738 |
The presence of a leader may influence tables. Consider this example with two table cells in one row: 745 | 746 |
747 | td.leader::after { content: leader('..') }
748 |
749 | <table style="width: 30em">
750 | <tr><td class=leader>foo</td> <td>bar</td></tr>
751 | </table>
752 |
753 |
754 | In UAs that don't do leaders, the two cells will have the same width 755 | and the table cells could be rendered like this: 756 | 757 |
758 | |foo |bar | 759 |760 | 761 |
When leaders are supported, the maximum cell width of the 762 | first cell grows, and the table cell could be rendered like this: 763 | 764 |
765 | |foo........................................................|bar| 766 |767 | 768 | 769 |
A table of contents often use leaders to visually connect a chapter 774 | title with the corresponding page number. This can be achieved with code like: 775 | 776 |
777 | ul.toc a::after {
778 | content: leader(". . . ") target-counter(attr(href url), page);
779 | }
780 |
781 |
782 | The formatted result could be: 783 | 784 |
785 | Africa ...........1 786 | America...........9 787 | Antarctica.......56 788 | Asia............134 789 |790 | 791 |
The appearance of leaders is influenced by the same set of properties that influence the appearance of fixed strings. 794 | 795 |
The same properties can affect the presentation of the fixed string and the leader. 797 | 798 |
799 | content: "...";
800 | content: leader("...");
801 |
802 | Line numbers sometimes displayed on the side of poetry, for reference purposes. In this example, a counter is dsplayed on every other line and pushed to the right by an invisible leader. 813 | 814 |
815 | @page { counter-reset: line }
816 | .line { counter-increment: line }
817 | .line:nth-of-type(2n+1)::after { content: leader(space) counter(line) }
818 |
819 |
820 | The formatted result could be: 821 | 822 |
823 | Oh! let that eye, which, wild as the gazelle's, 1 824 | Now brightly bold or beautifully shy, 825 | Wins as it wanders, dazzles where it dwells, 3 826 | Glance o'er this page, nor to my verse deny 827 |828 | 829 |
Note that the formatter doesn't really count lines, but rather elements marked up as lines. 830 |
A leader is only present on one line. If the presence of a minimum length leader at the end of a line results in subsequent content being moved to the next line, the leader will also be moved to the next line. 837 | 838 |
Consider this code: 840 | 841 |
842 | <style>
843 | .name::after { content: leader("...") }
844 | </style>
845 | <div class="entry">
846 | <span class="name">Douglas Adams</span>
847 | <span class="number">43</span>
848 | </div>
849 |
850 |
851 | Depending on the width of the containing block, the content may or may not fit on one line. In the rendered examples below, the thrird rendition the leader and its subsequent content is moved to the second line. 852 | 853 |
854 | |Douglas Adams......42| 855 |856 | 857 |
858 | |Douglas Adams...42| 859 |860 | 861 |
862 | |Douglas Adams | 863 | |..............42| 864 |865 | 866 |
The purpose of a leader is most often to connect two 869 | strings visually. To achieve this, User Agents may chose to move 870 | content appearing before the leader onto the same line as the leader. 871 | 872 |
In this renditon, the User Agen has chosen to move "Adams" to the next line to preserve a visual connection: 874 | 875 |
876 | |Douglas | 877 | |Adams.........42| 878 |879 |
In cases where there is not enough space for content on both sides of the leader, the leader will remain on the same line as the following content. 884 | 885 |
886 | |Douglas | 887 | |Adams | 888 | |.......42| 889 |890 | 891 |
892 | |Dou|glas 893 | |Ada|ms 894 | |...|42 895 |896 |
In this example, a whitespace leader is placed before a <cite> element: 900 | 901 |
902 | <style>
903 | cite::before { content: leader(' ') }
904 | </style>
905 | <blockquote>
906 | For a moment, nothing happend.
907 | Then, after a second or so,
908 | nothing continued to happen.
909 | <cite>Douglas Adams</cite>
910 | </blockquote>
911 |
912 |
913 | Whitespace leaders do not connect two strings in the same way that visible leaders do. User Agents may therefore chose to not move content appearing before the leader onto the same line as the leader. This may result in a rendition like: 914 | 915 |
916 | |For a moment, nothing happend. | 917 | |Then, after a second or so, | 918 | |nothing continued to happen. | 919 | | Douglas Adams| 920 |921 | 922 |
Rather than: 923 | 924 |
925 | |For a moment, nothing happend. | 926 | |Then, after a second or so, | 927 | |nothing continued to | 928 | |happen. Douglas Adams| 929 |930 | 931 |
When possible, User Agents should align corresponding glyphs from the 971 | leaders of consecutive lines. 972 | 973 |
In this example, the dotted lines are aligned horizontally so that the dots appear directly above and below each other: 975 |
976 | Alfa ........ 5 977 | Bravo ...... 41 978 | Charlie ... 125 979 |980 |
It is common to refer to other parts of a document by way of a 987 | section number (e.g., "See section 3.4.1"), a page number (e.g., "See 988 | discussion on page 72"), or a string (e.g., "See the chapter on 989 | Europe"). This specification describes how to resolve cross-references 990 | automatically by introducing two new values on the 'content' property. 991 | 992 |
Numerical cross-references are generated by ''target-counter()'' 995 | and ''target-counters()'' values on the 'content' property that fetch the value of a counter at 996 | the target end of the link. These functions are similar to the 997 | ''counter()'' and ''counters()'' functions, except that they fetch 998 | counter values from remote elements. ''target-counter()'' has two 999 | required arguments: the url of the link, and the name of a counter. 1000 | ''target-counters()'' has three required arguments: the url of the 1001 | link, the name of a counter, and a separator string. Both functions 1002 | accepts an optional argument at the end that describes which list 1003 | style type to use when presenting the resulting number; ''decimal'' 1004 | being the default. The syntax is defined as: 1005 | 1006 |
1007 | target-counter( <url> , <custom-ident> [ , <counter-style> ]? ) 1008 | target-counters( <url> , <custom-ident> , <string> [ , <counter-style> ]? ) 1009 |1010 | 1011 | 1012 |
This style sheet specifies that a string like " (see page 72)" 1014 | is added after a link: 1015 | 1016 |
1017 | a::after { content: "(see page " target-counter(attr(href url), page, decimal) ")" }
1018 |
1019 | This style sheet specifies that a string like " (see section 1.3.5)" 1038 | is added after a link: 1039 | 1040 |
1041 | a::after { content: "(see section " target-counters(attr(href url), section, ".", decimal) ")" }
1042 |
1043 |
1044 | Textual cross-references are generated by ''target-text()'' which 1049 | fetches the textual content from the target end of the link. Only text 1050 | is copied; not style, structure, or replaced content. 1051 | ''target-text()'' has one required argument: the url of the link. An 1052 | optional second argument specifies exactly which content is fetched. 1053 | There are four possible values: ''content'', ''before'', ''after'', 1054 | ''first-letter''; these keywords are defined on 'string-set' above. The syntax is: 1055 | 1056 |
1057 | target-text( <url> [, [ content | before | after | first-letter ]]? ) 1058 |1059 | 1060 | 1061 |
To generate this text: 1063 | 1064 |
1065 |1067 | 1068 | from this markup: 1069 | 1070 |See Chapter 3 ("A better way") on page 31 for an in-depth evaluation. 1066 |
1071 | <p>See <a href="#chx">this chapter</a> for an in-depth evaluation. 1072 | ... 1073 | <h2 id="chx">A better way</h2> 1074 |1075 | 1076 | this CSS code can be used: 1077 | 1078 |
1079 | h2 { counter-increment: chapter }
1080 | a { content: "Chapter " target-counter(attr(href url), chapter)
1081 | ' ("' target-text(attr(href url), content) '") on page '
1082 | target-counter(attr(href url), page);
1083 |
1084 | When an element is turned into a footnote, certain things 1098 | happen: the element is moved to the footnote area, a footnote call is 1099 | left behind in its place, a footnote marker is displayed before the 1100 | element, and the footnote counter is incremented. 1101 | 1102 |
A footnote is a note typically placed at the bottom of a page that 1103 | comments on, or cites, a reference. References to footnotes are marked 1104 | with a footnote call in the main text which corresponds to 1105 | a footnote marker in the footnote area. The 1106 | rendering of footnotes is complex. As far as possible, footnotes try 1107 | to reuse other parts of CSS. However, due to the typographic 1108 | traditions of footnotes, some new functionality is required. 1109 | 1110 | 1125 | 1126 |
In its simplest form, making a footnote is simple. 1128 | 1129 |
1130 | <style>
1131 | .footnote { float: footnote }
1132 | </style>
1133 |
1134 | <p>A sentence consists of words.<span class="footnote">Most often.</span>.
1135 |
1136 |
1137 | In this example, the text Most often.
will be placed in a
1138 | footnote. A note-call will be left behind in the main text and a
1139 | corresponding marker will be shown next to the footnote. Here is one
1140 | possible rendering:
1141 |
1142 |
1143 | A sentence consists of words.¹ 1144 | 1145 | ¹ Most often. 1146 |1147 |
Footnotes make sense in paged media, but in continous media the information is better displayed inline. Here is an example of how to support both paged and contious media: 1151 | 1152 |
1153 | <style>
1154 | @media print {
1155 | .footnote { float: footnote }
1156 | }
1157 | @media screen {
1158 | .footnote::before { content: " (" }
1159 | .footnote::after { content: ")" }
1160 | }
1161 | </style>
1162 |
1163 | <p>A sentence consists of words.<span class="footnote">Most often.</span>.
1164 |
1165 |
1166 | In contious media, the presentaion will be: 1167 | 1168 |
1169 | A sentence consists of words. (Most often.) 1170 |1171 |
Consider this markup: 1215 | 1216 |
1217 | <p>Sorry, <span title="This is, of course, a lie.">we're closing for lunch</span>. 1218 |1219 | 1220 |
The content of the "title" attribute can be turned into a footnote with this code: 1221 | 1222 |
1223 | span[title]::after {
1224 | content: attr(title);
1225 | float: footnote;
1226 | }
1227 |
1228 | An element with ''float: footnote'' (called a footnote 1234 | element) is moved to the footnote area and a footnote-call 1235 | pseudo-element is put in its original place. 1236 | 1237 |
1239 | span.footnote {
1240 | float: footnote;
1241 | }
1242 |
1243 | Footnote elements are presented inside the footnote area, 1246 | but they inherit through their normal place in the structure of the 1247 | document. 1248 | 1249 | 1276 | 1279 | 1280 |
For each new footnote element, the ''footnote'' counter is automatically 1281 | incremented. 1282 | 1283 | 1284 |
All elements with ''float: footnote'' are moved to the footnote 1287 | area. The footnote area is described by an @footnote-rule inside 1288 | the @page-rule. By default, the footnote area appears at the bottom of 1289 | the page, but it can be positioned in other places. 1290 | 1291 |
These rules place the footnote area at the bottom of the page, 1294 | spanning all columns of the outermost multicol element: 1295 | 1296 |
1297 | @page {
1298 | @footnote {
1299 | float: bottom;
1300 | float-reference: page;
1301 | }
1302 | }
1303 |
1304 |
1305 | The code above is part of the default style sheet. 1306 |
These rules place the footnote area at the bottom of the first column: 1311 | 1312 |
1313 | @page {
1314 | @footnote {
1315 | float: bottom;
1316 | float-reference: column;
1317 | }
1318 | }
1319 |
1320 | These rules place the footnote area at the bottom of the page. Also, the footnote area is split into three columns which the footnotes are flowed into: 1324 | 1325 |
1326 | @page {
1327 | @footnote {
1328 | float: bottom;
1329 | float-reference: page;
1330 | columns: 3;
1331 | }
1332 | }
1333 |
1334 | This code places the footnote area at the bottom of the last column of the outermost multicol element: 1338 | 1339 |
1340 | @page {
1341 | @footnote {
1342 | float: bottom;
1343 | float-defer-column: last;
1344 | }
1345 | }
1346 |
1347 |
1348 | The content of the footnote area is considered to come before other 1352 | content which may compete for the same space on the same page. 1353 | 1354 |
1356 | @page { @footnote { float: bottom; float-reference: page; }}
1357 | figure { float: bottom; column-span: all }
1358 |
1359 |
1360 | If figures and footnotes are on the same page, the footnotes will appear below the figures as they are floated to the bottom before the figures. 1361 |
Potentially, every page has a footnote area. If there 1364 | are no footnotes on the page, the footnote area will not take up any 1365 | space. If there are footnotes on a page, the layout of the footnote 1366 | area will be determined by the properties/values set on it, and by the 1367 | footnote elements inside it. 1368 | 1369 |
These properties apply to the footnote area: 'float', 'float-reference', 'content', 'border', 1370 | 'padding', 'margin', 'height', 'width', 'max-height', 'max-width', 1371 | 'min-height', 'min-width', and the background properties. 1372 | 1373 | 1382 | 1383 | 1384 |
This example uses some of the applicable properties on @footnote: 1386 | 1387 |
1388 | @footnote {
1389 | margin-top: 0.5em;
1390 | border-top: thin solid black;
1391 | border-clip: 4em;
1392 | padding-top: 0.5em;
1393 | }
1394 |
1395 |
1396 | The result of this code is a footnote area separated from other content above it by margin, border and padding. Only 4em of the border is visible due to the 'border-clip' property, which is defined in CSS Backgrounds and Borders Module Level 4. 1397 | 1398 |
When an element is moved to the footnote area, 1409 | a footnote-call is left behind. By default, User Agents must 1410 | behave as if this code is part of the default style sheet: 1411 | 1412 |
1413 | ::footnote-call {
1414 | content: counter(footnote, super-decimal);
1415 | }
1416 |
1417 |
1418 | The resulting note call is a super-script decimal number. 1419 | 1420 | 1421 |
A ::footnote-marker pseudo-element is added to each footnote 1424 | element, before the ::before 1425 | pseudo-element (if any), and replacing the ::marker pseudo-element (if any). User agents must, by default, show the "footnote" 1426 | counter in the footnote-marker. 1427 | 1428 |
User Agents may display footnote-calls and footnote-markers this way by default: 1430 | 1431 |
1432 | ::footnote-call {
1433 | content: counter(footnote, super-decimal);
1434 | }
1435 | ::footnote-marker {
1436 | content: counter(footnote, super-decimal);
1437 | }
1438 |
1439 | Marker elements are discussed in more detail in the CSS Lists 1450 | module [CSSLIST]. One suggested change to that module is to honor 1451 | the value of 'list-style-position' on the ::footnote-marker 1452 | pseudo-element itself rather than the corresponding list-item element. 1453 | Further, one clarification to the horizontal placement of the marker 1454 | is suggested: the margin box of the marker box is 1455 | horizontally aligned with the start of the line box. 1456 | 1457 | 1458 |
The "footnote" counter is automatically incremented each time a 1461 | footnote is generated. That is, the "footnote" counter is incremented 1462 | by one each time an element with ''float: footnote'' appears. 1463 | 1464 |
This code adds square brackets around footnote calls and 1466 | 1467 |
1468 | ::footnote-call {
1469 | content: " [" counter(footnote) "]";
1470 | }
1471 |
1472 | The footnote counter can be reset with the 'counter-reset' property. 1476 | 1477 |
This code resets the "footnote" counter on a per-page page basis: 1479 |
1480 | @page { counter-reset: footnote }
1481 |
1482 | Footnotes can also be combined with other counters. In this example, a poem is shown with line numbers on the side. The "line" counter is also used in the footnoter marker. 1514 | 1515 |
1516 | @page { counter-reset: line }
1517 | div.line { counter-increment: line }
1518 | div.line:nth-of-type(2n+1)::after { content: leader(space) counter(line) }
1519 | .footnote { float: footnote }
1520 | .footnote::footnote-call { content: "" }
1521 | .footnote::footnote-marker { content: counter(line) }
1522 |
1523 |
1524 | The formatted result could be: 1525 | 1526 |
1527 | Come, blue-eyed maid of heaven! - but thou, alas, 1 1528 | Didst never yet one mortal song inspire - 1529 | Goddess of Wisdom! here thy temple was, 3 1530 | And is, despite of war and wasting fire, 1531 | 1532 | 1 From "Childe Harold's Pilgrimage" by Lord Byron 1533 | 3 The use of uppercase "W" indicates great wisdom 1534 |1535 | 1536 |
Footnotes must appear as early as possible under the following constraints: 1542 | 1543 |
The page area and footnote area are predefined areas in CSS; all content is shown in the page area by default, and footnotes can be floated to the page area. This section describes a generic mechanism to create named areas, how to posistion named areas, and how to flow content into named areas. 1600 | 1601 |
@areaNamed areas can be generated by the style sheet to provide space for sidenotes, figures and other content which is presented apart from the main flow. The @area construct is used to create named areas, into which content can be flowed into with the 'flow' property.
1604 |
1605 |
Named areas are can be absolutely positioned, or positiond with the 'float' property. When absolutely positioned, measurements are relative to the page box. 1606 | 1607 |
In this example, a named area called sidenote is created. 1609 | 1610 |
1611 | @page {
1612 | margin-left: 10em;
1613 | @area sidenote { position: absolute; left: -8em; top: 0; width: 6em; height: auto }
1614 | }
1615 |
1616 |
1617 | The left edge of the named area is 8em to the left of the left edge of the page box. 1618 | 1619 |
Areas with the same name are connected and content can flow from such area to the next, when necessary. 1622 | 1623 |
In this example, both left and right pages have a sidenote area: 1625 | 1626 |
1627 | @page :left {
1628 | margin-left: 10em;
1629 | @area sidenote { position: absolute; left: -8em; top: 0; width: 6em; height: auto }
1630 | }
1631 | @page :right {
1632 | margin-right: 10em;
1633 | @area sidenote { position: absolute; right: -8em; top: 0; width: 6em; height: auto }
1634 | }
1635 |
1636 |
1637 | The baseline of the sidenotes are aligned with the baseline of their reference point. 1638 | 1639 |
To support having several identically named areas on the same page, 1642 | a second level of @area blocks are used. Only two levels of @area are 1643 | allowed. The outer @area must always have a name, and the inner @area 1644 | must never have a name. The named areas are painted as if they 1645 | appeared in the source file after the footnote area, and before any 1646 | content. 1647 | 1648 |
1650 | @page {
1651 | margin-left: 1cm 5cm; /* wide side margins */
1652 | @area sidenote {
1653 | @area { position: absolute; left: -4cm; top: 0; bottom: 0; width: 3.5cm; } /* left */
1654 | @area { position: absolute; right: -4cm; top: 0; bottom: 0; width: 3.5cm; } /* right */
1655 | }
1656 | }
1657 |
1658 | The 'flow' property is introduced to flow content into a named area. A functional notation indicates a named area, alignment within the named area, and placement policy. 1664 | 1665 |
1666 | area(<ident> [, <alignment> [, <placement-policy> ]]); 1667 |1668 | 1669 |
Aligmment is one of: 1670 | 1671 |
An optional exclamation mark ('!') can be added to the above keywords to express that aligment is essential: if it cannot be honored, the ele,ment will not be shown. 1696 | 1697 | 1698 |
This code moves <aside> elements to the named area called "sidenote" on the same page as the reference point: 1700 | 1701 |
1702 | aside { flow: area(sidenote, same-page); }
1703 |
1704 | In this example, images are flowed to right pages, where the "photos" area take up all available space: 1709 |
1710 | @page :right {
1711 | @area photos {
1712 | float: top;
1713 | float-reference: bleed-box;
1714 | width: 1vw;
1715 | height: 1vh;
1716 | }
1717 | }
1718 | img { flow: area(photos) }
1719 |
1720 |
1721 | The result is a document where content in the normal flow is shown on left pages, and right pages hold images. The images are filled into the named area in sequential order. 1722 | 1723 |
1729 | @page {
1730 | margin-left: 1cm 5cm; /* wide side margins */
1731 | @area sidenote {
1732 | @area { position: absolute; left: -4cm; top: 0; bottom: 0; width: 3.5cm; } /* left */
1733 | @area { position: absolute; right: -4cm; top: 0; bottom: 0; width: 3.5cm; } /* right */
1734 | }
1735 | }
1736 | .sidenote { flow: area(sidenote, baseline) }
1737 |
1738 |
1739 | One possible rendering is: 1740 |
1741 | ........ ......... 1742 | ........ ......... 1743 | ........ ...2..... second 1744 | ........ ......... sidenote 1745 | ........ ......... 1746 | first ....1... ......... 1747 | sidenote ........ ......... 1748 | ........ ....3.... third 1749 | ........ ......... sidenote 1750 | ........ ......... 1751 |1752 |
The digits mark the call points. 1753 |
In this example there are two streams of footnotes, both using named areas. The first stream flowed into the "fn1" area, and the second is flowed into "fn2". The first stream is referenced by numbers, and the second by lower-alpha. 1763 | 1764 |
1765 | @page {
1766 | @area fn1 { float: bottom; float-reference: page }
1767 | @area fn2 { float: bottom; float-reference: page }
1768 | }
1769 |
1770 | .fn1 { flow: area(fn1, same-page); counter-increment: fn1 }
1771 | .fn1::call { content: "[" counter(fn1) "]" }
1772 | .fn2::marker { content: "[" counter(fn1) "]" }
1773 |
1774 | .fn2 { flow: area(fn2,same-page); counter-increment: fn2 }
1775 | .fn2::call { content: "[" counter(fn2, lower-alpha) "]" }
1776 | .fn2::marker { content: "[" counter(fn2, lower-alpha) "]" }
1777 |
1778 |
1779 | In the formatted result, the named areas appear at the bottom of the page; fn1 is floated to the bottom first and therefore appears below fn2. A possible rendering could be: 1780 | 1781 |
1782 | [a] From "Childe Harold's Pilgrimage" by Lord Byron 1783 | [3] The use of uppercase "W" indicates great wisdom 1784 |1785 | 1786 |
In this example there are two streams of footnotes. The first stream is floated to the predefined "footnote" area, and the second is flowed to a name area called "fn2". The first stream is referenced by line numbers, and the second by lower-alpha. 1798 | 1799 |
1800 | @page {
1801 | counter-reset: line
1802 | @area fn2 {
1803 | float: bottom;
1804 | float-reference: page;
1805 | }
1806 | }
1807 | div.line { counter-increment: line }
1808 | div.line:nth-of-type(2n+1)::after { content: leader(space) counter(line) }
1809 |
1810 | .footnote { float: footnote }
1811 | .footnote::footnote-call { content: "[" counter(footnote, lower-alpha) "]" }
1812 | .footnote::footnote-marker { content: "[" counter(footnote, lower-alpha) "]" }
1813 |
1814 | .fn2 { flow: area(fn2, same-page) }
1815 | .fn2::call { content: "" }
1816 | .fn2::marker { content: "[" counter(line) "]" }
1817 |
1818 |
1819 |
1820 | In the formatted result, the footnote area appears below the named area. 1821 | 1822 |
1823 | Come, blue-eyed maid of heaven! - but thou, alas,[a] 1 1824 | Didst never yet one mortal song inspire - 1825 | Goddess of Wisdom! here thy temple was, 3 1826 | And is, despite of war and wasting fire, 1827 | 1828 | [3] The use of uppercase "W" indicates great wisdom 1829 | [a] From "Childe Harold's Pilgrimage" by Lord Byron 1830 |1831 | 1832 |
Consider this code: 1839 | 1840 |
1841 | .s1 { flow: area(sidenote, same-page) }
1842 | .s2 { flow: area(sidenote, same-page) }
1843 |
1844 |
1845 | When there is one sidenote area, to the left of the first column, the rendering may look like: 1846 | 1847 |
1848 | ┌─────┐......1..... ............ 1849 | │ s1 │............ ............ 1850 | └─────┘............ ............ 1851 | ┌─────┐............ ............ 1852 | │ s2 │............ ............ 1853 | └─────┘............ ............ 1854 | ............ ....2....... 1855 | ............ ............ 1856 | ............ ............ 1857 |1858 |
This example is similar to the previous example, except that there are two sidenote areas: left of the first column, and right of the second column. The sidenote elements are move to the closest sidenote area: 1862 | 1863 |
1864 | .s1 { flow: area(sidenote, same-page)
1865 | .s2 { flow: area(sidenote, same-page)
1866 |
1867 |
1868 | 1869 | ┌─────┐......1..... ............┌─────┐ 1870 | │ s1 │............ ............│ s2 │ 1871 | └─────┘............ ............└─────┘ 1872 | ............ ............ 1873 | ............ ............ 1874 | ............ ............ 1875 | ............ ....2....... 1876 | ............ ............ 1877 | ............ ............ 1878 |1879 |
In this example, figures appear in the main flow, while captions are flowed to the closest sidenote areas (there are two: left of the first column, and right of the second column). The captions are aligned with the top of the figure element. 1884 | 1885 |
1886 | figcaption { flow: area(sidenote, top-edge) }
1887 |
1888 | <figure>
1889 | <figcaption>s1</figcaption>
1890 | </figure>
1891 | <figure>
1892 | <figcaption>s2</figcaption>
1893 | </figure>
1894 |
1895 |
1896 | 1897 | ............ ............ 1898 | ............ ............ 1899 | ┌─────┐┌──────────┐ ............ 1900 | │ s1 ││ fig1 │ ┌──────────┐┌─────┐ 1901 | └─────┘│ │ │ fig2 ││ s2 │ 1902 | │ │ │ │└─────┘ 1903 | └──────────┘ │ │ 1904 | ............ └──────────┘ 1905 | ............ ............ 1906 | ............ ............ 1907 | ............ ............ 1908 |1909 |
In this example, the figure has an image that spans the width of the page and bleeds to the edges. The caption follows underneath, in the sidenote area. The intended rendering is: 1914 | 1915 |
1916 | ┌──────────────────────┐ 1917 | │ image │ 1918 | │ │ 1919 | │ │ 1920 | └──────────────────────┘ 1921 | ┌────────┐ ........... 1922 | │caption │ ........... 1923 | └────────┘ ........... 1924 | ........... 1925 | ........... 1926 |1927 | 1928 |
The style sheet define two name areas, one for the photograph and one for the sidenote. The "photo" named area is floated to the top, while the "sidenote" area is absolutely positioned. The two named areas overlap. Therefore, the order of the content is significant; the image is first flowed into the "photo" area. The position of the caption will be influcenced by the height of the image. 1929 | 1930 |
1931 | @page {
1932 | margin: 7mm 7mm 7mm 40mm;
1933 | @area photo { float: top; float-reference: bleed-box }
1934 | @area sidenote { position: absolute; left: -40mm; top: 0; bottom: 0; width: 35mm; }
1935 | }
1936 | figure img { flow: area(photo, same-page); clear: page }
1937 | figcaption { flow: area(sidenote, same-page) }
1938 |
1939 | ...
1940 |
1941 | <figure>
1942 | <img>
1943 | <figcaption>caption</figcaption>
1944 | </figure>
1945 |
1946 |
1947 | In this example, photographs are shown on right pages while the corresponding captions are flowed to a sidenote area on left pages. 1969 | 1970 |
1971 | @page :right {
1972 | margin-right: 10em;
1973 | @area photos {
1974 | position: absolute;
1975 | top: 0; right: -10em; bottom: 0; left: 0;
1976 | }
1977 | }
1978 | @page :left {
1979 | margin-left: 10em;
1980 | @area sidenote { position: absolute; right: -8em; top: 0; width: 6em; height: auto }
1981 | }
1982 | img { flow: area(photos) }
1983 | caption { flow: area(sidenote) }
1984 |
1985 |
1986 | When there is one sidenote area, to the left of the first column, the rendering may look like: 1987 | 1988 |
1989 | ┌─────┐ ......1..... ┌─────────────┐ 1990 | │ s1 │ ............ │photo 1 │ 1991 | └─────┘ ............ │ │ 1992 | ┌─────┐ ............ └─────────────┘ 1993 | │ s2 │ ............ ┌──────────┐ 1994 | └─────┘ ............ │photo 2 │ 1995 | .........2.. │ │ 1996 | ............ └──────────┘ 1997 | ............ 1998 |1999 |
This is fairly sketchy
2006 | 2007 |An optional argument indicates a placement policy: 2008 | 2009 |
In this example, there are two named areas called "sidenote", one 2025 | on the left side of the first column, and the other on the right side 2026 | of the second column. Three reference points are marked with 1, 2027 | 2, and 3. Exact alignment along the baseline is possible for all three notes. 2028 | 2029 |
2030 | ........ ......... 2031 | ........ ......... 2032 | ........ ...2..... second 2033 | ........ ......... sidenote 2034 | ........ ......... 2035 | first ....1... ......... 2036 | sidenote ........ ......... 2037 | ........ ....3.... third 2038 | ........ ......... sidenote 2039 | ........ ......... 2040 |2041 | 2042 |
The code used to achieve this is: 2043 | 2044 |
2045 | .sidenote { flow: area(sidenote, baseline) }
2046 |
2047 |
2048 | This example is similar to the previous one, except for the placement of the third reference point: it appears much closer to the second reference point. As a result, the second sidenote pushes down the third sidenote, which is no longer exactly aligned along the baseline. 2053 | 2054 |
2055 | ........ ......... 2056 | ........ ......... 2057 | ........ ...2..... second 2058 | ........ .....3... sidenote 2059 | ........ ......... third 2060 | first ....1... ......... sidenote 2061 | sidenote ........ ......... 2062 | ........ ......... 2063 | ........ ......... 2064 | ........ ......... 2065 |2066 |
This example is similar to the previous one, except that 'baseline!' is used: 2072 | 2073 |
2074 | .sidenote { flow: area(sidenote, baseline!) }
2075 |
2076 |
2077 | As a result, the third sidnote (which cannot be granted its requested placement) is not shown: 2078 | 2079 |
2080 | ........ ......... 2081 | ........ ......... 2082 | ........ ...2..... second 2083 | ........ .....3... sidenote 2084 | ........ ......... 2085 | first ....1... ......... 2086 | sidenote ........ ......... 2087 | ........ ......... 2088 | ........ ......... 2089 | ........ ......... 2090 |2091 |
First, move an element to a named area: 2098 | 2099 |
2100 | aside { flow: area(sidenote, same-page) }
2101 |
2102 |
2103 | Then, make the element stick so that it is shown on succeeding pages: 2104 | 2105 |
2106 | h1.copy { flow: area(sidenote, same-page, stick) }
2107 |
2108 |
2113 | aside { flow: area(sidenote, same-page, erase) }
2114 |
2115 | In this example, the h1 element is copied into a running header which is defined with @area. The copied element is restyled. It erases the running header when it enters, and is set to stick (until eased by another element): 2120 | 2121 |
2122 | @page :left {
2123 | @area running-header {
2124 | position: absolute; top: -2cm; left: 0; width: 3.5cm; height: 1cm
2125 | @inside h1 {
2126 | font: 12pt sans-serif;
2127 | text-align: right;
2128 | }
2129 | }
2130 | }
2131 | @page :right {
2132 | @area running-header {
2133 | position: absolute; top: -2cm; right: 0; width: 3.5cm; height: 1cm
2134 | @inside h1 {
2135 | font: 12pt sans-serif;
2136 | text-align: right;
2137 | }
2138 | }
2139 | }
2140 |
2141 | h1 { flow: area(running-header, same-page, stick) }
2142 |
2143 | In this example, the named area called "running header" is placed in the center top of the page. It is filled with three elements, one being the copy 2148 | 2149 |
2150 | @page {
2151 | @area running-header {
2152 | position: absolute; top: -2cm; left: 0; right: 0; height: 1cm;
2153 | text-align: center;
2154 | @inside h1 {
2155 | font: 12pt sans-serif;
2156 | display: inline;
2157 | }}}
2158 |
2159 | #pagecounter {
2160 | flow: area(running-header, fill, stick); content: counter(page); }
2161 | #ornament {
2162 | flow: area(running-header, fill, stick); color: red; content: "\2747" /* snow crystal */}
2163 | h1 {
2164 | flow: area(running-header, fill, copy stick); font: 12pt serif }
2165 |
2166 | <span id=pagecounter></span>
2167 | <span id=ornament></span>
2168 | <h1>Erin Hildebrand</h1>
2169 |
2170 |
2171 | ::callElements that are floated to named areas can add a "call", similar to a footnote-call, at the place where they were floated from. 2177 | 2178 |
2180 | .sidenote {
2181 | flow: area(sidenote, same-page);
2182 | counter-increment: sn;
2183 | }
2184 | .sidenote::call {
2185 | content: counter(sn, lower-alpha); font-size: 0.6em; vertical-align: top;
2186 | }
2187 |
2188 | Margin boxes can be considered a special type of named areas. Unlike names areas, margin boxes: 2193 | 2194 |
The 'margin()' function moves elements to margin areas: 2200 | 2201 |
target-pull()To support legacy browsers, it is often better to make a link to 2213 | the note rather than including the text inline. This example shows how 2214 | to fetch the content of a note and place it in a footnote. 2215 | 2216 |
2217 | <style>
2218 | @media print {
2219 | .footnote {
2220 | float: footnote;
2221 | content: target-pull(attr(href url)) }
2222 | .call { display: none }
2223 | }
2224 | </style>
2225 | ...
2226 | <p>A sentence consists of words<a class="footnote" href="#words"> [3]</a>.
2227 | ...
2228 | <p id=words><span class="call">[3]</span> Most often.
2229 |
2230 |
2231 | When shown in a legacy browser, the content of the element will be 2232 | shown as a clickable link to an endnote. When printed according to 2233 | this specification, there will be a footnote: 2234 | 2235 |
2236 | A sentence consists of words¹. 2237 | 2238 | ¹ Most often. 2239 |2240 |
When footnotes are long or complex, it may be impractical to keep their content at the point of reference. Instead, the content of the footnote may be stored at some other point in the source file. This example shows how to fetch the content of a note and place it in a footnote. 2244 | 2245 |
2246 | <style>
2247 | @media print {
2248 | .footnote {
2249 | float: footnote;
2250 | content: target-pull(attr(href url)) }
2251 | }
2252 | </style>
2253 | ...
2254 | <p>A sentence consists of words<a class="footnote" href="#words"></a>.
2255 | ...
2256 | <div id=words>Most often, a sentence consists of words. However, some sentences also
2257 | have <em>numbers</em>. And punctuation, don't forget punctuation.</div>
2258 |
2259 | Some document formats have the capability to represent bookmarks 2277 | into the document. These bookmarks can e.g. be used to show an outline 2278 | or an index of the document. Bookmarks are typically shown outside the 2279 | document itself, often in a tree-structured and clickable table of 2280 | contents. To generate bookmarks, these properties are defined: 2281 | 'bookmark-level', 'bookmark-label', and 'bookmark-state'. 2282 | 2283 |
| Name: 2288 | | bookmark-level 2289 | |
| Value: 2291 | | none | <integer> 2292 | |
| Initial: 2294 | | none 2295 | |
| Applies to: 2297 | | all elements 2298 | |
| Inherited: 2300 | | no 2301 | |
| Percentages: 2303 | | N/A 2304 | |
| Media: 2306 | | all 2307 | |
| Computed value: 2309 | | specified value 2310 | |
This property describes what level a certain bookmark has in a 2313 | hierarchical bookmark structure. The values are: 2314 | 2315 |
| Name: 2333 | | bookmark-label 2334 | |
| Value: 2336 | | <content-list> | none 2337 | |
| Initial: 2339 | | none 2340 | |
| Applies to: 2342 | | all elements 2343 | |
| Inherited: 2345 | | no 2346 | |
| Percentages: 2348 | | N/A 2349 | |
| Media: 2351 | | all 2352 | |
| Computed value: 2354 | | specified value 2355 | |
This property specifies the label of the bookmark, i.e., the text that will represent the bookmark in the bookmark structure. This properly will only be consulted if 'bookmark-level' is different from 'none'. The values are: 2358 | 2359 |
This code would generate a simple hierachical outline of a document that uses three heading levels: 2374 | 2375 |
2376 | h1 { bookmark-level: 1 }
2377 | h2 { bookmark-level: 2 }
2378 | h3 { bookmark-level: 3 }
2379 | h1, h2, h3 { bookmark-label: content() }
2380 |
2381 | This code will make bookmarks from links. 2385 |
2386 | a[href] { bookmark-label: attr(href); bookmark-level: 1 }
2387 | a[title] { bookmark-label: attr(title); bookmark-level: 1 }
2388 |
2389 | If a title attribute exisits, its value will be used as the bookmark label. Otherwisee, the URL is used.
2390 |
This code specififies a string to be used as the bookmark label: 2394 |
2395 | #frog { bookmark-label: "The green frog"; bookmark-level: 1 }
2396 |
2397 | Consider this code: 2401 |
2402 | h1 { bookmark-label: content(before) ": " content(); bookmark-level: 1 }
2403 | h1:before { content: "Chapter" }
2404 |
2405 | <h1>Africa</h1>
2406 |
2407 |
2408 | The resulting bookmark would be: "Chapter: Africa". 2409 |
| Name: 2418 | | bookmark-state 2419 | |
| Value: 2421 | | open | closed 2422 | |
| Initial: 2424 | | open 2425 | |
| Applies to: 2427 | | block-level elements 2428 | |
| Inherited: 2430 | | no 2431 | |
| Percentages: 2433 | | N/A 2434 | |
| Media: 2436 | | all 2437 | |
| Computed value: 2439 | | specified value 2440 | |
A hierarchy of bookmarks may be shown in an open or closed state. 2443 | The user will typically be able to toggle the state to navigate in the 2444 | bookmarks. This property describes the initial state of a bookmark. 2445 | 2446 |
In this example, h1 and h2 elements are set to have an open initial bookmark stat, all other elements will be closed initially:
2448 |
2449 |
2450 | * { bookmark-state: closed }
2451 | h1, h2 { bookmark-state: open }
2452 |
2453 | A document consists of a linear sequence of pages. In simple documents, all pages have the same page area and marginalia. In more complex documents, pages may have different sizes, marginalia and orientation. Being able to style pages differently is therefore important. 2459 | 2460 |
In CSS2, first, left and right pages, as well as named pages, can be selected. This specification adds more advanced page selectors. Page selectors are similar to normal selectors in the sense that they query a data set and select parts of it. However, page selectors and normal selector are different in what they query (normal selectors query a document tree; page selectors query a sequence of pages) and what they select (normal selectors find structured elements, page selectors find formatted pages). 2461 | 2462 |
nth() page pseudo-classThe nth() construct is added to select a numbered page.
2465 |
2466 |
These are equivalent, they both select the first page of a document: 2468 |
2469 | @page :first { background: lime }
2470 | @page :nth(1) { background: lime }
2471 |
2472 | The grammar of nth-child() pseudo-class can be used with nth():
2475 |
2476 |
In this example, pages in a document will cycle through pink, lime and white backgrounds: 2478 |
2479 | @page :nth(3n) { background: pink }
2480 | @page :nth(3n+1) { background: lime }
2481 | @page :nth(3n+2) { background: white }
2482 |
2483 | A page group is a sequence of pages with the same name. Being able to style the first page of page group different from the other pages in the page group is important. To support this, the named page and the :first and :nth() selector can be combined with the page name in page selectors:
2522 |
2523 |
In this example, various background colors will be set on different pages in the "chapter" page group: 2525 |
2526 | @page chapter:first { background: pink } /* the first page */
2527 | @page chapter:nth(1) { background: pink } /* the first page */
2528 | @page chapter:nth(2) { background: lime } /* the second page */
2529 | @page chapter:nth(3n+2) { background: white } /* every third page */
2530 |
2531 | A new page group is started when an element is set to a named page which is different from the preceding element, or different from the ancestor element. 2534 | 2535 |
In this example, the first article starts a new page group due to having a different named page than its ancestor. However, the second article continues in the same page group as the first, due to having the same named page. As a result, there will only be one page with a green background. 2537 | 2538 |
2539 | @page chapter:first { background: green }
2540 | body { page: upright }
2541 | article { page: chapter }
2542 |
2543 | <body>
2544 | <article>...</article>
2545 | <article>...</article>
2546 | </body>
2547 |
2548 | To enable page groups to be created when sibling elements use the same named page, the 'break-before' and 'break-after' properties are consulted. When a forced page break has been set between the two elements (either 'break-after: page' on the first element, or 'break-before: page' on the second element), the second element will create a new page group. 2551 | 2552 |
In this example, both articles start new page groups due to there being an explicit page break between them. 2554 | 2555 |
2556 | @page chapter:first { background: lime }
2557 | body { page: upright }
2558 | article { page: chapter; break-before: page }
2559 |
2560 | <body>
2561 | <article>...</article>
2562 | <article>...</article>
2563 | </body>
2564 |
2565 | Content is sometimes displayed or hidden based on their placement 2719 | after formatting. This specification proposes the 'condition' property 2720 | to express conditions that must be met in order for the element to be 2721 | displayed; if the condition is not met, the effect will be as if 2722 | 'display: none' had been set. 2723 | 2724 |
In this example, thematic breaks within the prose is normally indicated by a few blank lines. However, if the thematic break appears at a page break, it will be indicated by three asterisks. 2726 | 2727 |
2728 | .tb:before { content: "***"; condition: at-page-break; margin: 1em 0; text-align: center; }
2729 | .tb:after { content: "\a\a\a"; condition: not-at-page-break }
2730 |
2731 | <div class=tb></div>
2732 |
2733 |
2734 | | Name: 2745 | | column-rule-clip 2746 | |
| Value: 2748 | | none | auto | [ <length> <length>? ] 2749 | |
| Initial: 2751 | | none 2752 | |
| Applies to: 2754 | | multicol elements 2755 | |
| Inherited: 2757 | | no 2758 | |
| Percentages: 2760 | | N/A 2761 | |
| Media: 2763 | | visual 2764 | |
| Computed value: 2766 | | as specified 2767 | |
Values are: 2770 | 2771 |
Spanners split column rules, and each fragment is possibly clipped by this property. 2783 | 2784 |
This section sketches several possible solutions. 2787 | 2788 | 2789 |
To select elements depending on which page they start on, these pseudo-classes can be used: 2792 | 2793 |
2794 | aside:left { background: red }
2795 | aside:right { background: green }
2796 | aside:first { background: blue }
2797 | aside:nth(4n+1) { background: pink }
2798 |
2799 | To select elements within a page, normal selectors can be combined with a page selector. 2803 | 2804 |
2806 | @page :first p { background: lime }
2807 | @page :nth(1) .sidenote { background: lime }
2808 | @page :nth(3n+1) p:first-line { background: lime }
2809 | @page funky:nth(1) p { background: pink }
2810 |
2811 | The syntax is: 2814 | 2815 |
2816 | @page \S+ <page-selector> \S+ <selector> 2817 |2818 | 2819 | 2820 |
In an alternative longhand syntax, selectors are placed inside an @inside-block: 2821 | 2822 |
These are identical: 2824 | 2825 |
2826 | @page :left {
2827 | @inside {
2828 | p { text-align: left }
2829 | }
2830 | }
2831 |
2832 | @page :left p { text-align: left }
2833 |
2834 | The longhand syntax also allows the styling of elements that appear inside page areas and margin boxes. 2837 | 2838 |
In this example, two sidenote areas are declared. Paragraphs inside those areas are given a differnet styling based on which side they are in. 2840 |
2841 | @page {
2842 | margin-left: 1cm 5cm; /* wide side margins */
2843 | @area sidenote {
2844 | @area {
2845 | position: absolute; left: -4cm; top: 0; bottom: 0; width: 3.5cm; /* left sidenote */
2846 | @inside p {
2847 | text-align: right; /* paragraphs in left sidenotes are aligned right */
2848 | }
2849 | }
2850 | @area {
2851 | position: absolute; right: -4cm; top: 0; bottom: 0; width: 3.5cm; /* right sidenote */
2852 | @inside p {
2853 | text-align: left; /* paragraphs in right sidenotes are aligned left */
2854 | }
2855 | }
2856 | }
2857 | }
2858 |
2859 |
2863 | @page :left {
2864 | background: pink; /* declaration applies to pages */
2865 | @inside {
2866 | p { text-align: left } /* declaration applies to elements on page */
2867 | }
2868 | @top-center {
2869 | background: orange; /* declaration applies to margin box */
2870 | @inside {
2871 | p { text-align: left } /* declaration applies to elements in top-center margin boxes */
2872 | }
2873 | }
2874 | }
2875 |
2876 | This section is not fully developed. 2882 | 2883 |
2885 | div.chapter:column(3) /* the 3rd column of the element */ 2886 | div.chapter:column(2n) /* all even columns of the element */ 2887 | div.chapter:column(3+) /* all columns but the 1st and 2nd */ 2888 | div.chapter:column(2,2) /* second column on second page */ 2889 | div.chapter:column(*,2) /* all columns on the second page */ 2890 | div.chapter:column(1,*) /* the first column on all pages */ 2891 |2892 |
Text in adjacent columns often use the same baselines. This appears more pleasant to typographers, and reduces show-through, where a printed line shows through to the other side of the sheet. By aligning text to a grid of baselines, a baseline rhythm is established. Subheadings and figures may disturb the baseline rhythm, but subsequent text should find it again. The 'baseline-grid' property is introduced to define, engage and clear baseline grids, while the 'baseline-block-snap' property indicates how to align elements that do not align themselves with a baseline grid. 2908 | 2909 |
| Name: 2914 | | baseline-grid 2915 | |
| Value: 2917 | | normal | none | new | root | page 2918 | |
| Initial: 2920 | | normal 2921 | |
| Applies to: 2923 | | block containers 2924 | |
| Inherited: 2926 | | no 2927 | |
| Percentages: 2929 | | N/A 2930 | |
| Media: 2932 | | visual 2933 | |
| Computed value: 2935 | | as specified 2936 | |
This property is used to define, engage, and clear baseline grids. When a baseline grid is enganged, it will be in effect on content inside the block container (including child elements) until another baseline grid is engaged, or the baseline grid is cleared. When a baseline grid is in effect, content will be aligned with the baseline grid. 2939 | 2940 |
In this example, the article element defines an enganges a baseline grid. Content inside the article will align with the baseline grid, except for headlines and figures.
2967 |
2968 |
2969 | article { baseline-grid: new }
2970 | h1, h2, figure { baseline-grid: none }
2971 |
2972 |
2973 | One possible rendition is: 2974 | 2975 |
Notice how the body text aligns with the baseline grid (shown in orange for illustration purposes), while the heading, figure and figure caption do not. After the heading and figure, the main text starts again on the next available baseline. 3025 |
In this example there are sidenotes in different scripts: 3032 | 3033 |
3034 | aside { font: 12pt serif; baseline-grid: new }
3035 | [lang=ar] { font: 10pt 'Amiri', serif }
3036 |
3037 | <aside><span lang=en>...</span></aside>
3038 | ...
3039 | <aside><span lang=ar>...</span></aside>
3040 |
3041 |
3042 | The <aside> elements establish a baseline grid from the used font (font: 12pt serif). Content inside the <aside> elements, even in different scripts, fonts and sizes, align with the baseline grid established by the <aside> elements.
3043 |
3044 |
The root baseling grid is automatically defined, but is not automatically engaged. In this example, the root baseline grid is enganged by the root element. 3049 | 3050 |
3051 | :root { baseline-grid: root }
3052 |
3053 |
3054 | The root baseline grid is handy when only a few elements want to opt-in to use a baseline grid. 3059 | 3060 |
3061 | p, li, blockquote { baseline-grid: root }
3062 |
3063 |
3064 | The 'page' baseline grid is automatically defined so that pages with different page margins still can align content to to the same baseline grid. In this example, the 'page' basedline grid is applied to all sidenotes: 3070 | 3071 |
3072 | aside { baseline-grid: page }
3073 |
3074 |
3075 | | Name: 3084 | | baseline-block-snap 3085 | |
| Value: 3087 | | [before | after | center | auto] || [margin-box | border-box] 3088 | |
| Initial: 3090 | | auto 3091 | |
| Applies to: 3093 | | elements with 'baseline-grid: new' or 'baseline-grid: none' 3094 | |
| Inherited: 3096 | | no 3097 | |
| Percentages: 3099 | | N/A 3100 | |
| Computed value: 3102 | | specified value 3103 | |
This property describes how to align content that is not aligned to a baseline grid. Values are: 3106 | 3107 |
In this example, elements that do not follow the baseline grid will snap upwards towards their older siblings. 3127 | 3128 |
3129 | h2, h2, figure {
3130 | baseline-block-snap: before;
3131 | }
3132 |
3133 |
3134 |
3135 | It is sometimes convenient to replace one character or string with another without changing the source document. The ‘text-replace’ property offers a way to perform the replacement in the style sheet. 3439 | 3440 |
| Name: 3443 | | text-replace 3444 | 3445 | |
| Value: 3447 | | [<string> <string>]+ | none 3448 | 3449 | |
| Initial: 3451 | | none 3452 | 3453 | |
| Applies to: 3455 | | all elements 3456 | 3457 | |
| Inherited: 3459 | | yes 3460 | 3461 | |
| Percentages: 3463 | | N/A 3464 | 3465 | |
| Media: 3467 | | visual 3468 | 3469 | |
| Computed value: 3471 | | as specified value 3472 | |
This property replaces all occurrences of a certain string with another string in the content of the element. The property accepts pairs of strings as value, in addition to the initial 'none' value. For each pair of strings, occurrences of the first string in the content will be replaced with the second string. If 'none' is specified, no replacements will occur. 3475 | 3476 |
3481 | 3482 |In this example, three consecutive period characters are replaced with an ellipsis character and the apostrophe character is replaced with a quotation character: 3484 | 3485 |
3486 | body { text-replace: "..." "\2026" "'" "\2019" }
3487 |
3488 |
3489 | As a result, the string "It's the beginning...!" will be changed to "It’s the beginning…!". 3490 |
In this example, a narrow no-break space is added before exclamation marks in French texts. This is known as "quart de cadratin" in French. 3494 | 3495 |
3496 | html:lang(fr) { text-replace "!" "\202F!" }
3497 |
3498 |
3499 | As a result, the string "Mais, oui!" is changed to "Mais, oui !". 3500 | 3501 |
In this example, a hair space is added before and after em-dashes. 3505 | 3506 |
3507 | body { text-replace: "—" "\200A—\200A" }
3508 |
3509 |
3510 | As a result, this string "no—not yet" is changed to "no — not yet". 3511 |
Text replacements are applied serially; the first pair of strings is applied to the textual content of the element, then the second pair of strings is applied to the outcome etc. 3526 | 3527 |
The two rules below yield the same result. In the first rule all 'a' characters are converted to 'b'. Subsequently, all 'b' characters are converted to 'c'. In the second rule, all 'a' and 'b' characters are converted directly to 'c'. 3530 | 3531 |
3532 | body { text-replace: "a" "b" "b" "c" }
3533 | body { text-replace: "a" "c" "b" "c" }
3534 |
3535 | The first string in a pair must have at least one character, while the second may be empty. 3538 | 3539 |
In this example, all 'a' characters are removed. 3541 | 3542 |
3543 | body { text-replace: "a" "" }
3544 |
3545 | If the first string of a pair is empty, or if an odd number of strings has been specified, the whole value is ignored and no text replacements are performed. Text replacements do not occur across element boundaries. 3548 | 3549 |
No text replacement will occur in this example: 3551 | 3552 |
3553 | h1 { text-replace: "foo" "bar" "" "foo" } /* ignore value */
3554 | h2 { text-replace: "foo" "bar" "foobar" } /* ignore value */
3555 | h3 { text-replace: "foobar" "barfoo" } /* accept value, but ... */
3556 |
3557 | <h3>foo<span>bar</span></h3> <!-- ... start tag breaks string which would otherwise match -->
3558 |
3559 | This property is evaluated after the content property, and before text-transform. 3562 | 3563 |
Microtypography is a range of methods for improving the appearance of text. Often, small adjustments in the space between letters and words can achieve a more even presentation with less need for hyphenation and fewer widows and orphans. This specification extends two existing CSS properties — 'letter-spacing' and 'word-spacing' — with minimum and maximum values to guide User Agents when laying out text. 3566 | 3567 |
The 'letter-spacing' and 'word-spacing' properties are extended to accept up to three values: 3571 | 3572 |
3573 | [ normal | <length> | <percentage>]{1,3}
3574 |
3575 |
3576 |
3577 |
3578 | Values are: 3579 | 3580 |
If one value is specified, it describes the optimum value, as well as the minimum and maximum values. If two values are specified, the first denotes the optimum and the minimum, and the second denotes the maximum. If three values are specified, they describe the optimum, minimum and maximum values. 3594 | 3595 |
3601 | p {
3602 | letter-spacing: -0.04em 0 0.04em;
3603 | word-spacing: -0.2em normal 0.2em;
3604 | }
3605 |
3606 | What are min/max values relative to? Are they relative to the 3611 | normal position (like the opt values are), or to the opt position? 3612 |
If we add percentage values, what are they relative to? Something other than em? CSS3 Text suggested advance measure/width for word-spacing, which probably means the space character? 3616 | 3617 |
3618 | letter-spacing: -5% 0% 5%; 3619 | letter-spacing: -5% 0% 5%; 3620 | 3621 | word-spacing: 80% 100% 120%; 3622 | word-spacing: 80% 100% 120%; 3623 |3624 |
Would it be better to only use positive numbers? Like this: 3629 |
3630 | p {
3631 | letter-spacing: 0.04em 0 0.05em;
3632 | word-spacing: 0.2em normal 0.2em;
3633 | }
3634 |
3635 | If so, one could often just use two values:: 3636 |
3637 | p {
3638 | letter-spacing: 0 0.05em;
3639 | word-spacing: normal 0.2em;
3640 | }
3641 |
3642 |
3643 | In commonly used apps, pages are often laid out spatially so that 3648 | users can nagivate from one page to another by moving up, down, right 3649 | or left. To support this feature for web content, a new @-rule is 3650 | proposed: @layout. The purpose of @layout is to describe how pages are 3651 | laid out spatially relative to the current document. 3652 | 3653 |
Four new properties are allowed inside @layout: nav-up, nav-right, nav-bottom, nav-right. 3654 | 3655 |
The name of the properties inside @layout are borrowed from CSS3 Basic User Interface Module. 3656 | 3657 |
The properties accept these values: 3658 | 3659 |
3667 | <link rel=index href="../index.html">
3668 | <link rel=previous href=g3.html>
3669 | <link rel=next href=g1.html>
3670 | ...
3671 |
3672 | @layout {
3673 | nav-up: go(index);
3674 | nav-left: go(previous);
3675 | nav-right: go(next);
3676 | }
3677 |
3678 | This functionality relies on semantics in HTML and CSS. Other languages may have other other ways to describe such semantics. One possible solution for other languages is "link[rel=index] { nav-up: attr(href) }" 3681 | 3682 |
3688 | @layout {
3689 | nav-left: back;
3690 | }
3691 |
3692 |
3701 | @layout {
3702 | nav-up: url(..);
3703 | nav-down: url(a1.html);
3704 | }
3705 |
3706 |
3715 | @layout {
3716 | nav-up: url-doc(..);
3717 | nav-down: url-doc(a1.html);
3718 | }
3719 |
3720 | Combined with the @document-rule, navigation maps can be described: 3729 | 3730 |
3731 | @document url("http://example.com/foo") {
3732 | @layout {
3733 | nav-right: link-rel(next);
3734 | }
3735 | }
3736 |
3737 | @document url("http://example.com/bar") {
3738 | @layout {
3739 | nav-up: link-rel(next);
3740 | }
3741 | }
3742 |
3743 |
3744 | alternative name: @navigation, @neighborhood, @hood
3747 | 3748 |To describe page shift effects, four new properties inside 3751 | @layout are proposed: nav-up-shift, nav-right-shift, 3752 | nav-down-shift, nav-left-shift. These properties take one of several 3753 | keyword values: 3754 | 3755 |
The proposed keyword values are loosely described. Are 3772 | there better ways to describe transitions? 3773 | 3774 |
3776 | @layout {
3777 | nav-up-shift: pan;
3778 | nav-down-shift: flip;
3779 | }
3780 |
3781 |
3800 | @page {
3801 | counter-reset: footnote;
3802 | @footnote {
3803 | counter-increment: footnote;
3804 | float: bottom;
3805 | column-span: all;
3806 | height: auto;
3807 | }
3808 | }
3809 |
3810 | ::footnote-call {
3811 | counter-increment: footnote;
3812 | content: counter(footnote, super-decimal);
3813 | }
3814 | ::footnote-marker {
3815 | content: counter(footnote, super-decimal);
3816 | }
3817 |
3818 | h1 { bookmark-level: 1 }
3819 | h2 { bookmark-level: 2 }
3820 | h3 { bookmark-level: 3 }
3821 | h4 { bookmark-level: 4 }
3822 | h5 { bookmark-level: 5 }
3823 | h6 { bookmark-level: 6 }
3824 |
3825 |
3826 | This document has been improved by Bert Bos, Michael Day, Melinda 3834 | Grant, David Baron, Markus Mielke, Steve Zilles, Ian Hickson, Elika 3835 | Etemad, Laurens Holst, Mike Bremford, Allan Sandfeld Jensen, Kelly 3836 | Miller, Werner Donné, Tarquin (Mark) Wilton-Jones, Michel Fortin, 3837 | Christian Roth, Brady Duga, Del Merritt, Ladd Van Tol, Tab Atkins Jr., 3838 | Jacob Grundtvig Refstrup, James Elmore, Ian Tindale, Murakami Shinyu, Paul E. 3839 | Merrell, Philip Taylor, Brad Kemper, Peter Linss, Daniel Glazman, Tantek Çelik, Florian Rivoal, Alex Mogilevsky, Simon Sapin, Cameron McCormack, Liam R E Quin, Peter Moulder, Morten Stenshorne, Rune Lillesveen, Lars Erik Bolstad, Anton Prowse, Michel Onoff, Dave Cramer.
3840 | 3841 | 3842 | --------------------------------------------------------------------------------