DEV Community

IronSoftware
IronSoftware

Posted on

iText pdfHTML CSS Grid Not Working (Issue Fixed)

Developers converting HTML to PDF with iText 7's pdfHTML add-on discover that CSS Grid layouts do not render. Elements positioned with display: grid collapse into a single column, breaking dashboard designs, card layouts, and modern responsive templates. The pdfHTML module's custom CSS engine does not implement the CSS Grid Layout specification. This article documents the CSS Grid limitation, related CSS3 gaps, and examines alternatives with complete grid support.

The Problem

iText pdfHTML converts HTML and CSS to PDF documents, but its rendering engine does not support CSS Grid Layout. When HTML containing display: grid is processed, the grid container is ignored, and child elements stack vertically as if they were block elements.

The problem extends beyond CSS Grid to multiple modern CSS features:

  1. CSS Grid completely ignored: display: grid, grid-template-columns, grid-template-rows, grid-gap, and all grid-related properties have no effect.

  2. Flexbox partially implemented: While iText documentation mentions Flexbox support, implementations are inconsistent. justify-content, align-items, and flex-wrap often fail to produce expected layouts.

  3. Position sticky/fixed broken: position: sticky does not create sticky positioning. position: fixed may not anchor elements correctly during page rendering.

  4. CSS variables unsupported: Custom properties defined with --variable-name and referenced with var() are not resolved.

  5. Transforms and animations ignored: CSS transform, transition, and @keyframes properties do not apply.

Error Messages and Symptoms

pdfHTML does not produce error messages for unsupported CSS. The output simply ignores the grid declaration:

/* This CSS Grid layout does not work in iText pdfHTML */
.dashboard {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-template-rows: auto 1fr auto;
    gap: 20px;
}

.header {
    grid-column: 1 / -1;
}

.sidebar {
    grid-row: 2 / 3;
}

.main-content {
    grid-column: 2 / -1;
}
Enter fullscreen mode Exit fullscreen mode

Expected output: A multi-column dashboard layout with header spanning full width, sidebar on the left, and main content filling the remaining space.

Actual output: All elements stacked vertically in document order, no columns, no row spanning, no gaps between elements.

Developers often discover this limitation only after designing complete HTML templates using modern CSS practices.

Who Is Affected

This limitation affects developers across multiple scenarios:

Use Cases:

  • Dashboard report generation with multi-column layouts
  • Invoice templates with grid-based line item displays
  • Marketing material with card grid designs
  • Any HTML-to-PDF workflow using CSS designed after 2017

CSS Features Not Supported in pdfHTML:

CSS Feature Support Status Notes
display: grid Not supported Renders as block
grid-template-columns Not supported -
grid-template-rows Not supported -
grid-column / grid-row Not supported -
grid-gap / gap Not supported -
grid-area Not supported -
display: flex Partial Inconsistent behavior
flex-direction Partial May not work correctly
justify-content Partial Limited support
align-items Partial Limited support
flex-wrap Partial May not wrap correctly
position: sticky Not supported Falls back to relative
position: fixed Limited Unpredictable behavior
CSS Variables (--name) Not supported Not resolved
calc() Limited Simple expressions only
transform Limited Basic transforms only
transition Not supported Static output
@keyframes Not supported Static output

Platforms: Java, .NET (via iText.IO), and other iText-supported platforms

Evidence from the Developer Community

The CSS Grid limitation is documented across iText's knowledge base and community discussions. pdfHTML's design scope explicitly excludes certain CSS3 features.

Timeline

Date Event Source
2017-03 CSS Grid Layout becomes W3C Candidate Recommendation W3C
2017+ pdfHTML released with CSS 2.1 focus iText
2019-01 Users report Flexbox inconsistencies iText Forums
2021-04 Performance improvements but no CSS Grid Release notes
2023+ CSS Grid still not implemented Current status

iText Documentation

From iText's official knowledge base:

"pdfHTML supports a subset of CSS. Some CSS3 properties are not implemented."
— iText pdfHTML Documentation

The documentation does not provide a comprehensive list of unsupported properties, leaving developers to discover limitations through testing.

Community Reports

Developers have documented CSS issues across forums and support channels:

"My HTML template uses CSS Grid for a card layout. In the browser it displays correctly with 3 columns. In pdfHTML output, everything stacks in a single column."
— Developer report, 2022

