The @page At-Rule
The @page at-rule is the cornerstone of CSS Paged Media. Defined in the W3C CSS Paged Media Module Level 3, it allows you to specify properties that apply to the page box—the rectangular region that contains your content area and surrounding margin areas when a document is paginated.
Unlike regular CSS selectors that target HTML elements, @page targets the page itself. You cannot use element-specific properties like color or font-size inside @page. Instead, you use page descriptors: properties that control the physical characteristics of the page.
Basic Syntax
@page {
/* Page descriptors go here */
size: A4;
margin: 25mm;
}
You can also target specific pages using pseudo-class selectors or named pages:
/* First page only */
@page :first {
margin-top: 50mm;
}
/* Left-hand (even) pages */
@page :left {
margin-right: 30mm;
}
/* Right-hand (odd) pages */
@page :right {
margin-left: 30mm;
}
/* A named page */
@page landscape-page {
size: A4 landscape;
}
Allowed Descriptors Inside @page
The following descriptors can be used inside an @page block:
| Descriptor | Purpose | Example |
|---|---|---|
size |
Page dimensions and orientation | size: A4 landscape; |
margin |
Page margins (shorthand and individual) | margin: 20mm 15mm; |
page-orientation |
Physical rotation of the page | page-orientation: rotate-left; |
marks |
Crop and/or cross marks outside the page box | marks: crop cross; |
bleed |
Extent of bleed area beyond the page box | bleed: 3mm; |
orphans |
Minimum lines at bottom of a page | orphans: 3; |
widows |
Minimum lines at top of a page | widows: 3; |
Additionally, @page can contain margin at-rules (like @top-center, @bottom-right) for headers, footers, and page numbers. Those are covered in detail in the Margin Boxes & Page Numbers chapter.
The size Descriptor
The size descriptor sets the dimensions of the page box. It accepts predefined page-size keywords, explicit length values, orientation keywords, or a combination of these.
Auto (Default)
When no size is specified, the page box defaults to the target sheet size chosen by the user or application. In headless Chrome, this is US Letter (8.5in × 11in) unless overridden by the API.
@page {
size: auto;
}
Predefined Page Size Keywords
The specification defines the following named sizes. All dimensions follow the ISO 216 or North American standard:
| Keyword | Dimensions | Common Use |
|---|---|---|
A3 |
297mm × 420mm | Large posters, drawings |
A4 |
210mm × 297mm | Standard documents (most of the world) |
A5 |
148mm × 210mm | Booklets, flyers |
B4 |
250mm × 353mm | Newspapers, maps |
B5 |
176mm × 250mm | Books, magazines |
JIS-B4 |
257mm × 364mm | Japanese B4 standard |
JIS-B5 |
182mm × 257mm | Japanese B5 standard |
letter |
8.5in × 11in | Standard documents (US, Canada) |
legal |
8.5in × 14in | Legal documents (US) |
ledger |
11in × 17in | Tabloid-size spreadsheets |
/* ISO A4 */
@page {
size: A4;
}
/* US Letter */
@page {
size: letter;
}
/* ISO A5 for a booklet */
@page {
size: A5;
}
Custom Dimensions
You can specify exact width and height using any CSS length units (mm, cm, in, pt, px). The first value is width, the second is height.
/* 6x9 inch book */
@page {
size: 6in 9in;
}
/* Square page */
@page {
size: 200mm 200mm;
}
/* Receipt-style narrow page */
@page {
size: 80mm 297mm;
}
If only one length is provided, it sets both width and height (a square page):
@page {
size: 150mm; /* 150mm × 150mm */
}
Orientation: Portrait & Landscape
You can append portrait or landscape to any size keyword or custom dimension pair. Portrait is the default.
/* A4 landscape */
@page {
size: A4 landscape;
}
/* Letter landscape */
@page {
size: letter landscape;
}
/* Custom size, landscape orientation */
@page {
size: 6in 9in landscape;
}
When you specify landscape, the browser swaps the width and height. So A4 landscape produces a page that is 297mm wide and 210mm tall.
Tip: If you only need some pages in landscape, use named pages to assign different
@pagerules to different sections of your document.
Margins
The margin shorthand and the individual margin-top, margin-right, margin-bottom, and margin-left properties work inside @page exactly as they do on elements, except they apply to the page box itself.
@page {
size: A4;
margin: 20mm; /* All four sides */
}
@page {
size: A4;
margin: 25mm 20mm; /* Top/bottom: 25mm, Left/right: 20mm */
}
@page {
size: A4;
margin: 30mm 20mm 25mm 20mm; /* Top, right, bottom, left */
}
How Margins Interact with Margin Boxes
Page margins serve a dual purpose. They provide whitespace around your content and define the regions where margin boxes live. Margin boxes like @top-center and @bottom-right are placed inside the page margin area. If your margins are too small, margin box content may overlap with page content or be clipped.
A practical recommendation for most PDF documents:
@page {
size: A4;
margin: 20mm 15mm 25mm 15mm;
@bottom-center {
content: counter(page);
font-size: 9pt;
}
}
The extra 5mm on the bottom margin (compared to the sides) gives room for the page number without crowding the content area.
Asymmetric Margins for Book Layouts
For bound documents, you typically want a wider inner margin (the gutter) to account for the binding. Use the :left and :right page selectors:
@page :left {
margin: 20mm 15mm 20mm 25mm; /* Wider right margin (inner) */
}
@page :right {
margin: 20mm 25mm 20mm 15mm; /* Wider left margin (inner, mirrored) */
}
The page-orientation Descriptor
The page-orientation descriptor is distinct from the landscape keyword used with size. While size: A4 landscape swaps the dimensions of the page (making it wider than tall), page-orientation physically rotates the page in the output medium without changing the layout dimensions.
Values
| Value | Effect |
|---|---|
upright |
No rotation (default). The page is displayed as laid out. |
rotate-left |
The page is rotated 90° counter-clockwise. Content that was at the top is now on the left. |
rotate-right |
The page is rotated 90° clockwise. Content that was at the top is now on the right. |
@page {
size: A4;
page-orientation: rotate-left;
}
size: landscape vs page-orientation
These two approaches produce different results:
| Approach | Layout | Physical Page |
|---|---|---|
size: A4 landscape |
Content flows in a 297 × 210mm area | Page is 297mm wide, 210mm tall |
size: A4; page-orientation: rotate-left; |
Content flows in a 210 × 297mm area (portrait) | The entire page is rotated 90° in the viewer |
Use size: landscape when you want the layout to be wider than tall. Use page-orientation when you want the content to be laid out in portrait but the physical sheet to be rotated (useful for wide tables or charts that should print sideways).
Marks and Bleed
The marks and bleed descriptors are advanced properties used primarily in professional print production. They add crop marks and registration marks outside the page box and define a bleed area where content extends beyond the trim edge.
The marks Descriptor
The marks descriptor adds marks outside the page area that help a print shop align and trim pages:
| Value | Description |
|---|---|
none |
No marks (default) |
crop |
Crop marks indicating where the page should be trimmed |
cross |
Registration marks for aligning color separations |
crop cross |
Both crop and registration marks |
@page {
size: A4;
marks: crop cross;
}
The bleed Descriptor
Bleed is the area beyond the page box where content is allowed to extend. This prevents white edges when a page is trimmed. The standard bleed in print is 3mm:
@page {
size: A4;
marks: crop;
bleed: 3mm;
}
The bleed property only has an effect when marks is set to a value other than none. If marks is none, the bleed area is suppressed.
Browser Support for Marks & Bleed
Support for these properties is limited. Even Chromium has partial support—crop marks render but may not be pixel-perfect for professional prepress. For production print workflows requiring exact marks and bleed, a dedicated prepress tool or Paged.js polyfill may be needed.
Browser Support by Property
| Property | Chrome 131+ | Safari 18.2+ | Firefox 133+ |
|---|---|---|---|
@page { } |
Yes | Yes | Partial |
size (keywords) |
Yes | Yes | No |
size (custom lengths) |
Yes | Yes | No |
size + landscape/portrait |
Yes | Yes | No |
margin (shorthand & individual) |
Yes | Yes | Partial |
page-orientation |
Yes | No | No |
marks |
Partial | No | No |
bleed |
Partial | No | No |
:first selector |
Yes | Partial | Partial |
:left / :right selectors |
Yes | Partial | Partial |
:blank selector |
Yes | No | No |
Practical Examples
Invoice Setup
A typical invoice needs A4 pages with comfortable margins, a company header on the first page, and page numbers on subsequent pages:
@page {
size: A4;
margin: 20mm 15mm 25mm 15mm;
@bottom-right {
content: "Page " counter(page) " of " counter(pages);
font-size: 8pt;
color: #999;
}
}
@page :first {
margin-top: 10mm;
@bottom-right {
content: none;
}
}
The first page gets a smaller top margin (since the company logo or header block is typically at the top), and the page number is suppressed on page one.
Multi-Page Report Setup
For a corporate report with a cover page, table of contents, and body content, use named pages to apply different layouts:
/* Cover page: no margins, full-bleed background */
@page cover {
size: A4;
margin: 0;
}
/* Body pages: standard layout with header and footer */
@page body {
size: A4;
margin: 25mm 20mm 30mm 20mm;
@top-left {
content: "Quarterly Report — Q4 2025";
font-size: 8pt;
color: #666;
}
@bottom-center {
content: counter(page);
font-size: 9pt;
}
}
/* Assign named pages in HTML */
.cover { page: cover; }
.report-body { page: body; }
Custom Size for Receipts
Point-of-sale receipts typically use 80mm thermal paper. Since the length varies, you can use a tall custom size:
@page {
size: 80mm 200mm;
margin: 5mm;
}
body {
font-family: "Courier New", monospace;
font-size: 10pt;
line-height: 1.3;
}
If you are generating these via Doppio, set preferCSSPageSize: true in the API request so the output PDF matches your custom size instead of defaulting to US Letter.
Putting It All Together
Here is a comprehensive @page configuration that uses many of the features discussed:
/* Default pages */
@page {
size: A4;
margin: 25mm 20mm 30mm 20mm;
orphans: 3;
widows: 3;
@top-right {
content: string(chapter-title);
font-size: 8pt;
color: #888;
}
@bottom-center {
content: counter(page);
font-size: 9pt;
}
}
/* First page: extra top margin, no header */
@page :first {
margin-top: 40mm;
@top-right {
content: none;
}
}
/* Left pages: wider inner margin */
@page :left {
margin-left: 25mm;
margin-right: 15mm;
}
/* Right pages: wider inner margin (mirrored) */
@page :right {
margin-left: 15mm;
margin-right: 25mm;
}
/* Landscape pages for wide data tables */
@page wide {
size: A4 landscape;
margin: 15mm;
}
.data-spread { page: wide; }