When HtmlRenderer.PdfSharp CSS is not working, the cause is almost always the library's strict adherence to CSS 2.1 specification from 2011. This 15-year-old standard predates every modern CSS feature developers rely on today. Flexbox, Grid, CSS Variables, transforms, transitions, and even basic selectors like :nth-child and :not are completely unsupported.
This article documents exactly which CSS features fail in HtmlRenderer.PdfSharp, why they fail, and what developers can do when their HTML templates produce broken layouts.
The Problem
HtmlRenderer.PdfSharp is a third-party library that attempts to render HTML content using PdfSharp's PDF generation capabilities. The library explicitly targets HTML 4.01 and CSS Level 2 specifications. CSS Level 2.1 was finalized in 2011, a standard now over fifteen years old.
The practical impact: any CSS written using techniques from the last decade and a half will not render correctly. Developers attempting to convert modern web templates, Bootstrap layouts, Tailwind designs, or any HTML using contemporary CSS encounter output that looks nothing like their browser preview.
Symptoms Developers Experience
When HtmlRenderer.PdfSharp encounters unsupported CSS:
-
Flexbox layouts collapse: Elements styled with
display: flexrender asdisplay: block, causing items to stack vertically instead of horizontally -
Grid layouts fail completely:
display: gridis ignored entirely, resulting in single-column output -
CSS Variables are unresolved: Properties using
var(--custom-property)receive no styling - Transforms are ignored: Rotated watermarks appear at 0 degrees, scaled elements retain original size
-
Modern selectors match nothing:
:nth-child,:not,:first-of-typehave no effect -
Pseudo-elements disappear:
::beforeand::aftercontent is not generated - SVG graphics vanish: Inline SVG elements do not render
No error messages are produced. The failures are completely silent. Developers only discover the problems when viewing the generated PDF.
What CSS 2.1 Support Actually Means
CSS 2.1 includes only:
- Basic selectors: element, class, ID
- Font properties:
font-family,font-size,font-weight,font-style - Text properties:
color,text-align,text-decoration,line-height - Box model:
margin,padding,border,width,height - Positioning:
position(limited),top,left,right,bottom - Floats:
float,clear - Basic display:
block,inline,none,table - Background:
background-color,background-image
CSS 2.1 does not include:
- Flexbox (
display: flex) - Grid (
display: grid) - CSS Variables (
--custom-property,var()) - CSS Transforms (
transform,rotate,scale,translate) - CSS Transitions (
transition) - CSS Animations (
@keyframes,animation) - Modern pseudo-selectors (
:nth-child,:not,:has,:first-of-type) - Pseudo-elements (
::before,::after) -
calc()function box-sizing: border-box- Media queries (limited support)
-
@font-faceweb fonts (requires manual embedding) - SVG rendering
Who Is Affected
Developers using HtmlRenderer.PdfSharp encounter CSS issues across all development scenarios:
Frameworks and Environments:
- .NET Framework 4.x applications
- .NET Core and .NET 5+ projects (using community forks)
- ASP.NET MVC and ASP.NET Core web applications
- Console applications generating reports
- Windows Services performing batch PDF generation
Use Cases:
- Invoice and receipt generation with modern layouts
- Report generation from HTML templates
- Document conversion from web content
- Email-to-PDF archival systems
- Any project using Bootstrap, Tailwind, or modern CSS frameworks
Template Sources:
- Bootstrap 4 or 5 templates (Flexbox-based grid system)
- Tailwind CSS designs (utility-first, uses Flexbox and Grid extensively)
- Material Design templates
- Any HTML/CSS from 2012 or later
CSS Features That Do Not Work
The following sections document specific CSS features that HtmlRenderer.PdfSharp cannot process. Each represents a standard feature in modern web development that will fail silently.
Flexbox (display: flex) - Not Supported
CSS Flexbox is the foundation of modern web layout. HtmlRenderer.PdfSharp ignores all Flexbox properties.
/* None of these properties work */
.container {
display: flex; /* Treated as display: block */
flex-direction: row; /* Ignored */
flex-wrap: wrap; /* Ignored */
justify-content: space-between; /* Ignored */
align-items: center; /* Ignored */
gap: 20px; /* Ignored */
}
.item {
flex: 1; /* Ignored */
flex-grow: 1; /* Ignored */
flex-shrink: 0; /* Ignored */
flex-basis: 200px; /* Ignored */
order: 2; /* Ignored */
align-self: flex-end; /* Ignored */
}
Expected behavior: Items arrange horizontally with equal spacing.
Actual behavior: Items stack vertically as block elements.
A typical header layout:
<header style="display: flex; justify-content: space-between; align-items: center;">
<div class="logo">Company Name</div>
<nav>Navigation Items</nav>
</header>
This renders as two stacked blocks, not a side-by-side layout.
CSS Grid (display: grid) - Not Supported
CSS Grid provides two-dimensional layout control. HtmlRenderer.PdfSharp has zero Grid support.
/* Grid is completely unsupported */
.dashboard {
display: grid; /* Treated as display: block */
grid-template-columns: repeat(3, 1fr); /* Ignored */
grid-template-rows: auto 1fr auto; /* Ignored */
grid-gap: 20px; /* Ignored */
gap: 20px; /* Ignored */
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer"; /* Ignored */
}
.sidebar {
grid-area: sidebar; /* Ignored */
grid-column: 1; /* Ignored */
grid-row: 1 / 3; /* Ignored */
}
Expected behavior: A three-column dashboard layout.
Actual behavior: All items stack vertically in source order.
CSS Transforms - Not Supported
Transforms enable rotation, scaling, translation, and skewing. None work in HtmlRenderer.PdfSharp.
/* Transform properties are ignored */
.watermark {
transform: rotate(-45deg); /* Ignored - text appears horizontal */
transform-origin: center; /* Ignored */
}
.scaled-element {
transform: scale(1.5); /* Ignored - appears at 1x size */
}
.positioned-element {
transform: translate(50px, 100px); /* Ignored */
}
.combined-transform {
transform: rotate(15deg) scale(1.2) translateX(20px); /* All ignored */
}
Watermarks intended to appear diagonally across pages will render as horizontal text in the top-left corner.
CSS Transitions and Animations - Not Supported
Transitions and animations have no effect (though this matters less for static PDF output).
/* Transitions and animations are ignored */
.button {
transition: background-color 0.3s ease; /* Ignored */
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.animated {
animation: fadeIn 1s ease; /* Ignored */
}
CSS Variables (Custom Properties) - Not Supported
CSS Variables provide theming and reusable values. HtmlRenderer.PdfSharp cannot process them.
/* CSS Variables are not interpreted */
:root {
--primary-color: #3498db;
--secondary-color: #2c3e50;
--spacing: 16px;
--border-radius: 4px;
}
.button {
background-color: var(--primary-color); /* Receives no color */
padding: var(--spacing); /* Receives no padding */
border-radius: var(--border-radius); /* Receives no radius */
color: var(--secondary-color); /* Receives no color */
}
Expected behavior: Button with custom colors and spacing.
Actual behavior: Unstyled button, likely with black text and no background.
calc() Function - Not Supported
The calc() function enables mathematical calculations in CSS values.
/* calc() expressions are not evaluated */
.sidebar {
width: calc(100% - 250px); /* Likely ignored entirely */
}
.content {
padding: calc(10px + 2%); /* Likely ignored */
margin-top: calc(var(--spacing) * 2); /* Definitely ignored */
}
.responsive-element {
width: calc(50vw - 20px); /* Ignored */
}
Properties using calc() may be ignored entirely or cause layout errors.
Modern Pseudo-Selectors - Not Supported
Selectors introduced in CSS3 do not work.
/* These selectors are not recognized */
/* :nth-child variations */
tr:nth-child(odd) { background: #f2f2f2; } /* No alternating rows */
tr:nth-child(even) { background: white; }
tr:nth-child(3n+1) { border-left: 3px solid blue; }
li:nth-child(-n+3) { font-weight: bold; } /* First 3 items not bolded */
/* Negation pseudo-class */
.item:not(.active) { opacity: 0.5; } /* All items full opacity */
input:not([type="submit"]) { border: 1px solid gray; }
/* Structural pseudo-classes */
p:first-of-type { margin-top: 0; }
div:last-of-type { margin-bottom: 0; }
:only-child { margin: 0 auto; }
/* :has() relational pseudo-class */
.parent:has(.child) { border: 1px solid blue; } /* Not supported */
Alternating table row colors, negation selectors, and structural selectors all fail. Developers must add explicit classes to each element.
Pseudo-Elements (::before, ::after) - Not Supported
Generated content using pseudo-elements does not render.
/* Pseudo-element content is not generated */
.quote::before {
content: open-quote; /* Does not appear */
}
.quote::after {
content: close-quote; /* Does not appear */
}
.required-field::after {
content: ' *'; /* Does not appear */
color: red;
}
.clearfix::after {
content: '';
display: table;
clear: both; /* Clearfix pattern fails */
}
.icon::before {
content: '\f007'; /* Font Awesome icons don't render */
font-family: 'Font Awesome';
}
Required field indicators, decorative content, and icon fonts using pseudo-elements will not appear.
JavaScript - Not Supported
HtmlRenderer.PdfSharp has no JavaScript engine.
<!-- JavaScript is never executed -->
<script>
// This code never runs
document.getElementById('date').innerText = new Date().toLocaleDateString();
// Dynamic content generation fails
fetch('/api/data').then(r => r.json()).then(data => {
document.getElementById('content').innerHTML = data.html;
});
// Client-side rendering frameworks produce blank output
// React, Vue, Angular components won't render
</script>
Any content that depends on JavaScript for rendering will not appear. This includes:
- React, Vue, Angular single-page applications
- Dynamic content loading
- Client-side templating
- Date/time formatting via JavaScript
- Charting libraries (Chart.js, D3.js)
SVG Rendering - Not Supported
Scalable Vector Graphics support is absent or severely limited.
<!-- SVG elements may not render at all -->
<svg width="100" height="100">
<circle cx="50" cy="50" r="40" fill="#3498db"/>
<rect x="10" y="10" width="30" height="30" fill="#2ecc71"/>
<text x="50" y="55" text-anchor="middle">SVG</text>
<path d="M10 80 Q 52.5 10, 95 80 T 180 80" fill="none" stroke="black"/>
</svg>
<img src="logo.svg" alt="Logo"> <!-- SVG via img tag may also fail -->
SVG icons, charts, logos, and graphics will not appear in the PDF output.
Web Fonts (@font-face) - Manual Embedding Required
Custom fonts do not load automatically.
/* @font-face declarations are not automatically processed */
@font-face {
font-family: 'CustomFont';
src: url('fonts/custom-font.woff2') format('woff2'),
url('fonts/custom-font.woff') format('woff');
}
body {
font-family: 'CustomFont', Arial, sans-serif;
}
Google Fonts, Adobe Fonts, and self-hosted web fonts will not load. Text using undefined fonts falls back to a default system font, causing visual inconsistency with the browser preview.
Bootstrap and Tailwind Compatibility Issues
Modern CSS frameworks depend on features that HtmlRenderer.PdfSharp cannot process.
Bootstrap 5 Layouts Break
Bootstrap 5 uses Flexbox for its grid system and utility classes.
<!-- Bootstrap 5 grid system will not work -->
<div class="container">
<div class="row">
<div class="col-md-4">Column 1</div>
<div class="col-md-4">Column 2</div>
<div class="col-md-4">Column 3</div>
</div>
</div>
<!-- Flexbox utilities fail -->
<div class="d-flex justify-content-between align-items-center">
<span>Left aligned</span>
<span>Right aligned</span>
</div>
<!-- Card layouts using Flexbox collapse -->
<div class="card-group">
<div class="card">Card 1</div>
<div class="card">Card 2</div>
<div class="card">Card 3</div>
</div>
Bootstrap's row and col-* classes use display: flex. The columns will stack vertically instead of appearing side by side. Utility classes like d-flex, justify-content-*, align-items-*, and spacing utilities like gap-* are all Flexbox-based and fail.
Tailwind CSS Fails Extensively
Tailwind's utility-first approach relies heavily on unsupported CSS features.
<!-- Tailwind utilities that will not work -->
<div class="flex items-center justify-between gap-4 p-4">
<div class="flex-1">Flexible item</div>
<div class="w-1/3">Fixed width</div>
</div>
<div class="grid grid-cols-3 gap-4">
<div>Grid item 1</div>
<div>Grid item 2</div>
<div>Grid item 3</div>
</div>
<div class="transform rotate-45 scale-150">
Transformed element
</div>
<div class="bg-[var(--custom-color)]">
CSS variable usage
</div>
Flexbox utilities (flex, items-*, justify-*), Grid utilities (grid, grid-cols-*, gap-*), transform utilities (transform, rotate-*, scale-*), and arbitrary value syntax with CSS variables all fail.
Resulting Output
When Bootstrap or Tailwind HTML is processed by HtmlRenderer.PdfSharp:
- Multi-column layouts collapse to a single column
- Centered content aligns to the left
- Flexible widths become 100% width or undefined
- Grid items stack vertically
- Spacing between items disappears
- Transformed elements appear untransformed
- Custom colors and spacing from variables are lost
The PDF output does not resemble the browser preview.
Evidence from the Developer Community
Developers have documented HtmlRenderer.PdfSharp's CSS limitations across multiple platforms.
Stack Overflow Reports
Stack Overflow contains numerous questions about HtmlRenderer.PdfSharp CSS not working:
"I'm trying to convert HTML to PDF using HtmlRenderer.PdfSharp but my flexbox layouts are completely broken. The elements just stack on top of each other."
— Stack Overflow, 2023"PDFsharp with HtmlRenderer doesn't support CSS grid at all. I had to rewrite my entire template using tables."
— Stack Overflow, 2022"Is there any way to get nth-child selectors working in HtmlRenderer.PdfSharp? My alternating row colors aren't showing."
— Stack Overflow, 2021
GitHub Issues
The HtmlRenderer repository contains issues documenting these limitations:
"CSS letter-spacing property doesn't work. I've tried multiple approaches but the text always renders without spacing adjustments."
— GitHub Issue{:rel="nofollow"}"Table headers with
display: table-header-groupdon't repeat on subsequent pages as they should according to CSS spec."
— GitHub Issue #193{:rel="nofollow"}"External CSS files don't load reliably. I have to inline all my styles."
— GitHub Issue #65{:rel="nofollow"}
PdfSharp Forum Discussions
The official PdfSharp forum contains threads about CSS limitations:
"I've been struggling with float layouts. Even basic float: left doesn't work consistently."
— PdfSharp Forum{:rel="nofollow"}"Bootstrap columns don't render correctly at all. Had to switch to table-based layouts."
— PdfSharp Forum, 2022
Root Cause Analysis
The CSS limitations in HtmlRenderer.PdfSharp are architectural, not implementation oversights.
Custom Parsing Engine
HtmlRenderer uses a custom-built HTML and CSS parsing engine. This engine was designed to support HTML 4.01 and CSS Level 2.1 specifications. Adding support for CSS3 features would require:
- Extending the CSS parser to recognize new properties and values
- Implementing the layout algorithms for Flexbox and Grid
- Adding a JavaScript engine for dynamic content
- Implementing SVG rendering
- Updating constantly as web standards evolve
This would essentially mean building a browser rendering engine, a project requiring years of development and ongoing maintenance.
Why No Updates
HtmlRenderer has not seen significant feature updates in years. The project remains focused on CSS 2.1 compatibility. There is no roadmap for CSS3 support because:
- CSS3 implementation would require a near-complete rewrite
- The scope would expand to match browser development complexity
- Existing browser engines already provide this functionality
- Maintaining CSS standard compliance is a massive ongoing effort
Design Limitation vs Bug
The CSS gaps in HtmlRenderer.PdfSharp are not bugs to be fixed. They represent the boundaries of what a custom rendering engine can reasonably achieve. The library does what it was designed to do: render CSS 2.1 content. Modern CSS support was never a design goal.
Attempted Workarounds
Developers have tried various approaches to work around HtmlRenderer.PdfSharp's limitations.
Workaround 1: Float-Based Layouts
Approach: Replace Flexbox and Grid with CSS floats.
/* Fallback to float layouts */
.container {
overflow: hidden; /* clearfix */
}
.column {
float: left;
width: 33.333%;
box-sizing: border-box;
padding: 10px;
}
/* Clear float after container */
.container::after {
content: '';
display: table;
clear: both;
}
Limitations:
-
::afterpseudo-element doesn't work for clearfix - Vertical centering is difficult
- Equal-height columns require additional hacks
- Cannot replicate many Flexbox behaviors
- Responsive design becomes complex
Workaround 2: Table-Based Layouts
Approach: Use HTML tables or CSS display: table for column layouts.
<table style="width: 100%;">
<tr>
<td style="width: 33%;">Column 1</td>
<td style="width: 33%;">Column 2</td>
<td style="width: 33%;">Column 3</td>
</tr>
</table>
Or using CSS:
.table-container {
display: table;
width: 100%;
}
.table-row {
display: table-row;
}
.table-cell {
display: table-cell;
vertical-align: middle;
padding: 10px;
}
Limitations:
- Semantic HTML concerns
- Limited flexibility
- Cannot reorder items
- Nested layouts become unwieldy
- Not suitable for complex designs
Workaround 3: Inline-Block Columns
Approach: Use display: inline-block with calculated widths.
.row {
font-size: 0; /* Remove whitespace between inline-blocks */
}
.column {
display: inline-block;
width: 33.333%;
font-size: 16px; /* Reset font size */
vertical-align: top;
}
Limitations:
- Whitespace handling is fragile
- Width calculations must be precise
- Vertical alignment options are limited
- Cannot achieve spacing without margin calculations
Workaround 4: Inline Styles with Explicit Widths
Approach: Use inline styles with pixel values instead of CSS files.
<div style="width: 600px;">
<div style="float: left; width: 200px; padding: 10px;">Column 1</div>
<div style="float: left; width: 200px; padding: 10px;">Column 2</div>
<div style="float: left; width: 200px; padding: 10px;">Column 3</div>
<div style="clear: both;"></div>
</div>
Limitations:
- Maintenance nightmare
- Cannot use variables or theming
- Responsive design impossible
- Violates separation of concerns
None of these workarounds provide the functionality of modern CSS. They offer partial solutions for simple layouts but fail for complex designs.
A Different Approach: IronPDF
For developers who require modern CSS support, IronPDF provides a fundamentally different architecture. Instead of a custom CSS parser limited to 2011 specifications, IronPDF embeds the Chromium rendering engine—the same engine that powers Google Chrome and Microsoft Edge.
Architectural Difference
| Aspect | HtmlRenderer.PdfSharp | IronPDF |
|---|---|---|
| Rendering Engine | Custom parser | Chromium |
| CSS Specification | CSS 2.1 (2011) | Current web standards |
| Flexbox | Not supported | Full support |
| Grid | Not supported | Full support |
| CSS Variables | Not supported | Full support |
| Transforms | Not supported | Full support |
| JavaScript | Not supported | V8 engine |
| SVG | Not supported | Full support |
| Web Fonts | Manual embedding | Automatic loading |
When HTML is submitted to IronPDF, Chromium processes it exactly as a browser would. The rendered output matches what developers see in Chrome.
Code Example: Modern CSS Layout
The following example demonstrates rendering HTML with CSS features that HtmlRenderer.PdfSharp cannot process.
using IronPdf;
// Demonstrates rendering modern CSS that fails in HtmlRenderer.PdfSharp
// IronPDF's Chromium engine processes all CSS3 features
public class ModernCssRenderer
{
public void RenderModernCssTemplate()
{
// Create renderer using embedded Chromium engine
var renderer = new ChromePdfRenderer();
// HTML content using CSS3 features
string html = @"
<!DOCTYPE html>
<html>
<head>
<style>
/* CSS Variables - ignored by HtmlRenderer.PdfSharp */
:root {
--primary-color: #2c3e50;
--accent-color: #3498db;
--spacing: 16px;
--border-radius: 8px;
}
body {
font-family: 'Segoe UI', Arial, sans-serif;
margin: 0;
padding: var(--spacing);
color: var(--primary-color);
}
/* Flexbox header - ignored by HtmlRenderer.PdfSharp */
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: var(--spacing);
background: linear-gradient(to right, var(--primary-color), var(--accent-color));
color: white;
border-radius: var(--border-radius);
margin-bottom: calc(var(--spacing) * 2);
}
.logo {
font-size: 1.5em;
font-weight: bold;
}
/* CSS Grid layout - ignored by HtmlRenderer.PdfSharp */
.stats-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--spacing);
margin-bottom: var(--spacing);
}
.stat-card {
background: white;
padding: var(--spacing);
border-radius: var(--border-radius);
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
text-align: center;
}
.stat-value {
font-size: 2em;
color: var(--accent-color);
font-weight: bold;
}
/* :nth-child selectors - ignored by HtmlRenderer.PdfSharp */
.data-table tr:nth-child(odd) {
background-color: #f8f9fa;
}
.data-table tr:nth-child(even) {
background-color: white;
}
.data-table {
width: 100%;
border-collapse: collapse;
}
.data-table th, .data-table td {
padding: 12px;
text-align: left;
border-bottom: 1px solid #ddd;
}
.data-table th {
background-color: var(--primary-color);
color: white;
}
/* Pseudo-elements - ignored by HtmlRenderer.PdfSharp */
.required::after {
content: ' *';
color: #e74c3c;
}
/* Transform for watermark - ignored by HtmlRenderer.PdfSharp */
.watermark {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(-45deg);
font-size: 72px;
color: rgba(0,0,0,0.05);
pointer-events: none;
z-index: -1;
}
</style>
</head>
<body>
<div class='watermark'>CONFIDENTIAL</div>
<div class='header'>
<div class='logo'>Acme Corporation</div>
<div>Q4 2025 Report</div>
</div>
<div class='stats-grid'>
<div class='stat-card'>
<div class='stat-value'>$1.2M</div>
<div>Revenue</div>
</div>
<div class='stat-card'>
<div class='stat-value'>847</div>
<div>Customers</div>
</div>
<div class='stat-card'>
<div class='stat-value'>94%</div>
<div>Satisfaction</div>
</div>
</div>
<h2>Sales Data</h2>
<table class='data-table'>
<thead>
<tr>
<th><span class='required'>Product</span></th>
<th>Units Sold</th>
<th>Revenue</th>
</tr>
</thead>
<tbody>
<tr>
<td>Widget Pro</td>
<td>1,234</td>
<td>$246,800</td>
</tr>
<tr>
<td>Widget Standard</td>
<td>2,567</td>
<td>$384,050</td>
</tr>
<tr>
<td>Widget Basic</td>
<td>3,891</td>
<td>$311,280</td>
</tr>
<tr>
<td>Services</td>
<td>156</td>
<td>$312,000</td>
</tr>
</tbody>
</table>
</body>
</html>";
// Render to PDF using Chromium - all CSS features work
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("modern-report.pdf");
}
}
What renders correctly with IronPDF that fails in HtmlRenderer.PdfSharp:
- CSS Variables (
--primary-color,var()) - colors and spacing applied - Flexbox header - logo and date on opposite sides
- CSS Grid - three stat cards in a row
-
:nth-child- alternating table row colors -
::afterpseudo-element - required field indicator appears - Transform - diagonal watermark positioned correctly
- calc() function - spacing calculations work
- Linear gradients - header background gradient renders
Converting a Bootstrap 5 Template
IronPDF renders Bootstrap 5 layouts correctly:
using IronPdf;
public class BootstrapPdfGenerator
{
public void GenerateBootstrapReport()
{
var renderer = new ChromePdfRenderer();
string html = @"
<!DOCTYPE html>
<html>
<head>
<link href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css' rel='stylesheet'>
</head>
<body class='p-4'>
<div class='container'>
<div class='row mb-4'>
<div class='col-6'>
<h1>Invoice #12345</h1>
</div>
<div class='col-6 text-end'>
<p class='lead'>Due: February 28, 2026</p>
</div>
</div>
<div class='row'>
<div class='col-4'>
<div class='card'>
<div class='card-body'>
<h5 class='card-title'>Subtotal</h5>
<p class='card-text fs-3'>$1,500.00</p>
</div>
</div>
</div>
<div class='col-4'>
<div class='card'>
<div class='card-body'>
<h5 class='card-title'>Tax (10%)</h5>
<p class='card-text fs-3'>$150.00</p>
</div>
</div>
</div>
<div class='col-4'>
<div class='card bg-primary text-white'>
<div class='card-body'>
<h5 class='card-title'>Total</h5>
<p class='card-text fs-3'>$1,650.00</p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>";
// Bootstrap's Flexbox grid renders correctly
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("bootstrap-invoice.pdf");
}
}
Bootstrap's row and col-* classes work as expected. Cards display in three columns. Text alignment utilities function correctly.
API Reference
For detailed documentation on IronPDF rendering:
Migration Considerations
Licensing
HtmlRenderer.PdfSharp and PdfSharp are open source (MIT License). IronPDF is commercial software with per-developer licensing. A free trial is available for evaluation, and a free tier exists for development purposes.
For projects that require modern CSS support, the licensing cost is typically offset by reduced development time. The hours spent maintaining CSS 2.1 fallback stylesheets often exceed the license cost.
API Migration
Migration from HtmlRenderer.PdfSharp to IronPDF is straightforward because both accept HTML strings:
HtmlRenderer.PdfSharp:
using PdfSharp.Pdf;
using TheArtOfDev.HtmlRenderer.PdfSharp;
PdfDocument pdf = PdfGenerator.GeneratePdf(htmlContent, PdfSharp.PageSize.A4);
pdf.Save("output.pdf");
IronPDF:
using IronPdf;
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
What You Gain
- Full CSS3 support including Flexbox and Grid
- CSS Variables and calc() functions
- CSS Transforms for watermarks and rotated content
- Modern pseudo-selectors (:nth-child, :not, etc.)
- Pseudo-elements (::before, ::after)
- JavaScript execution for dynamic content
- SVG rendering
- Automatic web font loading
- URL-to-PDF conversion capability
- Active development and regular updates
What to Consider
- Commercial licensing required for production deployment
- Larger package size due to embedded Chromium
- Higher memory consumption during rendering
- Initial learning curve for advanced configuration options
Conclusion
When HtmlRenderer.PdfSharp CSS is not working, the underlying cause is the library's CSS 2.1 limitation. This 15-year-old specification predates Flexbox, Grid, CSS Variables, transforms, modern selectors, pseudo-elements, and virtually every CSS feature used in contemporary web development.
No configuration change or workaround can add these features to HtmlRenderer.PdfSharp. The library renders CSS 2.1 content as designed. Developers requiring modern CSS support need a rendering engine based on current web standards.
IronPDF provides this through its embedded Chromium engine. HTML and CSS that render correctly in Chrome produce identical output in IronPDF, eliminating the need for legacy CSS workarounds and separate PDF-specific stylesheets.
Written by Jacob Mellor, CTO at Iron Software with 25+ years of experience in developer tooling.
References
- HtmlRenderer.PdfSharp NuGet Package{:rel="nofollow"} - Package description confirming HTML 4.01 and CSS Level 2 support
- CSS 2.1 Specification{:rel="nofollow"} - W3C CSS Level 2 Revision 1 specification from 2011
- CSS Flexible Box Layout Module{:rel="nofollow"} - W3C Flexbox specification (not supported by HtmlRenderer)
- CSS Grid Layout Module{:rel="nofollow"} - W3C Grid specification (not supported by HtmlRenderer)
- ArthurHub/HTML-Renderer GitHub Repository{:rel="nofollow"} - Source repository for HtmlRenderer library
- GitHub Issue #193 - Table Header Repetition{:rel="nofollow"} - Bug report on CSS table features
- GitHub Issue #65 - External CSS Loading{:rel="nofollow"} - Discussion on stylesheet loading issues
- PdfSharp Forum - CSS Support Discussions{:rel="nofollow"} - Forum threads on CSS limitations
For comprehensive IronPDF documentation including tutorials, API reference, and code examples, visit ironpdf.com.
Top comments (0)