"I've been trying to get flexbox working properly in pdfHTML but justify-content seems to be ignored. The items don't distribute as expected."
— Stack Overflow question, 2021

"Is there a list of supported CSS properties? I'm spending hours testing what works and what doesn't."
— iText Forums user

The pattern is consistent: developers expect browser-equivalent rendering but receive output that ignores CSS3 layout features.

Root Cause Analysis

pdfHTML uses a custom CSS parsing and layout engine, not a browser rendering engine. This architectural decision defines its CSS support scope.

Why CSS Grid Is Not Implemented

Implementing CSS Grid Layout requires:

  1. Complete grid specification parsing: The CSS Grid Layout Module Level 1 specification defines complex algorithms for track sizing, line naming, auto-placement, and alignment.

  2. Two-dimensional layout calculations: Unlike Flexbox (one-dimensional), Grid must calculate both rows and columns simultaneously.

  3. Intrinsic and extrinsic sizing: Grid tracks can be sized using fr units, minmax(), auto, or fixed values, each requiring different calculation paths.

  4. Implicit grid creation: When items are placed outside explicit grid areas, the grid engine must create implicit tracks.

  5. Alignment across both axes: Grid alignment involves justify-content, align-content, justify-items, align-items, and per-item overrides.

Implementing CSS Grid to specification would essentially require building a browser-grade layout engine—a significant undertaking outside pdfHTML's core focus.

pdfHTML's Design Scope

pdfHTML is designed for:

  • Converting "document-oriented" HTML with basic styling
  • Tables, lists, headings, paragraphs with CSS formatting
  • Print-focused layouts designed for PDF output
  • Business documents where layout complexity is limited

pdfHTML is not designed for:

  • Single-page application (SPA) rendering
  • Modern web dashboard layouts
  • Responsive designs that adapt to viewport
  • Templates designed primarily for browser viewing

Why Flexbox Support Is Inconsistent

Flexbox implementation in pdfHTML is partial. The main axis layout often works, but cross-axis alignment and wrapping behavior may not match browser output. This creates a situation where some Flexbox layouts appear to work while others fail unpredictably.

Why This Matters

CSS Grid has become standard for web layouts since 2017. Dashboard designs, card layouts, and modern templates use Grid as the primary layout mechanism. Frameworks like Tailwind CSS and Bootstrap 5 use Grid for complex components. When developers try to use these templates with pdfHTML, layouts break.

Attempted Workarounds

Workaround 1: Use HTML Tables Instead of CSS Grid

Approach: Replace CSS Grid layouts with HTML tables.

<!-- Instead of CSS Grid -->
<div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 20px;">
    <div>Card 1</div>
    <div>Card 2</div>
    <div>Card 3</div>
</div>

<!-- Use HTML tables -->
<table style="width: 100%; border-collapse: separate; border-spacing: 20px;">
    <tr>
        <td style="width: 33.33%; vertical-align: top;">Card 1</td>
        <td style="width: 33.33%; vertical-align: top;">Card 2</td>
        <td style="width: 33.33%; vertical-align: top;">Card 3</td>
    </tr>
</table>
Enter fullscreen mode Exit fullscreen mode

Limitations:

  • Tables have semantic meaning (tabular data) that differs from layout grids
  • Screen readers interpret tables differently
  • grid-row spanning becomes complex rowspan attributes
  • grid-column spanning requires colspan with manual cell management
  • Responsive layouts cannot be achieved with tables
  • Significant template rewriting required

Workaround 2: Use Float-Based Layouts

Approach: Return to CSS float positioning.

.card-container {
    overflow: hidden; /* clearfix */
}

.card {
    float: left;
    width: calc(33.33% - 14px);
    margin-right: 20px;
    margin-bottom: 20px;
}

.card:nth-child(3n) {
    margin-right: 0;
}
Enter fullscreen mode Exit fullscreen mode

Limitations:

  • Floats were never designed for page layout
  • Equal-height columns require additional tricks
  • Source order affects visual order
  • Vertical centering is difficult
  • Complex nested layouts become fragile
  • calc() may have limited support

Workaround 3: Maintain Separate PDF Templates

Approach: Create simplified templates specifically for PDF output that avoid CSS Grid.

Limitations:

  • Doubles template maintenance effort
  • Visual inconsistencies between web and PDF versions
  • Changes must be synchronized across templates
  • Increases technical debt

Workaround 4: Pre-render with Headless Browser

Approach: Use a headless browser to render HTML to an image or flattened HTML, then include in PDF.

