SyntaxdocSyntaxdoc

Page Breaks

Control page breaks for perfect multi-page PDFs with automatic table splitting

Control how content flows across pages with intelligent page break management. SyntaxDoc automatically optimizes page breaks for tables, headings, and content blocks.


Automatic Page Break Optimization

SyntaxDoc automatically enhances your PDFs with smart page break handling:

  • Large tables automatically split across pages with repeating headers
  • Headings stay with their following content (no orphaned titles)
  • Table rows grouped intelligently to avoid awkward breaks
  • Paragraphs optimized to prevent widows and orphans
  • Images and figures kept together without splitting

Page break optimization is enabled by default for all PDFs. No configuration needed!


Manual Page Break Control

Use CSS classes to manually control page breaks in your HTML:

Break Before Element

Force a page break before an element:

<div class="page-break-before">
  <h1>Chapter 2</h1>
  <p>This content starts on a new page...</p>
</div>

Break After Element

Force a page break after an element:

<section>
  <h1>Chapter 1</h1>
  <p>Content here...</p>
</section>
<div class="page-break-after"></div>

<section>
  <h1>Chapter 2</h1>
  <!-- Starts on new page -->
</section>

Prevent Page Breaks

Keep content together on the same page:

<div class="keep-together">
  <h2>Important Notice</h2>
  <p>This heading and paragraph will always stay together.</p>
</div>

Alternative: No Page Break

<div class="no-page-break">
  <h3>Summary</h3>
  <ul>
    <li>Point 1</li>
    <li>Point 2</li>
    <li>Point 3</li>
  </ul>
</div>

Data Attributes (Easy Method)

Use data- attributes for even simpler control:

<!-- Break before this element -->
<section data-page-break="before">
  <h1>New Chapter</h1>
</section>

<!-- Break after this element -->
<section data-page-break="after">
  <h1>End of Chapter</h1>
</section>

<!-- Keep this together -->
<div data-keep-together>
  <h2>Pricing Table</h2>
  <table>...</table>
</div>

<!-- Avoid breaking this -->
<div data-page-break="avoid">
  <p>Important content that should not be split.</p>
</div>

Data attributes are processed automatically during PDF generation and converted to the appropriate CSS classes.


Available CSS Classes

ClassDescription
page-break-beforeForce page break before element
page-break-afterForce page break after element
no-page-breakPrevent page break inside element
keep-togetherSame as no-page-break
section-breakSame as page-break-after
no-page-break-beforePrevent page break before element
no-page-break-afterPrevent page break after element

Large Table Handling

Tables with more than 20 rows are automatically optimized:

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Email</th>
      <th>Status</th>
    </tr>
  </thead>
  <tbody>
    <!-- 100+ rows -->
    <tr><td>John Doe</td><td>john@example.com</td><td>Active</td></tr>
    <tr><td>Jane Smith</td><td>jane@example.com</td><td>Active</td></tr>
    <!-- More rows... -->
  </tbody>
</table>

Automatic Optimizations:

  • ✅ Table headers (<thead>) repeat on each page
  • ✅ Rows are grouped in sets of 5 for better visual breaks
  • ✅ Table footers (<tfoot>) appear at bottom of each page
  • ✅ Individual rows never split across pages

Always use <thead> for table headers if you want them to repeat on each page!


Complete Example

Generate a multi-page report with perfect page breaks:

