Headers and FootersEdit online
Most printed publications use page headers and footers for almost all of their pages. To define them, you will use the page margin boxes.
@page :first { @top-center { content: "How to Grow Flowers"; font-size: smaller; color: gray; } }
You can set content and style to multiple page margin boxes. You should place them in the
same parent @page rule. In the above example, the text is displayed only in
the top-center of the first page, due to the :first page
selector.
Extracting Text from Document Using String SetsEdit online
To display the title of the publication or the title of the current chapter, you will need to
extract some content from the document and use it in one or more page margin boxes. This is
possible by using a string-set property. It is similar to a variable that is
initialized to a content each time a specific element is matched.
In the following example, the text content of the H1 element is extracted
and used as a publication title and the H2 element defines the chapter
title:
h1 {
string-set: publication_title content();
}
h2 {
string-set: chapter_title content();
}
string-set property with a list of comma-separated
definitions:h1 {
string-set: publication_title content(), publication_author attr(data-author);
}The following example uses the collected strings in the top margins of the pages. It joins the publication title and the chapter title by a "/" character, then places them in the outer side of the pages (to the left for the left-side pages, to the right for the right-side pages).
@page :left { @top-left { content : string(publication_title) " / " string(chapter_title); } } @page :right { @top-right { content: string(publication_title) " / " string(chapter_title); } }
A string set may contain static text, content from the document, attributes from the element,
or counters. This is a more complex example, where a chapter number is added to the
chapter_title string set:
h1 {
counter-reset: chapter;
}
h2 {
string-set: chapter_title "Chapter (" counter(chapter) ")" content();
counter-increment: chapter;
}
Extracting Text from Document Using XPathEdit online
oxy_xpath CSS extension function to execute an XPath
expression over the input document. The main advantage is that you can execute any XPath
processing, including:- Document data retrieval
- Mathematical calculations
- If/then/else conditions
oxy_xpath in values of all properties defined in a page
rule./ or //. This is different from the case when the
oxy_xpath is used in CSS rules that match an element. In this case, the
XPath expressions are evaluated in the context of the matched element and you can use relative
paths.Suppose your document defines a creation date in a metadata section. This section may be anywhere in your document. To place the creation date in the center of the publication header:
@page { @top-center { content: "Created: " oxy_xpath("//div[@class='created']/text()"); } }
Another example is to use an image from the document in the publication header:
@page { @top-center { content: url(oxy_xpath('//img[@class='product-img']/@href')); } }
If the URL returned by oxy_xpath is not absolute, it is considered to be
relative to the CSS file. To obtain a URL relative to the XML document, you can use in the
XPath expression functions, such as resolve-uri and
document-uri:
@page { @top-center { content: url(oxy_xpath(resolve-uri(//img[@class='product-img']/@href, document-uri(/)))); } }
Multiple Lines in Headers and FootersEdit online
Sometimes you need to format the text from the header (or any page margin box) on two or more lines.
For example, suppose you want to have the following notice in the footer:
Confidential Document. Do not distribute it without written consent!
The solution is to use \a in the static content from your CSS. This is an
escape representing the line feed character in ISO-10646 (U+000A). This character
represents the generic notion of "newline" in CSS.
@page { @bottom-center { content: "Confidential Document. \a Do not distribute it without written consent!"; } }
The Page CounterEdit online
Besides the CSS counters that can be set on elements (for numbering sections, lists, tables, etc.), the CSS paged media module defines two more counters:
- page
- This counter returns the number of the current page.
- pages
- The number of total pages from the publication.
These counters are automatically updated by the publishing processor and can be used from the page margin boxes.
@page { @bottom-center { content: "Page: " counter(page); } }
Or if you need to obtain "Page 4 of 100", you simply use:
content: "Page: " counter(page) " of " counter(pages);
You can format the page counter with styles such as decimal,
roman, lower-roman:
@page table-of-contents { @top-right { content: "Contents | " counter(page, lower-roman); } }
lower-roman for the left page and decimal on the right
page) is not supported.How to Use Flexible Layout in Headers and FootersEdit online
In typical usage, the sub-regions of the header (the page margin boxes
@top-left, @top-center, @top-right) and
footer (@bottom-left, @bottom-center,
@bottom-right) are distinct regions. If you are specifying content for all
of them, the content set in one does not use space from the others. Instead, it wraps lines in
its own region.
@page { @top-left { content: "A very long publication title..."} @top-center { content: "The long organization name..."} @top-right { content: counter(page)} }
This creates a sort of table with fixed equal-sized columns, with the text wrapping inside of them.
You may need to 'merge' the center and right sub-regions for the header so that the layout engine has more room for topic titles before it wraps the title to a new line.
The solution is to eliminate the center part from the header and footer
(@top-center and @bottom-center), and move the content to
one of the sides:
@page { @top-left { content: content: "A very long publication title..."} @top-right { content: "The long organization name..." " " counter(page)} }
How to Style a Part of the Text from the HeaderEdit online
- Use an SVG image as background for a page margin box or for the entire page.
- Use the
oxy_labelconstructor. This is a function that creates a text label with a set of styles.@page { @top-right { content: oxy_label(text, "My Company", styles, "color:red; font-size: larger;") ' ' oxy_label(text, "Product", styles, "color:blue; text-decoration:underline;")); } }
You can combine theoxy_labelwithoxy_xpath, to extract and style a piece of text from the document:content: oxy_label(text, oxy_xpath("/some/xpath"), styles, "color:blue; "));
Note: These functions work only with the Chemistry CSS processor. - Use two adjacent page margin boxes, and style them
differently:
@page { @top-center { content: "First part"; color: red; text-align:right; } @top-left { content: "- Second part"; color: blue; text-align:left; } }
How to Use Dynamic Images in Headers and FootersEdit online
It is possible to dynamically change the images from the publication header or footer depending on the section.
For example, you want to place an image that describes the current section. Assuming that the titles of the sections define some metadata attribute pointing to some image file and the image references should be absolute URIs or relative to the input document.
<h2 -data-header-image="installation.png"> ... <h2 -data-header-image="configuring.png"> ...
The CSS should define a string-set that extracts the attribute value and
builds an image for it using the attr(.., url) or url
function.
attr(name, url) function resolves the reference
relative to the input XML document URI. The url(attr(name)) resolves the
reference relative to the CSS file URI.@page { margin: 1in; @top-right-corner { content: string(str); font-size:0; /* Get rid of ascent and descent to avoid spaces around the image */ } } h2 { string-set: str attr(-data-header-image, url); /* references relative to the input document */ }
Besides the attr function, you can add text:
...
string-set: str "Section... " attr(-data-header-image, url);
...