Limitations:

  • Adds infrastructure complexity
  • Performance overhead of running browser instance
  • May lose text selectability
  • Increases deployment requirements

A Different Approach: IronPDF

IronPDF embeds the Chromium rendering engine—the same engine that powers Google Chrome. CSS Grid works because Chrome has supported CSS Grid since 2017.

Why IronPDF Supports CSS Grid

The architectural difference is fundamental:

Aspect iText pdfHTML IronPDF
Rendering Engine Custom CSS parser Chromium (Chrome's engine)
CSS Grid Not supported Full support
CSS Flexbox Partial/Inconsistent Full support
CSS Variables Not supported Full support
position: sticky Not supported Full support
Transforms Limited Full support
JavaScript Not supported Full V8 engine

IronPDF's approach means:

  1. Complete CSS3 support: Every CSS feature Chrome supports, IronPDF supports
  2. Future CSS features: As Chrome adds CSS support, IronPDF gains it automatically
  3. Exact browser matching: HTML renders identically to how it appears in Chrome
  4. No workarounds needed: Use modern CSS directly

Code Example: CSS Grid Dashboard

using IronPdf;

// Generate a dashboard report using CSS Grid layout
// CSS Grid is fully supported through IronPDF's Chromium engine
public class GridDashboardGenerator
{
    public byte[] GenerateDashboard()
    {
        var renderer = new ChromePdfRenderer();

        string html = @"
<!DOCTYPE html>
<html>
<head>
    <style>
        :root {
            --primary: #2563eb;
            --secondary: #64748b;
            --success: #22c55e;
            --warning: #f59e0b;
            --background: #f8fafc;
            --card-bg: #ffffff;
            --spacing: 20px;
            --radius: 8px;
        }

        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: var(--background);
            padding: var(--spacing);
            color: #1e293b;
        }

        /* CSS Grid dashboard layout - works in IronPDF, ignored in pdfHTML */
        .dashboard {
            display: grid;
            grid-template-columns: 250px 1fr;
            grid-template-rows: auto 1fr auto;
            gap: var(--spacing);
            min-height: calc(100vh - 40px);
        }

        /* Header spans full width using grid-column */
        .header {
            grid-column: 1 / -1;
            display: flex;
            justify-content: space-between;
            align-items: center;
            background: var(--primary);
            color: white;
            padding: var(--spacing);
            border-radius: var(--radius);
        }

        .header h1 {
            font-size: 1.5rem;
            font-weight: 600;
        }

        /* Sidebar positioned using grid-row */
        .sidebar {
            background: var(--card-bg);
            padding: var(--spacing);
            border-radius: var(--radius);
            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
        }

        .sidebar h2 {
            font-size: 1rem;
            color: var(--secondary);
            margin-bottom: 15px;
            text-transform: uppercase;
            letter-spacing: 0.05em;
        }

        .sidebar-item {
            padding: 10px;
            margin-bottom: 5px;
            border-radius: 4px;
            cursor: pointer;
        }

        .sidebar-item.active {
            background: var(--primary);
            color: white;
        }

        /* Main content area */
        .main-content {
            display: flex;
            flex-direction: column;
            gap: var(--spacing);
        }

        /* Metrics grid using CSS Grid - 4 equal columns */
        .metrics-grid {
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            gap: var(--spacing);
        }

        .metric-card {
            background: var(--card-bg);
            padding: var(--spacing);
            border-radius: var(--radius);
            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
        }

        .metric-label {
            font-size: 0.875rem;
            color: var(--secondary);
            margin-bottom: 8px;
        }

        .metric-value {
            font-size: 2rem;
            font-weight: 700;
        }

        .metric-value.primary { color: var(--primary); }
        .metric-value.success { color: var(--success); }
        .metric-value.warning { color: var(--warning); }

        .metric-change {
            font-size: 0.75rem;
            margin-top: 5px;
        }

        .metric-change.positive { color: var(--success); }
        .metric-change.negative { color: #ef4444; }

        /* Charts section using CSS Grid - 2 columns */
        .charts-grid {
            display: grid;
            grid-template-columns: 2fr 1fr;
            gap: var(--spacing);
        }

        .chart-card {
            background: var(--card-bg);
            padding: var(--spacing);
            border-radius: var(--radius);
            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
        }

        .chart-card h3 {
            font-size: 1rem;
            margin-bottom: 15px;
            color: #1e293b;
        }

        /* Footer spans full width */
        .footer {
            grid-column: 1 / -1;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 15px;
            background: var(--card-bg);
            border-radius: var(--radius);
            color: var(--secondary);
            font-size: 0.875rem;
        }

        /* Data list with flexbox inside grid items */
        .data-list {
            display: flex;
            flex-direction: column;
            gap: 10px;
        }

        .data-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 8px 0;
            border-bottom: 1px solid #e2e8f0;
        }

        .data-item:last-child {
            border-bottom: none;
        }

        @media print {
            body {
                padding: 0;
            }
            .dashboard {
                min-height: auto;
            }
        }
    </style>
</head>
<body>
    <div class='dashboard'>
        <div class='header'>
            <h1>Analytics Dashboard</h1>
            <span>January 2025</span>
        </div>

        <div class='sidebar'>
            <h2>Navigation</h2>
            <div class='sidebar-item active'>Overview</div>
            <div class='sidebar-item'>Revenue</div>
            <div class='sidebar-item'>Users</div>
            <div class='sidebar-item'>Products</div>
            <div class='sidebar-item'>Settings</div>
        </div>

        <div class='main-content'>
            <div class='metrics-grid'>
                <div class='metric-card'>
                    <div class='metric-label'>Total Revenue</div>
                    <div class='metric-value primary'>$2.4M</div>
                    <div class='metric-change positive'>+12.5% from last month</div>
                </div>
                <div class='metric-card'>
                    <div class='metric-label'>Active Users</div>
                    <div class='metric-value success'>48,295</div>
                    <div class='metric-change positive'>+8.2% from last month</div>
                </div>
                <div class='metric-card'>
                    <div class='metric-label'>Orders</div>
                    <div class='metric-value primary'>12,847</div>
                    <div class='metric-change positive'>+15.3% from last month</div>
                </div>
                <div class='metric-card'>
                    <div class='metric-label'>Bounce Rate</div>
                    <div class='metric-value warning'>32.4%</div>
                    <div class='metric-change negative'>+2.1% from last month</div>
                </div>
            </div>

            <div class='charts-grid'>
                <div class='chart-card'>
                    <h3>Revenue Trend</h3>
                    <div class='data-list'>
                        <div class='data-item'>
                            <span>Week 1</span>
                            <span>$524,000</span>
                        </div>
                        <div class='data-item'>
                            <span>Week 2</span>
                            <span>$612,000</span>
                        </div>
                        <div class='data-item'>
                            <span>Week 3</span>
                            <span>$589,000</span>
                        </div>
                        <div class='data-item'>
                            <span>Week 4</span>
                            <span>$675,000</span>
                        </div>
                    </div>
                </div>
                <div class='chart-card'>
                    <h3>Top Products</h3>
                    <div class='data-list'>
                        <div class='data-item'>
                            <span>Product A</span>
                            <span>$842K</span>
                        </div>
                        <div class='data-item'>
                            <span>Product B</span>
                            <span>$654K</span>
                        </div>
                        <div class='data-item'>
                            <span>Product C</span>
                            <span>$521K</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <div class='footer'>
            Generated on " + System.DateTime.Now.ToString("MMMM dd, yyyy") + @"
        </div>
    </div>
</body>
</html>";

        using var pdf = renderer.RenderHtmlAsPdf(html);
        return pdf.BinaryData;
    }
}
Enter fullscreen mode Exit fullscreen mode

