Appearance
Layout and Sizing
Frames are the fundamental building block of layout in Press. Every page is itself a frame, and you nest frames within frames to create any layout you can imagine. This guide covers how frames work, how to size them, and how to position content precisely.
The <frame> Element
A <frame> is a rectangular container that holds other elements.
xml
<frame>
<h2>Section Title</h2>
<p>Some content goes here.</p>
</frame>By default, a frame stacks its children vertically from top to bottom.
Direction: Column vs. Row
The direction attribute controls how children are arranged within a frame.
Column Direction (Default)
direction="column" (or direction="col") stacks children vertically. This is the default, so you can omit it.
xml
<frame direction="column">
<p>First paragraph (top)</p>
<p>Second paragraph (middle)</p>
<p>Third paragraph (bottom)</p>
</frame>Row Direction
direction="row" arranges children horizontally from left to right.
xml
<frame direction="row">
<frame width="50%">
<p>Left column</p>
</frame>
<frame width="50%">
<p>Right column</p>
</frame>
</frame>Width and Height
Frame dimensions can be specified using several value types.
Static Values
Use points (pt) or centimetres (cm) for exact dimensions. PDFs have 72 points per inch.
xml
<frame width="200pt" height="100pt">
<p>Exactly 200pt wide and 100pt tall.</p>
</frame>
<frame width="10cm" height="5cm">
<p>Exactly 10cm wide and 5cm tall.</p>
</frame>Parent-Relative (Percentage)
A percentage value sizes the frame relative to its parent.
xml
<frame direction="row">
<frame width="70%">
<p>This takes 70% of the parent's width.</p>
</frame>
<frame width="30%">
<p>This takes the remaining 30%.</p>
</frame>
</frame>Fill
fill causes the frame to take up all remaining space left by its siblings. This is useful when you want one element to be a fixed size and another to fill the rest.
xml
<frame direction="row" height="100%">
<frame width="200pt">
<p>Fixed sidebar (200pt wide).</p>
</frame>
<frame width="fill">
<p>Main content fills the remaining width.</p>
</frame>
</frame>Auto Sizing
If you do not specify a width or height, the frame sizes itself automatically to fully contain its content. A frame will grow as large as needed, but never larger than its parent.
xml
<frame>
<p>This frame will be exactly as tall as the paragraph requires.</p>
</frame>Min/Max Constraints
You can constrain dimensions with min-width, max-width, min-height, and max-height. These accept the same value types as width and height: points, cm, or percentages.
xml
<frame min-width="200pt" max-width="80%" min-height="50pt">
<p>This frame is at least 200pt wide but no more than 80% of its
parent. It is at least 50pt tall.</p>
</frame>This is particularly useful for responsive-feeling layouts where content length varies:
xml
<frame direction="row">
<frame width="fill" min-width="150pt" max-width="300pt">
<p>Sidebar content</p>
</frame>
<frame width="fill">
<p>Main content</p>
</frame>
</frame>Absolute Positioning
By default, frames are positioned relative to their siblings -- each one follows the previous. You can override this with absolute positioning using top, left, right, and bottom. These offsets are measured from the parent frame's edges.
xml
<frame width="100%" height="100%">
<!-- This frame is pinned to the top-right corner of its parent -->
<frame top="0pt" right="0pt" width="80pt" height="30pt">
<p font-size="8pt">Page 1</p>
</frame>
<!-- This frame is pinned to the bottom-left -->
<frame bottom="10pt" left="10pt">
<p font-size="8pt">Confidential</p>
</frame>
<!-- Normal flow content is unaffected by absolutely positioned frames -->
<h1>Report Title</h1>
<p>Body content goes here.</p>
</frame>When any of top, left, right, or bottom is set, the frame becomes absolutely positioned. It no longer participates in the normal flow, meaning it will not push its siblings around and its siblings will not push it.
Alignment
h-align -- Horizontal Alignment
Controls where child blocks are positioned horizontally within a frame. Values: left (default), right, center.
xml
<frame h-align="center" width="100%">
<frame width="200pt" background-color="#eeeeee" padding="12pt">
<p>This 200pt-wide box is centred in its parent.</p>
</frame>
</frame>v-align -- Vertical Alignment
Controls where child blocks are positioned vertically within a frame. Values: top (default), bottom, center.
xml
<frame v-align="center" width="100%" height="100%">
<p>This text is vertically centred.</p>
</frame>Combining Alignment
Use both to centre content in two dimensions:
xml
<frame v-align="center" h-align="center" width="100%" height="100%">
<h1 text-align="center">Centred Title</h1>
<p text-align="center">Both vertically and horizontally centred.</p>
</frame>Note the distinction: h-align and v-align position block-level children within a frame. text-align controls the alignment of inline content (text) within a block. This allows precise control of text blocks. For instance, we can center align the block and right align the text:
xml
<frame v-align="center" h-align="center" width="100%" height="100%">
<frame width="100pt" text-align="right">Both vertically and horizontally centred but right aligned text.</frame>
</frame>Padding
Padding adds space inside the frame, between its edges and its content.
xml
<!-- Uniform padding -->
<frame padding="12pt">
<p>12pt of space on all sides.</p>
</frame>
<!-- Per-side padding -->
<frame padding-top="24pt" padding-bottom="12pt"
padding-left="16pt" padding-right="16pt">
<p>Different padding on each side.</p>
</frame>When you set width or height on a frame, those dimensions include borders and padding.
Background Color
Apply a solid background to any frame using background-color.
xml
<frame background-color="#2c3e50" padding="16pt">
<p font-color="#ffffff">White text on a dark background.</p>
</frame>This works with any supported color format -- hex, rgb, rgba, hsl, or named colors.
Border Radius
The border-radius attribute rounds the corners of a frame's background and border.
xml
<frame background-color="#3498db" padding="16pt" border-radius="8pt">
<p font-color="white">Rounded corners at 8pt radius.</p>
</frame>Borders
Use border-weight and border-color to add borders. Like padding and margin, these can be set per side.
xml
<!-- Full border -->
<frame border-weight="1pt" border-color="#cccccc" padding="12pt">
<p>Bordered frame.</p>
</frame>
<!-- Bottom border only (like a divider) -->
<frame border-weight-bottom="2pt" border-color-bottom="#333333"
padding-bottom="8pt" margin-bottom="8pt">
<h2>Section Title</h2>
</frame>Spacing Between Siblings
The space-before-desired and space-after-desired attributes control the gap between a frame and its preceding or following sibling. Spacing is not applied if there is no sibling in the direction specified.
xml
<h2 space-after-desired="6pt">Findings</h2>
<p space-before-desired="6pt" space-after-desired="12pt">
The analysis revealed three primary trends...
</p>
<p space-before-desired="12pt">
Additionally, the data suggests...
</p>You can set these globally in <styles> to apply consistent spacing throughout the document:
xml
<styles>
<h2>
<space-before-desired>18pt</space-before-desired>
<space-after-desired>8pt</space-after-desired>
</h2>
<p>
<space-before-desired>6pt</space-before-desired>
</p>
</styles>Nesting Frames for Complex Layouts
The real power of frames comes from nesting. You combine direction="row" and direction="column" frames to build any layout.
Example: Two-Column Layout
xml
<press>
<document format="A4" page-margin="2cm">
<page>
<h1>Research Summary</h1>
<frame direction="row" width="100%">
<frame width="48%">
<h3>Methodology</h3>
<p>We surveyed 500 participants across three regions
using a standardised questionnaire.</p>
</frame>
<frame width="4%" />
<frame width="48%">
<h3>Key Findings</h3>
<p>Response rates exceeded 85% in all regions, with
the highest participation in the northern district.</p>
</frame>
</frame>
</page>
</document>
</press>Example: Sidebar and Main Content
xml
<press>
<document format="A4" page-margin="1.5cm">
<page>
<frame direction="row" width="100%" height="100%">
<!-- Sidebar -->
<frame width="30%" background-color="#f5f5f5" padding="12pt">
<h3 font-size="11pt">Contents</h3>
<p font-size="9pt">1. Overview</p>
<p font-size="9pt">2. Methodology</p>
<p font-size="9pt">3. Results</p>
<p font-size="9pt">4. Conclusion</p>
</frame>
<!-- Main content -->
<frame width="70%" padding-left="16pt">
<h1>Annual Sustainability Report</h1>
<p>Oakridge Environmental Services has committed to
reducing carbon emissions by 40% over the next decade.</p>
<h2>Overview</h2>
<p>This report details our progress towards the
targets set in the 2024 sustainability framework.</p>
</frame>
</frame>
</page>
</document>
</press>Example: Centred Card
xml
<press>
<document format="A4" page-margin="2cm">
<page>
<frame v-align="center" h-align="center" width="100%" height="100%">
<frame width="70%" background-color="#ffffff"
border-weight="1pt" border-color="#dddddd"
border-radius="6pt" padding="24pt">
<h2 text-align="center">Invitation</h2>
<p text-align="center">You are cordially invited to the annual
meeting of Whitfield & Partners.</p>
<p text-align="center" font-color="#888888" font-size="10pt">
14 March 2026 | Thornton Conference Centre
</p>
</frame>
</frame>
</page>
</document>
</press>Example: Header Bar with Logo
xml
<press>
<document format="A4" page-margin="0cm">
<page>
<!-- Header bar -->
<frame direction="row" width="100%" height="4cm" background-color="#1a1a2e" padding="1.5cm" v-align="center">
<frame width="fill">
<p font-color="white" font-size="16pt">Crestwood Logistics</p>
</frame>
<frame>
<p font-color="#aaaaaa" font-size="10pt" text-align="right">
Delivery Confirmation
</p>
</frame>
</frame>
<!-- Body content with its own padding -->
<frame padding="1.5cm">
<h2>Shipment #48291</h2>
<p>Dispatched: 7 February 2026</p>
<p>Destination: 42 Elmsworth Road, Kingsbridge</p>
<table>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Weight</th>
</tr>
<tr>
<td>Flat-pack furniture set</td>
<td>2</td>
<td>34.5 kg</td>
</tr>
<tr>
<td>Kitchen appliance box</td>
<td>1</td>
<td>12.2 kg</td>
</tr>
</table>
</frame>
</page>
</document>
</press>Summary of Frame Attributes
| Attribute | Values | Description |
|---|---|---|
direction | column (default), row | Stack children vertically or horizontally |
width / height | pt, cm, %, fill, auto | Dimensions of the frame |
min-width / max-width | pt, cm, % | Constrain width |
min-height / max-height | pt, cm, % | Constrain height |
top / left / right / bottom | pt, cm | Absolute positioning offsets |
h-align | left, right, center | Horizontal alignment of children |
v-align | top, bottom, center | Vertical alignment of children |
padding | pt, cm | Inner spacing (also per-side) |
margin | pt, cm | Outer spacing (also per-side) |
background-color | Any color value | Background fill |
border-radius | pt, cm | Rounded corners |
border-weight | pt (also per-side) | Border thickness |
border-color | Any color value (also per-side) | Border color |
space-before-desired | pt, cm | Desired gap before this element |
space-after-desired | pt, cm | Desired gap after this element |