IDPF Editors Draft 20120119
This version:
Latest version:
Previous version:
N/A
Authors: Peter Sorotokin ( Adobe Systems, Inc. )
Editors: Peter Sorotokin (Adobe Systems, Inc.), Brady Duga (Google, Inc.), Garth Conboy (Google, Inc.), Markus Gylling (IDPF)
Copyright © 2011, 2012 International Digital Publishing Forum™
This module defines a model for template-based paginated layouts as an extension to CSS, the style sheet language for the web. Using functionality described in the specification, content can be formatted into a sequence of richly-designed interactive pages, rather than being presented as a single scrolled container (as per the standard CSS formatting process for on-screen display) or as a scrolled container which has been simply split up into a sequence of pages (as per the standard CSS formatting process for printing).
This is a draft that has no official status at this time. It may be updated, replaced or rendered obsolete by other documents at any time. Its publication does not imply endorsement by the IDPF membership, IDPF EPUB Working Group, W3C membership or the CSS Working Group.
This module describes functionality to dynamically layout a document into a sequence of pages (or "screens"). Its primary focus is interactive display environments in which the page size and user preferred font metrics are unknown at the time of document authoring and layout has to be done on the fly. This module builds on CSS 2.1 and several CSS3 modules.
The processing model defined by this specification enables a User Agent (UA) to flow content (such as HTML) into a series of linked containers separately described by CSS page templates . The separation of content and template is prevalent in document-oriented formatting systems, and enhances content reusability, accessibility, and expressivity. This specification also defines an associated means for style property selection to be parameterized based on dynamic conditions, such as the width of the display region.
[Note: add section here for reference]
This specification consists of two parts: Page Layout , and Adaptive Styling .
Page Layout defines a way to partition a page into multiple partitions, associate content with a specified partition and add partition-specific styling, as well as defining the process by which a UA that supports this proposal flows content into partitions.
Adaptive Styling defines two supporting features to make Page Layout (and potentially other document styling functions) depend on the environment: a means to turn styling rules on and off based on conditions, and a means to perform simple calculations based on environmental parameters.
Note: all references point to the most recent versions of the specs
[TODO: clarify the history of regions and exclusions, why various decisions were made in this spec, etc]
CSS Page Templates can be viewed as an adaptation of the XSL-FO master page vocabulary and abstract formatting model to CSS syntax. XSL-FO is a W3C Recommendation that has seen adoption in certain batch processing workflows, but is much less widely used than CSS, and is not natively supported in Web browsers.
An important design constraint of this module is that a reasonable level of emulated implementation in JavaScript via existing User Agents be feasible, in order that this specification can be immediately useful and its major features can be tested in practical applications .
[TODO: explain rationale behind expressions, variables and conditionals]
Since this specification is not on W3C Recommendation track, all properties, at-rules, and CSS constructs (e.g., -epubx-expr) that it defines have to be prefixed with a vendor-specific property (e.g., -epubx-). The -epub- prefix is used where the item in question has a stable syntax in a CSS module, while -epubx- is used for items defined in this specification or in particularly unstable CSS modules.
Properties and at-rules from CSS modules that require prefixing and their specific prefixes are:
[NOTE: This section (-epubx-expr(), @-epubx-define and @-epubx-when) may be moved to a separate module]
This section defines two supporting features that enable the Page Layout processing model to dynamically depend on the current environment:
This section also defines a compatibilitiy at-rule to encapsulate all the functionality defined in this specification.
[TODO: Add examples]
Achieving complex page layouts based on dynamic conditions requires taking into account various parameters include the media characteristics (width, height) and user preferences (font size). CSS 2.1 provides limited ways to specify property values based on container dimensions (percentages) and current font size (em unit). However, this only works for some properties (e.g. it is not possible to set font size based on viewport width), and some elements (e.g. it is not possible to use viewport height if parent element height was not defined as a percentage) and different values cannot be combined (cannot specify value based on both viewport width and height).
Page Template specification defines a generalized expression value that uses function notation in this form:
-epubx-expr( <expression> )
This value can be use for any CSS property that is not a shorthand property as defined in [CSS21].
The expression syntax grammar is:
[TODO: Standardize on EBNF productions ISO/IEC 14977]
expression := cond_term
cond_term = infix_term '?' infix_term ':' infix_term | infix_term
infix_term = infix_term infix_op prefix_term | prefix_term
prefix_term = prefix_op prefix_term | term
term = simple_term | '(' cond_term ')' | call_term
call_term := func '(' args ')'
args = args ',' cond_term | cond_term
func = identifier '.' identifier | identifier
simple_term = number | number unit | string |
identifier | identifier '.' identifier
prefix_op = '-' | '!'
infix_op = '+' | '-' | '*' | '/' | '%' | '<' | '>' | '=' | '==' | '<=' | '>=' | '!=' | '&&' | '||'
Operator priorities are given by this table from highest to lowest
[Note: precedence is not captured in grammar - consider doing so]
'*', '/' , '%' |
'+', '-' |
'<', '>', '=', '==', '<=', '>=', '!=' |
'&&', '||' |
Since CSS names treat "dash" as a valid identifier character and a percent sign after a number is treated as a unit designation, it is recommended to put spaces around dash and percent signs when they are used as operators (this is similar to XPath).
Operators work with three basic data types: numbers, strings, and booleans. These data types are converted as needed following ECMAScript rules.
[Note: Types need clarification. What are the types, how do they convert?]
When an expression is evaluated the result is converted to string and parsed as a base CSS value. If the result is of type number, it is converted to string by appending "px" at the end, except when used for the properties that only accept number, but not value with a unit (opacity, z-index). If this behavior is not desired authors should explicitly convert value to string by appending an empty string as part of the expression.
The following values are predefined:
page-width width of page in CSS pixels page-height height of page in CSS pixels
Note: we need to communicate user preferences: preferred orientation for languages that support vertical writing, night mode, high contrast mode, preferred margin, preferred column width, preferred body font. Conceptually these can come from the user stylesheet, but they need to have well-defined names.
The following intrinsic functions are predefined:
Units in -epubx-expr() values are always resolved in the context of the root element in the document. Percentages are resolved based on width or height as defined by the appropriate property.
[TODO: Make explicit when calculations happen with respect CSS value calculation]
Note that -epubx-expr() values are not resolved within shorthand style definitions.
In many cases certain combination of values appear over and over. A stylesheet is more readable and efficient when these combination are factored out and given descriptive names. The ‘@-epubx-define’ rule enables this functionality.
@-epubx-define {
<name>: <value>
...
}
"name" must be a valid CSS name; "value" must be a valid CSS value or a valid "expr" calculation. Names defined by @-epubx-define rules can be used only inside expr() values (which includes other @-epubx-define rules), and wherever used the indicated value is substituted. A given name can be defined at most once at the document-level scope : these are definitions that depend on the current environment, not variables. That is, their values can not be changed by redefinition, but will change to reflect changes to underlying document characteristics (e.g. page width). Named values may be defined in terms of other named values. Order does not matter, and a value can be used before it is defined, as long as there is no circular dependencies. Redefining predefined values is strongly discouraged.
[Note: scope of definitions is not entirely determined. May change when this is moved to a new module]
Some styling rules need to be applied only under certain conditions (e.g. when viewport size is small). This can be achieved by ‘@-epubx-when’ rule:
@-epubx-when <expression> {
CSS rule
...
}
"expression" must be a valid "-epubx-expr" calculation that evaluates to "true" or "false", which determines whether the contents of the following block are enabled
The @-epubx-when rule is only intended to be used for cases when the condition either depends on some named values introduced in @-epubx-define rules, or cannot be expressed through media queries. In all other cases media queries are preferable.
[Note: Need to revisit this section, add diagam]
A flow (n.) is a named sequence of elements that should be typically displayed in that order, for example an article in a magazine or other collection of content. Initially a document is considered to have a single flow named "body" that contains the document's root element. Elements can be assigned to other flows by specifying the CSS Regions -epubx-flow-into property. Flows are created as needed when some content is assigned to them.
A partition is an area of the page where content from a particular flow can be displayed. CSS Regions specification defines a more general notion of a region which could be created inside of any element or pseudo-element. In the content of this specification, regions can only be created out of partitions; implementing regions inside content elements is not required. In many cases it takes several partitions on a sequence of pages (or on the same page) to display all of the content from a particular flow: content is said to "flow" (v.) from one partition to the next. Partitions can contain several columns. Partitions can either grow in block progression direction to accomodate content (up to a certain limit) or can be of fixed size. Partitions can be of different dimensions, in particular there is no restriction that all partitions that accomodate a particular flow should have the same column width. Partitions are specified using the @-epubx-partition rule. Flows can be assigned to partitions using the CSS Regions flow-from property.
A page master is an allocation of a page into a set of partitions. Partitions always exist in the context of a particular page master. Page masters allow authors to create visually rich presentation of content by controlling the geometry of multiple partitions on a page. A stylesheet can specify any number of page masters, a particular page master is selected for every page algorithmically. Page masters are specified using the @-epubx-page-master rule.
Partitions are somewhat similar to slot pseudo-elements in CSS3 Template Layout module when defined at the page container, rather than an element level (see Page-based templates and other templates in paged media section in CSS3 Template Layout module).
[TODO: Add a sidebar explaining this. Use the pull-quote example, using a float outside @page-template that is overridded inside the section]
All constructs defined in this specification must occur within a containing @-epubx-page-template rule. This ensures compatibility with User Agents that do not support Page Templates (since UAs are required to ignore content inside any unsupported at-rule). UA supporting this specification may also wish to activate its functionality conditionally. Determination of activation is UA-dependent and not defined here, but this could for example include ignoring Page Templates on a very small screen device unless printing, or when creating an aural rendition.
Example:
... Regular rules ...
@-epubx-page-template {
... Page Template rules ...
}
When Page Template is unsupported or not active, only regular rules are applied. When Page Template is active both regular rules and Page Template rules are applied.
When creating Page Template stylesheets, several at-rules create CSS boxes and accept many CSS properties. In particular, these are @-epubx-page-master , @-epubx-partition-group , @-epubx-partition rules. These rules can be assigned class names (similar to elements) to facilitate reuse of styles, by making them targetable by CSS class selectors. It is done by appending class(<name>) to the rule header (before opening brace ).
Informative
Flows represent a logical grouping of one or more elements in the source document into a single stream of content. A flow is created when an element is first associated with a named flow via the -epubx-flow-into property. The elements added to a flow do not need to be contiguous, nor does their location in the html DOM change. That is, adding elements to a flow does not alter the structure of the document, and all cascaded style rules applied to the elements remain in effect.
[TODO: Clean up and add to this informative section]
[Note: How to determine if and which content is eligible for a given page master: “used up”, “consumed” and “removed” are essentially the same. Define that here. Replace with “eligible for placement” or similar language.]
By assigning elements to multiple flows, a single sequence of content in the document is split into multiple sequences (one for each flow). For each flow, content is then placed into available partitions (that are marked to consume content from that flow with flow-from property) one by one. By default elements from the flow are laid out in the partition (or partition’s column) box in the order they appear in the flow. When content in one element is exhausted, the next element is laid out, as if these elements were siblings in the document tree. When the space in the partition box is exhausted, the remaining content is overflown to the next partition. When an element fits in a partition box only partially, it is broken up in the same way that elements are broken across columns and pages; the portion that did not fit is overflown to the next partition. The default processing can be altered by setting additional properties to the elements that were assigned to the flow.
[Note: This can also be an introduction to the flow section]
[Note: add flow-from and -epubx-flow-into here, with appropriate refs]
Name: |
-epubx- flow-options |
Value: |
none | [ exclusive || last || static ] |
Initial: |
none |
Applies to: |
elements for which -epubx-flow-into property was specified |
Inherited: |
no |
Percentages: |
N/A |
Media: |
visual |
Computed value: |
as specified |
The '-epubx-flow-options' property affects how an element is processed in its flow. Several options can be specified at once.
exclusive When content is selected for a partition , elements marked as exclusive are considered first. Only one element is used for a single partition and one element is always "used up" (and removed from the flow if it is not also marked as static ). If multiple elements are marked exclusive, the one that comes later is used, but also see -epubx-flow-priority . If no element is marked exclusive, elements flow into available space in the partition one by one. Partially used elements are flowed into the next available partition.
static When an element is "used up" in a partition, it is removed from the flow, unless it is marked as static. Static elements are placed in the flow again when they are used up. When determining which element to use when multiple elements are marked exclusive , element's original placement on the flow is considered, not the time when the element is placed back there by the static option.
last TODO add definition of last here, this was split out from exclusive; doublecheck that too.
Name: |
-epubx- flow-linger |
Value: |
none | <integer> |
Initial: |
none |
Applies to: |
elements for which -epubx-flow-into property was specified |
Inherited: |
no |
Percentages: |
N/A |
Media: |
visual |
Computed value: |
as specified |
The '-epubx-flow-linger' property determines for how many pages an element is kept in the flow. None means it is kept forever (but removed if used if static option is not specified). Integer must be positive and means number of pages. 1 means that it should be used on the same page it was placed in the flow.
Name: |
-epubx- flow-priority |
Value: |
<integer> |
Initial: |
0 |
Applies to: |
elements for which the -epubx-flow-into property was specified and -epubx-flow-options exclusive is on |
Inherited: |
no |
Percentages: |
N/A |
Media: |
visual |
Computed value: |
as specified |
The '-epubx-flow-priority' property defines the priority of selection among elements in a flow with -epubx-flow-options exclusive . The active (unused) element with highest priority is selected next.
[note: --- end flow section ---]
Sometimes it is necessary to keep several pieces of content together in the same column or partition or on the same page. This can be achieved using following properties defined in CSS3 Multi-column Layout Module:
These properties may be used on flow content whether or not that content is within a multi-column partition (if there are no containing columns the inside/before/after values are applied to partitions).
The 'page-master' rule defines a page master . An example:
@-epubx-page-master [ <name> ]? [ class(<name>) ]*
{
<propname>: <propvalue>;
...
@-epubx-partition
<name> {
...
}
...
}
Each page-master rule defines a separate page master . Note that page-master rules can contain property declarations, @-epubx-partition and @-epubx-partition-group rules. Property declarations are optional, but at least one @-epubx-partition or @-epubx-partition-group must be defined. The following Page Template properties are applicable:
In addition, page master may use CSS3 background styles, except that background-attachment, background-clip and background-origin are ignored.
The Page master selection algorithm is very simple: for each page the first defined page master which is enabled is used. Thus, all the complexities of page master selection are in determining if a page master is enabled or not. The most common conditions that affect page master selection are geometric ( -epubx-min-page-width and -epubx-min-page-height properties), page position in page sequence ( -epubx-page property), and content availability ( -epubx-required property).
[TODO: Add writing-mode property, explain how it changes partition growth]
The 'partition' rule defines a partition inside a page master. It simply contains property declarations:
@-epubx-partition [ <name> ]? [ class(<name>) ]*
{
<propname>: <propvalue>;
...
}
The following standard CSS2.1 and CSS3 properties are allowed in partition rule (more specific properties are also allowed where a shorthand property is listed):
The 'overflow' property of a partition is set by default to 'hidden'. Content authors may overwrite it with the 'visible' value. Other values are not supported, and using any of these values will turn the overflow property into 'hidden'.
The '-epubx-wrap-flow' property of a partition is set by default to 'both'. This causes partition to create exclusions for content in all partitions that follow this one. Content authors may overwrite it with the 'auto' (making this partition overlap content in other partitions) and 'clear'.
The following Page Template properties are applicable:
Specifying flow-from property in the partition content binds the partition to the flow: content from the flow is laid out in that partition.
[TODO: Explain use of this, using opacity and z-index]
Typically partition rules are nested directly the page-master rule. However in some cases, it is convenient to have additional CSS box that can contain several partitions. The 'partition-group' rule can be used for that purpose. Grouping does not affect partition scoping, positions or overlap behavior (partition-group CSS box size is always the same as the page size). The @-epubx-partition-group rule can contain partition and partition-group rules and the following properties:
@-epubx-partition-group [ <name> ]? [ class(<name>) ]*
{
<propname>: <propvalue>;
...
(@-epubx-partition | @-epubx-partition-group) ...
}
Properties are optional, however every @-epubx-partition-group must contain at least one @-epubx-partition or @-epubx-partition-group rule.
Name: |
-epubx-enabled |
Value: |
true | false |
Initial: |
true |
Applies to: |
@-epubx-page-master and @-epubx-partition rules |
Inherited: |
no |
Percentages: |
N/A |
Media: |
visual |
Computed value: |
true | false, see below for computation rules |
In many cases a page master or a particular partition can only be used under certain conditions. Before a page master (or a partition within the selected page master) is used it is first determined if it is enabled or not. This is done by calculating the computed value of the -epubx-enabled property. The calculation is done differently for partitions and page masters. In both cases for -epubx-enabled computed value to be ‘true' all of the following conditions must be met:
Additional conditions for partitions (all of which must be satisfied) are below. Partition is said to have an explicit height when either its height property is not auto or when both top and bottom properties are not auto.
Additional conditions for page masters:
Name: |
-epubx-page |
Value: |
<integer> |
Initial: |
not specified |
Applies to: |
@-epubx-page-master rules |
Inherited: |
no |
Percentages: |
N/A |
Media: |
visual |
Computed value: |
as specified |
Specifies that the page master or the partition is only enabled for a particular page.
Name: |
-epubx-min-page-width |
Value: |
<length> |
Initial: |
0 |
Applies to: |
@-epubx-page-master and @-epubx-partition rules |
Inherited: |
no |
Percentages: |
N/A |
Media: |
visual |
Computed value: |
absolute length |
Name: |
-epubx-min-page-height |
Value: |
<length> |
Initial: |
0 |
Applies to: |
@-epubx-page-master and @-epubx-partition rules |
Inherited: |
no |
Percentages: |
N/A |
Media: |
visual |
Computed value: |
absolute length |
These properties define minimal page dimensions for which the page master or the partition are still usable. They participate in calculation of the -epubx-enabled property computed value.
Name: |
-epubx-required |
Value: |
true | false |
Initial: |
true |
Applies to: |
@-epubx-partition rules |
Inherited: |
no |
Percentages: |
N/A |
Media: |
visual |
Computed value: |
true | false |
This property determines if this partition has to be present for page master to be usable. It is typically used to select a particular page master based on availability of content in a particular flow. It participates in calculation of the enclosing page master -epubx-enabled property computed value.
Name: |
-epubx-conflicting-partitions |
Value: |
list of partition names |
Initial: |
empty |
Applies to: |
@-epubx-partition rules |
Inherited: |
no |
Percentages: |
N/A |
Media: |
visual |
Computed value: |
as specified |
This property determines if this partition cannot be used together with one or more other partitions in the page master (e.g. because their use together would cause overlap or would be visually "conflicting"). It participates in calculation of the enclosing page master enabled property computed value.
Name: |
-epubx-required-partitions |
Value: |
list of partition names |
Initial: |
empty |
Applies to: |
@-epubx-partition rules |
Inherited: |
no |
Percentages: |
N/A |
Media: |
visual |
Computed value: |
as specified |
This property determines if this partition must be only used together with one or more other partitions in the page master. It participates in calculation of the enclosing page master -epubx-enabled property computed value.
[TODO: add snap-width or make logical property for vertical text]
Name: |
-epubx-snap-height |
Value: |
<length> | none |
Initial: |
none |
Applies to: |
@-epubx-page-master and @-epubx-partition rules |
Inherited: |
no |
Percentages: |
N/A |
Media: |
visual |
Computed value: |
as specified |
This property snaps partition vertical content position and vertical edges of overlapping floated partitions to the grid with the given interval (typically the same as line-height property for the partition's content). Partition position is always pushed down to the next grid line. Edges of the overlaps are moved up for the top edge and down for the bottom edge. Note that overlapping partitions themselves are not moved, only exclusion areas that they generate for this partition are adjusted.
Name: |
-epubx-utilization |
Value: |
<number> | auto |
Initial: |
auto |
Applies to: |
@-epubx-page-master rules |
Inherited: |
no |
Percentages: |
N/A |
Media: |
visual |
Computed value: |
as specified |
This property defines a range of content which is looked up ahead to find the content available for various partitions. If the value if "auto", user agents can employ custom heuristics or use some fixed value (1 is recommended). If value is a number, then lookup size is determined in the following manner: the area of the page is measured in square em units (an area of a square with side length equal to 1em), multiplied by the -epubx-utilization value and rounded. The result is the amount of content to look forward for this page master . Content amount is calculated in this way:
Initial steps
1. The -epubx-flow-into property of every element in the document is determined
2. elements that belong to the same flow are collected in sequence
3. @-epubx-flow rules are examined and flows with -epubx-flow-consume : all are marked as primary flows. Flow “body” is primary by default.
Note that each element is still aware of its position in the document
Values used in pagination algorithm that are conceptually attached to every element:
To produce the next page, do these steps:
1. Determine current position in the document: Find the minimal consumed-offset for all elements not fully-consumed in each primary flow. Current position is maximum of the results among all primary flows.
2. Page master selection: for each page master:
A. calculate lookup position using current position and utilization
B. Determine element eligibility. Each element in a flow is considered eligible if it is is not marked as fully consumed and it comes in the document before lookup position.
C. Determine content availability. Flow has content available if it has some eligible elements in it.
D. Determine if page master is enabled using rules in section “Conditional page master and partition usage”.
E. First enabled page master is used for the next page.
3. For each element that first became eligible on this page, set its linger-count to the value of -epubx-flow-linger property
4. For each partition on the page master, find its corresponding flow and place content in the partition using the following rules. Only eligible elements are considered.
A. If there are any exclusive elements in the flow, only consider exclusive elements. Pick the ones with the highest priority. Out of those pick only those that are marked last. If there are any, pick the last of them. If there are not elements marked as last, pick the first element. Place that single element in the partition; it may overflow and overflow should be handled normally using CSS overflow property. Mark that element as fully consumed.
B. If there are no exclusive elements, place the first not fully consumed element starting with its consumed-offest. When content in that element is exhausted, it is marked as fully consumed and the next not fully consumed element in the flow is placed. When the space in the partition is exhausted, last incompletely placed element is broken up in the same way as elements are broken across columns and pages; element is marked partially consumed and its consumed-offset is set at the break point.
5. Reset the consumed state of all static elements to not consumed and their consumed-offset to the beginning of the element
6. Subtract 1 from linger-count of all eligible elements (unless linger-count is infinity). Mark elements with negative linger counts as fully consumed.
Each @-epubx-page-master rule creates a scope for named values. In addition to the names that are defined by @-epubx-define rule, certain values related to the page master partitions can be accessed using partition name with the "dot" notation:
<partition-name>.<value-name>
or
<partition-name>.<function-name>(args...)
The following values are defined:
and side can be one of
these names correspond to positions of the edges of the corresponding box (empty corresponds to the content area) relative to the page top left corner.
The only currently defined function is
As usual, values can be used before they are defined, as long as there are no circular dependencies. Rules for calculating the actual the values of the partition properties are implicitly included in the overall dependency resolution and value calculation. The only constraint is that when the height of the partition is not specified or set to "auto", CSS rules prescribe to lay out the content to determine block height. Partitions are always layed out in the order they appear in the page master, so partition parameters can depend only on the height of the partitions that precede that partition, or of partitions that explicitly specify a height.
To apply partition-specific styling inside some partitions, CSS Regions @-epubx-region rule can be used.
For instance, in the following example content is flowed from the top single-column region into the bottom 2-column region, and @-epubx-region rule is used to increase font size in the top region only.
@-epubx-page-master
{
@-epubx-partition class(top)
{
flow-from: body;
height: 6em;
}
@-epubx-partition class(bottom)
{
top: 7em;
flow-from: body;
column-count: 2;
}
}
@-epubx-region .top
{
p { font-size: 1.1em; }
}
At most one flow rule for each flow name may exist, defining that flow's global properties as per the following example:
@-epubx-flow <name>
{
<propname>: <propvalue>;
...
}
The only property that is defined for the @-epubx-flow rule at this point is
Name: |
-epubx-flow-consume |
Value: |
some | all |
Initial: |
'all' for 'body' flow; 'some' for all other flows |
Applies to: |
@-epubx-flow rules |
Inherited: |
no |
Percentages: |
N/A |
Media: |
visual |
Computed value: |
as specified |
If -epubx-flow-consume is set to all on a particular flow, that flow is considered to be primary . Pages are generated from page masters while at least one primary flow still has content to render. When all primary flows are exhausted, the document is considered fully rendered.
[Note: This may be moved to new Adaptive layout document]
Viewport rule contains a set of properties that apply to the overall page layout. The following properties are allowed:
Width and height properties should be used together. If both are set to some length value, they define logical size of the viewport. Each page will have that size as its dimension, and all pages will be scaled up or down to fit completely into the available device viewport.
The -epubx-text-zoom property controls how content is zoomed (or more colloquially "text size increased"). When -epubx-text-zoom is set to font-size (default), zooming will increase the initial value of the font-size property (and as a result em unit). This will increase the size of everything sized in em (or ex) units. When zoom is set to scale, logical viewport size is decreased by some scale factor and the resulting pages are zoomed by the same factor to keep real viewport size the same.