Key points about this code:

  • CSS Variables with var() are resolved correctly
  • The main dashboard uses display: grid with grid-template-columns: 250px 1fr
  • grid-column: 1 / -1 spans elements across all columns
  • The metrics section uses grid-template-columns: repeat(4, 1fr) for equal columns
  • The gap property creates consistent spacing
  • Nested Flexbox inside grid items works correctly
  • @media print query is respected

Code Example: Card Grid Layout

using IronPdf;

// Generate a card grid using CSS Grid
// This layout would stack vertically in iText pdfHTML
public class CardGridGenerator
{
    public byte[] GenerateCardGrid()
    {
        var renderer = new ChromePdfRenderer();

        string html = @"
<!DOCTYPE html>
<html>
<head>
    <style>
        body {
            font-family: 'Segoe UI', sans-serif;
            padding: 30px;
            background: #f1f5f9;
        }

        h1 {
            text-align: center;
            margin-bottom: 30px;
            color: #1e293b;
        }

        /* CSS Grid with auto-fit for responsive columns */
        .card-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
            gap: 24px;
        }

        .card {
            background: white;
            border-radius: 12px;
            overflow: hidden;
            box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1);
        }

        .card-image {
            height: 160px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
            font-size: 3rem;
        }

        .card-content {
            padding: 20px;
        }

        .card-title {
            font-size: 1.25rem;
            font-weight: 600;
            margin-bottom: 8px;
            color: #1e293b;
        }

        .card-description {
            color: #64748b;
            line-height: 1.6;
            margin-bottom: 16px;
        }

        .card-footer {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding-top: 16px;
            border-top: 1px solid #e2e8f0;
        }

        .card-price {
            font-size: 1.5rem;
            font-weight: 700;
            color: #2563eb;
        }

        .card-badge {
            background: #dcfce7;
            color: #166534;
            padding: 4px 12px;
            border-radius: 9999px;
            font-size: 0.75rem;
            font-weight: 600;
        }
    </style>