<!DOCTYPE html>
<html>
<head>
  <style>
    body { font-family: Arial, sans-serif; padding: 40px; }
    h1 { color: #2c3e50; }
    table { width: 100%; border-collapse: collapse; }
    th, td { padding: 10px; border: 1px solid #ddd; text-align: left; }
    th { background: #f8f9fa; font-weight: 600; }
  </style>
</head>
<body>
  <!-- Cover Page -->
  <div data-keep-together>
    <h1>Annual Report 2024</h1>
    <p>Company Name Inc.</p>
    <p>Published: December 2024</p>
  </div>
  
  <!-- Force new page for table of contents -->
  <div class="page-break-before">
    <h2>Table of Contents</h2>
    <ul>
      <li>Executive Summary</li>
      <li>Financial Overview</li>
      <li>Detailed Transactions</li>
    </ul>
  </div>
  
  <!-- Executive Summary on new page -->
  <div class="page-break-before">
    <h2>Executive Summary</h2>
    <p>Revenue increased by 23% year-over-year...</p>
  </div>
  
  <!-- Financial data section -->
  <section class="page-break-before">
    <h2>Financial Overview</h2>
    
    <!-- Small table - keep together -->
    <div class="keep-together">
      <h3>Key Metrics</h3>
      <table>
        <thead>
          <tr>
            <th>Metric</th>
            <th>Value</th>
            <th>Change</th>
          </tr>
        </thead>
        <tbody>
          <tr><td>Revenue</td><td>$5.2M</td><td>+23%</td></tr>
          <tr><td>Profit</td><td>$1.8M</td><td>+31%</td></tr>
          <tr><td>Customers</td><td>12,450</td><td>+18%</td></tr>
        </tbody>
      </table>
    </div>
  </section>
  
  <!-- Large table - automatically splits across pages -->
  <section class="page-break-before">
    <h2>Detailed Transactions</h2>
    <table>
      <thead>
        <tr>
          <th>Date</th>
          <th>Description</th>
          <th>Amount</th>
          <th>Status</th>
        </tr>
      </thead>
      <tbody>
        <!-- 100+ rows of data -->
        <tr><td>2024-12-01</td><td>Payment received</td><td>$1,200</td><td>Completed</td></tr>
        <tr><td>2024-12-02</td><td>Refund processed</td><td>-$150</td><td>Completed</td></tr>
        <!-- More rows... -->
      </tbody>
    </table>
  </section>
  
  <!-- Appendix on new page -->
  <div class="page-break-before">
    <h2>Appendix</h2>
    <p>Additional notes and references...</p>
  </div>
</body>
</html>
const formData = new FormData();

formData.append('files', new Blob([htmlContent], { type: 'text/html' }), 'index.html');
formData.append('options', JSON.stringify({
  fileName: 'annual-report-2024',
  format: 'A4',
  margin: {
    top: '1cm',
    bottom: '1cm',
    left: '1.5cm',
    right: '1.5cm'
  }
}));

const response = await fetch('https://api.syntaxdoc.com/pdf/generate', {
  method: 'POST',
  headers: { 'X-API-Key': 'YOUR_API_KEY' },
  body: formData
});

const pdfBlob = await response.blob();
// Perfect page breaks automatically applied!

Best Practices

1. Use Semantic HTML

<!-- ✅ Good - uses thead -->
<table>
  <thead>
    <tr><th>Header</th></tr>
  </thead>
  <tbody>
    <tr><td>Data</td></tr>
  </tbody>
</table>

<!-- ❌ Bad - header won't repeat -->
<table>
  <tr style="font-weight: bold;"><td>Header</td></tr>
  <tr><td>Data</td></tr>
</table>
<!-- ✅ Good - heading and content stay together -->
<div class="keep-together">
  <h3>Section Title</h3>
  <p>First paragraph of content...</p>
</div>

<!-- ❌ Bad - heading might be orphaned -->
<h3>Section Title</h3>
<p>First paragraph of content...</p>

3. Use Data Attributes for Readability

<!-- ✅ Good - clear and readable -->
<section data-page-break="before">
  <h1>New Chapter</h1>
</section>

<!-- ✅ Also good - explicit classes -->
<section class="page-break-before">
  <h1>New Chapter</h1>
</section>

4. Don't Over-Constrain

<!-- ❌ Bad - too many constraints -->
<div class="no-page-break">
  <div class="keep-together">
    <div class="no-page-break-before">
      <p>Overly constrained content</p>
    </div>
  </div>
</div>

<!-- ✅ Good - minimal necessary constraints -->
<div class="keep-together">
  <h3>Title</h3>
  <p>Content that should stay with title</p>
</div>

Troubleshooting

Content Still Splitting

If content splits despite using keep-together:

  1. Content too large - If content is taller than one page, it must split
  2. Nested constraints - Avoid nesting multiple page break classes
  3. Check margins - Large margins reduce available space

Solution:

<!-- Allow content to split naturally if needed -->
<div class="page-break-inside">
  <h2>Very Long Section</h2>
  <p>Lots of content that may need to split...</p>
</div>

Table Headers Not Repeating

Ensure you're using proper <thead> tags:

<!-- ✅ Correct -->
<table>
  <thead>
    <tr><th>Column 1</th><th>Column 2</th></tr>
  </thead>
  <tbody>
    <tr><td>Data 1</td><td>Data 2</td></tr>
  </tbody>
</table>

Unexpected Page Breaks

If you're seeing unwanted breaks:

<!-- Explicitly prevent breaks -->
<div class="no-page-break">
  <h3>Keep This Together</h3>
  <p>Content here...</p>
</div>

Advanced: CSS Page Rules

For fine-grained control, use CSS @page rules:

<style>
  @page {
    size: A4;
    margin: 2cm;
  }
  
  @page :first {
    margin-top: 5cm; /* Extra space on first page */
  }
  
  @page :left {
    margin-left: 3cm; /* Wider left margin for binding */
  }
  
  @page :right {
    margin-right: 3cm;
  }
  
  /* Named pages */
  @page chapter {
    margin: 3cm;
  }
  
  .chapter-start {
    page: chapter;
    page-break-before: always;
  }
</style>

Use preferCSSPageSize: true in your options to respect CSS @page size rules.


Performance

Page break optimization adds minimal overhead:

  • Processing time: +50-100ms for typical documents
  • Large tables (100+ rows): +200-300ms
  • Memory: Negligible impact

The automatic optimization runs during HTML preprocessing before PDF generation, ensuring fast and reliable results.

On this page