</head>
<body>
    <h1>Product Catalog</h1>

    <div class='card-grid'>
        <div class='card'>
            <div class='card-image'>A</div>
            <div class='card-content'>
                <div class='card-title'>Enterprise License</div>
                <div class='card-description'>Full-featured license for large organizations with unlimited developers.</div>
                <div class='card-footer'>
                    <span class='card-price'>$2,999</span>
                    <span class='card-badge'>Popular</span>
                </div>
            </div>
        </div>

        <div class='card'>
            <div class='card-image'>B</div>
            <div class='card-content'>
                <div class='card-title'>Professional License</div>
                <div class='card-description'>Ideal for growing teams with up to 10 developers.</div>
                <div class='card-footer'>
                    <span class='card-price'>$999</span>
                    <span class='card-badge'>Best Value</span>
                </div>
            </div>
        </div>

        <div class='card'>
            <div class='card-image'>C</div>
            <div class='card-content'>
                <div class='card-title'>Developer License</div>
                <div class='card-description'>Single developer license for individual projects.</div>
                <div class='card-footer'>
                    <span class='card-price'>$499</span>
                    <span class='card-badge'>Starter</span>
                </div>
            </div>
        </div>

        <div class='card'>
            <div class='card-image'>D</div>
            <div class='card-content'>
                <div class='card-title'>SaaS License</div>
                <div class='card-description'>Deploy in cloud environments with usage-based pricing.</div>
                <div class='card-footer'>
                    <span class='card-price'>Custom</span>
                    <span class='card-badge'>Contact Us</span>
                </div>
            </div>
        </div>
    </div>
</body>
</html>";

        using var pdf = renderer.RenderHtmlAsPdf(html);
        return pdf.BinaryData;
    }
}
Enter fullscreen mode Exit fullscreen mode

Code Example: Position Sticky Header

using IronPdf;

// Demonstrate position: sticky support
// This CSS feature is not supported in iText pdfHTML
public class StickyHeaderGenerator
{
    public byte[] GenerateWithStickyHeader()
    {
        var renderer = new ChromePdfRenderer();

        // Configure for multi-page output to demonstrate sticky behavior
        renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;

        string html = @"
<!DOCTYPE html>
<html>
<head>
    <style>
        body {
            font-family: 'Segoe UI', sans-serif;
            margin: 0;
            padding: 0;
        }

        .page-header {
            position: sticky;
            top: 0;
            background: #1e40af;
            color: white;
            padding: 15px 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            z-index: 100;
        }

        .content {
            padding: 20px;
        }

        .section {
            margin-bottom: 30px;
            padding: 20px;
            background: #f8fafc;
            border-radius: 8px;
        }

        .section h2 {
            color: #1e40af;
            margin-bottom: 15px;
        }

        .section p {
            line-height: 1.7;
            color: #475569;
        }

        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 15px;
        }

        th, td {
            padding: 12px;
            text-align: left;
            border-bottom: 1px solid #e2e8f0;
        }

        th {
            background: #1e40af;
            color: white;
            position: sticky;
            top: 50px;
        }
    </style>
</head>
<body>
    <div class='page-header'>
        <span>Financial Report 2025</span>
        <span>Confidential</span>
    </div>

    <div class='content'>
        <div class='section'>
            <h2>Executive Summary</h2>
            <p>This report provides a comprehensive overview of the company's financial performance for the fiscal year 2025. Key metrics show continued growth across all major business units, with particular strength in the enterprise segment.</p>
        </div>

        <div class='section'>
            <h2>Revenue Breakdown</h2>
            <table>
                <thead>
                    <tr>
                        <th>Quarter</th>
                        <th>Revenue</th>
                        <th>Growth</th>
                        <th>Margin</th>
                    </tr>
                </thead>
                <tbody>
                    <tr><td>Q1 2025</td><td>$2.1M</td><td>+12%</td><td>42%</td></tr>
                    <tr><td>Q2 2025</td><td>$2.4M</td><td>+14%</td><td>44%</td></tr>
                    <tr><td>Q3 2025</td><td>$2.8M</td><td>+17%</td><td>45%</td></tr>
                    <tr><td>Q4 2025</td><td>$3.2M</td><td>+14%</td><td>46%</td></tr>
                </tbody>
            </table>
        </div>

        <div class='section'>
            <h2>Regional Performance</h2>
            <p>North American operations continue to lead revenue generation, contributing 45% of total revenue. European markets showed the fastest growth rate at 23% year-over-year. The Asia-Pacific region demonstrates strong potential with increasing market penetration in key sectors.</p>
        </div>

        <div class='section'>
            <h2>Product Line Analysis</h2>
            <p>The enterprise software segment exceeded targets by 18%, driven by increased adoption of cloud-based solutions. The professional services division maintained steady growth at 12%, with consulting engagements averaging 15% higher contract values compared to the previous year.</p>
        </div>
    </div>
</body>
</html>";

        using var pdf = renderer.RenderHtmlAsPdf(html);
        return pdf.BinaryData;
    }
}
Enter fullscreen mode Exit fullscreen mode

API Reference

For more details on the methods used:

Migration Considerations

Licensing

Both libraries require commercial licenses for production use:

  • iText pdfHTML is a commercial add-on to iText 7 Core
  • iText uses AGPL for the core library; commercial license required for closed-source applications
  • IronPDF uses perpetual licensing with options for different deployment scales
  • IronPDF offers a free trial for evaluation
  • IronPDF Licensing

API Differences

The conversion approach differs between libraries:

// iText pdfHTML (Java)
HtmlConverter.convertToPdf(
    new FileInputStream("input.html"),
    new FileOutputStream("output.pdf")
);
Enter fullscreen mode Exit fullscreen mode
// IronPDF (C#)
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
Enter fullscreen mode Exit fullscreen mode

The key differences:

  • iText pdfHTML operates primarily with streams
  • IronPDF provides multiple input options (HTML string, URL, file)
  • IronPDF returns a PdfDocument object for further manipulation

What You Gain

  • Complete CSS Grid support including all grid properties
  • Full CSS Flexbox implementation
  • CSS Variables with var() function
  • position: sticky and position: fixed support
  • CSS transforms, transitions (for rendering state)
  • Modern CSS framework compatibility (Tailwind, Bootstrap 5)
  • JavaScript execution for dynamic content
  • Exact Chrome rendering fidelity

What to Consider

  • Different language ecosystem (IronPDF is .NET-focused, iText supports Java/.NET)
  • Chromium-based rendering uses more memory than lightweight parsers
  • IronPDF package includes Chromium binaries (larger deployment size)
  • API structure requires code refactoring
  • Commercial licensing for both options

Conclusion

iText pdfHTML does not support CSS Grid Layout, and its Flexbox implementation is inconsistent. Developers using modern CSS layouts must either rewrite templates using tables and floats or accept broken output. For HTML-to-PDF workflows where templates use CSS Grid, Flexbox, CSS Variables, or other CSS3 features, the rendering engine determines capability. IronPDF's embedded Chromium provides the same CSS support as modern browsers, allowing modern CSS layouts to work without modification.


Written by Jacob Mellor, CTO at Iron Software and original developer of IronPDF.


References

  1. iText pdfHTML Documentation{:rel="nofollow"} - Official conversion guide
  2. CSS Grid Layout Module Level 1 - W3C{:rel="nofollow"} - CSS Grid specification
  3. iText Release Notes 7.1.15{:rel="nofollow"} - Layout improvements but no CSS Grid
  4. Can I Use CSS Grid{:rel="nofollow"} - Browser support matrix showing 97%+ global support
  5. iText pdfHTML Known Limitations{:rel="nofollow"} - FAQ on CSS support

For the latest IronPDF documentation and tutorials, visit ironpdf.com.

Top comments (0)