How to Create Section 508 Compliant and Accessible PDFs in C# with IronPDF
Creating accessible PDF documents is no longer optional for many organizations. Government agencies, healthcare providers, educational institutions, and any business working with federal contracts must ensure their digital documents can be used by people with disabilities. This requirement stems from Section 508 of the Rehabilitation Act, which mandates that electronic content be accessible to everyone, including individuals who rely on screen readers and other assistive technologies.
For .NET developers, meeting these accessibility standards might seem daunting at first. The good news is that IronPDF provides straightforward methods to generate PDF/UA compliant documents without requiring deep expertise in the underlying PDF specification. This guide walks through everything you need to know about building accessible PDFs in C#, from understanding the legal requirements to implementing practical code solutions.
Quickstart: Create Accessible PDFs with IronPDF
Create a Section 508 compliant PDF/UA document in C# with just a few lines of code.
Get started making PDFs with NuGet now:
Install IronPDF with NuGet Package Manager
Copy and run this code snippet.
using IronPdf; ChromePdfRenderer renderer = new ChromePdfRenderer(); PdfDocument pdf = renderer.RenderHtmlAsPdfUA("<html lang='en'><body><h1>Accessible PDF</h1></body></html>"); pdf.SaveAs("accessible-document.pdf");Deploy to test on your live environment
Table of Contents
- Understanding Accessibility Standards
- Creating Accessible PDFs
- Advanced Accessibility Features
- Validation and Best Practices
What is Section 508 Compliance and Why Does it Matter for PDFs?
Section 508 refers to a 1998 amendment to the Rehabilitation Act of 1973. This federal law requires all electronic and information technology developed, procured, maintained, or used by federal agencies to be accessible to people with disabilities. The scope extends beyond government offices themselves. Any organization that receives federal funding, contracts with federal agencies, or provides technology services to government entities must also comply.
The practical implications are significant. A contractor building software for a federal healthcare program cannot simply deliver PDF reports that look correct on screen. Those documents must be readable by screen readers, navigable by keyboard, and structured in ways that assistive technologies can interpret. Failure to meet these requirements can result in rejected deliverables, lost contracts, and potential legal action.
PDFs present unique challenges for accessibility. Unlike HTML web pages, which browsers render with built-in accessibility features, PDF files are self-contained documents that must carry their own structural information. A PDF that appears visually perfect might be completely unusable for someone relying on a screen reader if it lacks proper tagging, logical reading order, or alternative text for images.
The consequences of non-compliance extend beyond legal risk. Organizations that produce inaccessible documents effectively exclude a significant portion of their audience. According to the World Health Organization, approximately 16% of the global population experiences some form of disability. For government services and federally funded programs, excluding these individuals is not just poor practice but a violation of civil rights protections.
What are PDF/UA and WCAG, and How do They Relate to Section 508?
Understanding the relationship between different accessibility standards helps clarify what developers actually need to implement. Three key standards intersect when discussing accessible PDFs: Section 508, WCAG, and PDF/UA.
The Web Content Accessibility Guidelines, commonly known as WCAG, originated from the World Wide Web Consortium. These guidelines establish principles for making digital content perceivable, operable, understandable, and robust. While WCAG was designed primarily for web content, its principles apply equally to PDF documents. The revised Section 508 standards, updated in 2017, directly incorporate WCAG 2.0 Level AA as the technical benchmark for compliance. This means that meeting WCAG 2.0 AA requirements is effectively the same as meeting Section 508 requirements for electronic documents.
PDF/UA, which stands for PDF/Universal Accessibility, is an ISO standard (ISO 14289) specifically designed for accessible PDF documents. Where WCAG describes what accessible content should accomplish, PDF/UA prescribes exactly how PDF files must be structured internally to achieve those goals. The standard defines requirements for tagged content, metadata, language specification, alternative text, and dozens of other technical elements.
Think of these standards as complementary layers. WCAG establishes the accessibility outcomes users need. PDF/UA provides the technical specification for achieving those outcomes in PDF format. Section 508 creates the legal mandate that requires compliance with WCAG, which in turn points to PDF/UA as the implementation path for PDF documents.
For developers, the practical takeaway is straightforward. Building PDF/UA compliant documents satisfies the technical requirements of Section 508 compliance. IronPDF handles much of this complexity through its built-in accessibility features, allowing you to focus on content while the library manages the underlying PDF structure.
How do I Convert an Existing PDF to PDF/UA Format in C#?
Many organizations have libraries of existing PDF documents that were created before accessibility became a priority. Rather than recreating these documents from scratch, IronPDF allows you to convert standard PDFs into PDF/UA format. This conversion process adds the necessary tagged structure and metadata for compatibility with assistive technologies.
The conversion uses the SaveAsPdfUA method, which takes an existing PdfDocument object and exports it in PDF/UA format. Here is a complete working example.
Input PDF
For this example, we use sample-document.pdf, a standard PDF without accessibility features that represents a typical legacy document requiring conversion.
The code below loads an existing PDF file using PdfDocument.FromFile(), then calls SaveAsPdfUA() to export a new version with PDF/UA-1 compliance. IronPDF automatically analyzes the document structure and adds the required tagged content, metadata, and accessibility markers.
:path=/static-assets/pdf/content-code-examples/tutorials/accessible-pdfs-government-compliance/convert-to-pdfua.csusing IronPdf;
public class PdfAccessibilityConverter
{
public void ConvertToPdfUA(string inputPath, string outputPath)
{
// Load the existing PDF document
PdfDocument pdf = PdfDocument.FromFile(inputPath);
// Export as PDF/UA compliant document
// The method automatically adds required accessibility structure
pdf.SaveAsPdfUA(outputPath);
Console.WriteLine($"Successfully converted {inputPath} to PDF/UA format.");
}
}
Imports IronPdf
Public Class PdfAccessibilityConverter
Public Sub ConvertToPdfUA(inputPath As String, outputPath As String)
' Load the existing PDF document
Dim pdf As PdfDocument = PdfDocument.FromFile(inputPath)
' Export as PDF/UA compliant document
' The method automatically adds required accessibility structure
pdf.SaveAsPdfUA(outputPath)
Console.WriteLine($"Successfully converted {inputPath} to PDF/UA format.")
End Sub
End ClassThe SaveAsPdfUA method accepts an optional parameter for specifying the document's natural language. For English documents, you would modify the call as follows.
Input PDF
This example uses benefits-summary.pdf, a benefits document that needs both accessibility conversion and explicit language tagging for proper screen reader pronunciation.
The code loads the PDF and passes NaturalLanguages.English as the second parameter to SaveAsPdfUA(). This embeds the language identifier in the PDF structure, ensuring screen readers use correct English pronunciation rules.
:path=/static-assets/pdf/content-code-examples/tutorials/accessible-pdfs-government-compliance/convert-with-language.csusing IronPdf;
public class PdfAccessibilityConverter
{
public void ConvertWithLanguage(string inputPath, string outputPath)
{
PdfDocument pdf = PdfDocument.FromFile(inputPath);
// Specify English as the document language
// This helps screen readers pronounce content correctly
pdf.SaveAsPdfUA(outputPath, IronPdf.Languages.NaturalLanguages.English);
Console.WriteLine("Conversion complete with language specification.");
}
}
Imports IronPdf
Public Class PdfAccessibilityConverter
Public Sub ConvertWithLanguage(inputPath As String, outputPath As String)
Dim pdf As PdfDocument = PdfDocument.FromFile(inputPath)
' Specify English as the document language
' This helps screen readers pronounce content correctly
pdf.SaveAsPdfUA(outputPath, IronPdf.Languages.NaturalLanguages.English)
Console.WriteLine("Conversion complete with language specification.")
End Sub
End ClassIronPDF generates PDF/UA-1 output by default, which is the widely adopted version of the standard. The conversion process analyzes the existing PDF structure and adds appropriate tags for headings, paragraphs, lists, and other content elements. While automatic conversion works well for many documents, complex layouts or scanned images may require additional manual intervention to achieve full compliance.
How can I Render HTML Directly to an Accessible PDF/UA Document?
Converting existing PDFs addresses legacy content, but new documents benefit from being created with accessibility in mind from the start. IronPDF's RenderHtmlAsPdfUA method generates standards-compliant output directly from HTML input. This approach leverages the semantic structure already present in well-formed HTML to create well-structured PDFs.
The following example demonstrates rendering an HTML string to an accessible PDF.
The code creates a ChromePdfRenderer instance and calls RenderHtmlAsPdfUA() with an HTML string containing semantic elements like headings and paragraphs. The renderer preserves the HTML structure as PDF tags, sets the document title via MetaData.Title, and saves the compliant output. The lang='en' attribute on the HTML element carries through to the PDF for screen reader language detection.
:path=/static-assets/pdf/content-code-examples/tutorials/accessible-pdfs-government-compliance/render-html-to-pdfua.csusing IronPdf;
public class AccessiblePdfGenerator
{
public void CreateAccessiblePdfFromHtml()
{
ChromePdfRenderer renderer = new ChromePdfRenderer();
string htmlContent = @"
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<title>Quarterly Financial Report</title>
<style>
body { font-family: Arial, sans-serif; line-height: 1.6; }
h1 { color: #333; }
h2 { color: #555; margin-top: 20px; }
p { margin-bottom: 15px; }
table { border-collapse: collapse; width: 100%; margin: 20px 0; }
th, td { border: 1px solid #ddd; padding: 12px; text-align: left; }
th { background-color: #f4f4f4; }
</style>
</head>
<body>
<h1>Q4 2024 Financial Summary</h1>
<p>This report provides an overview of financial performance for the fourth quarter.</p>
<h2>Revenue Highlights</h2>
<p>Total revenue increased by 12% compared to the previous quarter, driven primarily by expansion in the enterprise segment.</p>
<h2>Expense Analysis</h2>
<p>Operating expenses remained stable, with a slight reduction in administrative costs offset by increased investment in research and development.</p>
</body>
</html>";
// Render directly to PDF/UA format
PdfDocument pdf = renderer.RenderHtmlAsPdfUA(htmlContent);
// Set additional metadata for accessibility
pdf.MetaData.Title = "Q4 2024 Financial Summary";
pdf.SaveAs("financial-report-accessible.pdf");
Console.WriteLine("Accessible PDF created successfully.");
}
}
Imports IronPdf
Public Class AccessiblePdfGenerator
Public Sub CreateAccessiblePdfFromHtml()
Dim renderer As New ChromePdfRenderer()
Dim htmlContent As String = "
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<title>Quarterly Financial Report</title>
<style>
body { font-family: Arial, sans-serif; line-height: 1.6; }
h1 { color: #333; }
h2 { color: #555; margin-top: 20px; }
p { margin-bottom: 15px; }
table { border-collapse: collapse; width: 100%; margin: 20px 0; }
th, td { border: 1px solid #ddd; padding: 12px; text-align: left; }
th { background-color: #f4f4f4; }
</style>
</head>
<body>
<h1>Q4 2024 Financial Summary</h1>
<p>This report provides an overview of financial performance for the fourth quarter.</p>
<h2>Revenue Highlights</h2>
<p>Total revenue increased by 12% compared to the previous quarter, driven primarily by expansion in the enterprise segment.</p>
<h2>Expense Analysis</h2>
<p>Operating expenses remained stable, with a slight reduction in administrative costs offset by increased investment in research and development.</p>
</body>
</html>"
' Render directly to PDF/UA format
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdfUA(htmlContent)
' Set additional metadata for accessibility
pdf.MetaData.Title = "Q4 2024 Financial Summary"
pdf.SaveAs("financial-report-accessible.pdf")
Console.WriteLine("Accessible PDF created successfully.")
End Sub
End ClassOutput PDF
The code above produces a semantically structured PDF/UA document:
Notice that the HTML includes a lang attribute on the html element. This attribute carries through to the PDF and helps screen readers identify the document language. The semantic HTML elements like h1, h2, and p translate directly into appropriate PDF tags, creating a logical document structure that assistive technologies can navigate.
For rendering HTML files or URLs rather than strings, IronPDF provides corresponding methods.
The code below shows two approaches: RenderHtmlFileAsPdf() loads HTML from a local file path, while RenderUrlAsPdf() fetches and renders content from a web URL. Both methods produce standard PDFs that are then converted to PDF/UA format using SaveAsPdfUA(). This two-step approach works well when you need to apply additional processing before the accessibility conversion.
:path=/static-assets/pdf/content-code-examples/tutorials/accessible-pdfs-government-compliance/render-from-file-url.csusing IronPdf;
public class AccessiblePdfFromSources
{
public void RenderFromFile(string htmlFilePath, string outputPath)
{
ChromePdfRenderer renderer = new ChromePdfRenderer();
// Render from an HTML file on disk
PdfDocument pdf = renderer.RenderHtmlFileAsPdf(htmlFilePath);
// Convert the rendered PDF to PDF/UA format
pdf.SaveAsPdfUA(outputPath);
}
public void RenderFromUrl(string url, string outputPath)
{
ChromePdfRenderer renderer = new ChromePdfRenderer();
// Render from a web URL
PdfDocument pdf = renderer.RenderUrlAsPdf(url);
// Convert to accessible format
pdf.SaveAsPdfUA(outputPath);
}
}
Imports IronPdf
Public Class AccessiblePdfFromSources
Public Sub RenderFromFile(htmlFilePath As String, outputPath As String)
Dim renderer As New ChromePdfRenderer()
' Render from an HTML file on disk
Dim pdf As PdfDocument = renderer.RenderHtmlFileAsPdf(htmlFilePath)
' Convert the rendered PDF to PDF/UA format
pdf.SaveAsPdfUA(outputPath)
End Sub
Public Sub RenderFromUrl(url As String, outputPath As String)
Dim renderer As New ChromePdfRenderer()
' Render from a web URL
Dim pdf As PdfDocument = renderer.RenderUrlAsPdf(url)
' Convert to accessible format
pdf.SaveAsPdfUA(outputPath)
End Sub
End ClassHow do I Set Document Metadata for Accessibility Compliance?
PDF metadata serves multiple purposes in accessibility. Assistive technologies announce document properties like title and author to help users identify what they are reading. Search engines and document management systems use metadata for indexing and retrieval. Compliance validators check that required metadata fields are populated.
IronPDF exposes metadata through the MetaData property of PdfDocument objects. The following properties are most relevant for accessibility.
Input PDF
This example uses enrollment-guide-draft.pdf, a draft benefits enrollment guide that needs comprehensive metadata for accessibility compliance and document management.
The code loads an existing PDF and configures all key metadata properties: Title (announced by screen readers), Author (identifies source), Subject (brief description), Keywords (for searchability), Creator (originating application), and date stamps. Finally, SaveAsPdfUA() exports the document with both the metadata and PDF/UA accessibility structure.
:path=/static-assets/pdf/content-code-examples/tutorials/accessible-pdfs-government-compliance/set-metadata.csusing IronPdf;
using System;
public class MetadataConfiguration
{
public void SetAccessibilityMetadata(string inputPath, string outputPath)
{
PdfDocument pdf = PdfDocument.FromFile(inputPath);
// Set the document title - critical for accessibility
// Screen readers announce this when opening the document
pdf.MetaData.Title = "Employee Benefits Enrollment Guide 2024";
// Author information helps identify document source
pdf.MetaData.Author = "Human Resources Department";
// Subject provides a brief description
pdf.MetaData.Subject = "Guide to selecting and enrolling in employee benefit programs";
// Keywords improve searchability
pdf.MetaData.Keywords = "benefits, enrollment, health insurance, retirement, HR";
// Creator identifies the originating application
pdf.MetaData.Creator = "Benefits Portal v3.2";
// Set document dates
pdf.MetaData.CreationDate = DateTime.Now;
pdf.MetaData.ModifiedDate = DateTime.Now;
// Save as PDF/UA with complete metadata
pdf.SaveAsPdfUA(outputPath);
Console.WriteLine("Document metadata configured for accessibility.");
}
}
Imports IronPdf
Imports System
Public Class MetadataConfiguration
Public Sub SetAccessibilityMetadata(inputPath As String, outputPath As String)
Dim pdf As PdfDocument = PdfDocument.FromFile(inputPath)
' Set the document title - critical for accessibility
' Screen readers announce this when opening the document
pdf.MetaData.Title = "Employee Benefits Enrollment Guide 2024"
' Author information helps identify document source
pdf.MetaData.Author = "Human Resources Department"
' Subject provides a brief description
pdf.MetaData.Subject = "Guide to selecting and enrolling in employee benefit programs"
' Keywords improve searchability
pdf.MetaData.Keywords = "benefits, enrollment, health insurance, retirement, HR"
' Creator identifies the originating application
pdf.MetaData.Creator = "Benefits Portal v3.2"
' Set document dates
pdf.MetaData.CreationDate = DateTime.Now
pdf.MetaData.ModifiedDate = DateTime.Now
' Save as PDF/UA with complete metadata
pdf.SaveAsPdfUA(outputPath)
Console.WriteLine("Document metadata configured for accessibility.")
End Sub
End ClassThe Title property deserves particular attention. PDF viewers can display either the filename or the document title in their title bar and tabs. For accessibility, the document title should be displayed because it provides meaningful context. A title like "Employee Benefits Enrollment Guide 2024" is far more useful than a filename like "doc_final_v3_revised.pdf".
When creating new PDFs from HTML, you can set metadata before saving.
The code renders HTML directly to PDF/UA format using RenderHtmlAsPdfUA(), then configures the full set of metadata properties on the resulting PdfDocument object before calling SaveAs(). This approach embeds accessibility structure and metadata in a single workflow, ideal for generating new compliant documents.
:path=/static-assets/pdf/content-code-examples/tutorials/accessible-pdfs-government-compliance/new-document-metadata.csusing IronPdf;
using System;
public class NewDocumentMetadata
{
public void CreateWithMetadata()
{
ChromePdfRenderer renderer = new ChromePdfRenderer();
string html = @"
<!DOCTYPE html>
<html lang='en'>
<head><title>Policy Document</title></head>
<body>
<h1>Information Security Policy</h1>
<p>This document outlines security requirements for all employees.</p>
</body>
</html>";
PdfDocument pdf = renderer.RenderHtmlAsPdfUA(html);
// Configure comprehensive metadata
pdf.MetaData.Title = "Information Security Policy";
pdf.MetaData.Author = "IT Security Team";
pdf.MetaData.Subject = "Corporate security requirements and guidelines";
pdf.MetaData.Keywords = "security, policy, compliance, data protection";
pdf.MetaData.Creator = "Policy Management System";
pdf.MetaData.CreationDate = DateTime.Now;
pdf.MetaData.ModifiedDate = DateTime.Now;
pdf.SaveAs("security-policy-accessible.pdf");
}
}
Imports IronPdf
Imports System
Public Class NewDocumentMetadata
Public Sub CreateWithMetadata()
Dim renderer As New ChromePdfRenderer()
Dim html As String = "
<!DOCTYPE html>
<html lang='en'>
<head><title>Policy Document</title></head>
<body>
<h1>Information Security Policy</h1>
<p>This document outlines security requirements for all employees.</p>
</body>
</html>"
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdfUA(html)
' Configure comprehensive metadata
pdf.MetaData.Title = "Information Security Policy"
pdf.MetaData.Author = "IT Security Team"
pdf.MetaData.Subject = "Corporate security requirements and guidelines"
pdf.MetaData.Keywords = "security, policy, compliance, data protection"
pdf.MetaData.Creator = "Policy Management System"
pdf.MetaData.CreationDate = DateTime.Now
pdf.MetaData.ModifiedDate = DateTime.Now
pdf.SaveAs("security-policy-accessible.pdf")
End Sub
End ClassHow do I Specify the Document Language for Screen Readers?
Language specification is a fundamental accessibility requirement that directly impacts how content is vocalized. When assistive technology encounters text, it uses the specified language to select the appropriate pronunciation rules, voice, and reading patterns. A document without language specification forces the software to guess, often resulting in garbled or incomprehensible audio output.
For PDF/UA compliance, the document must declare its primary language. IronPDF handles this through the natural language parameter in the SaveAsPdfUA method.
The code demonstrates two language scenarios. The first method renders English HTML content and saves with NaturalLanguages.English. The second method handles Spanish content, using lang='es' in the HTML and NaturalLanguages.Spanish in the save call. The language setting ensures screen readers apply correct pronunciation rules for the document's primary language.
:path=/static-assets/pdf/content-code-examples/tutorials/accessible-pdfs-government-compliance/set-language.csusing IronPdf;
public class LanguageConfiguration
{
public void SetDocumentLanguage()
{
ChromePdfRenderer renderer = new ChromePdfRenderer();
string htmlContent = @"
<!DOCTYPE html>
<html lang='en'>
<head><title>Annual Report</title></head>
<body>
<h1>Annual Report 2024</h1>
<p>This report summarizes organizational activities and financial performance.</p>
</body>
</html>";
PdfDocument pdf = renderer.RenderHtmlAsPdfUA(htmlContent);
// Save with explicit English language specification
pdf.SaveAsPdfUA("annual-report.pdf", IronPdf.Languages.NaturalLanguages.English);
}
public void SetSpanishLanguage()
{
ChromePdfRenderer renderer = new ChromePdfRenderer();
string htmlContent = @"
<!DOCTYPE html>
<html lang='es'>
<head><title>Informe Anual</title></head>
<body>
<h1>Informe Anual 2024</h1>
<p>Este informe resume las actividades organizacionales y el desempeño financiero.</p>
</body>
</html>";
PdfDocument pdf = renderer.RenderHtmlAsPdfUA(htmlContent);
pdf.SaveAsPdfUA("informe-anual.pdf", IronPdf.Languages.NaturalLanguages.Spanish);
}
}
Imports IronPdf
Public Class LanguageConfiguration
Public Sub SetDocumentLanguage()
Dim renderer As New ChromePdfRenderer()
Dim htmlContent As String = "
<!DOCTYPE html>
<html lang='en'>
<head><title>Annual Report</title></head>
<body>
<h1>Annual Report 2024</h1>
<p>This report summarizes organizational activities and financial performance.</p>
</body>
</html>"
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdfUA(htmlContent)
' Save with explicit English language specification
pdf.SaveAsPdfUA("annual-report.pdf", IronPdf.Languages.NaturalLanguages.English)
End Sub
Public Sub SetSpanishLanguage()
Dim renderer As New ChromePdfRenderer()
Dim htmlContent As String = "
<!DOCTYPE html>
<html lang='es'>
<head><title>Informe Anual</title></head>
<body>
<h1>Informe Anual 2024</h1>
<p>Este informe resume las actividades organizacionales y el desempeño financiero.</p>
</body>
</html>"
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdfUA(htmlContent)
pdf.SaveAsPdfUA("informe-anual.pdf", IronPdf.Languages.NaturalLanguages.Spanish)
End Sub
End ClassIronPDF supports numerous languages through the NaturalLanguages enumeration. Common options include English, Spanish, French, German, Portuguese, Chinese, Japanese, Korean, and Arabic, among many others.
For documents containing multiple languages, the primary document language should reflect the predominant content. Assistive technologies handle occasional foreign phrases reasonably well, but documents with substantial content in multiple languages present more complex challenges that may require specialized approaches.
How do I Create Accessible Tagged PDF Structure from HTML?
Tagged PDF structure forms the backbone of accessibility. Tags define the logical organization of content, distinguishing headings from paragraphs, identifying lists and list items, marking up tables, and establishing reading order. Without correct tagging, assistive technologies cannot convey document structure to users.
The most efficient way to create well-tagged PDFs with IronPDF is to start with semantic HTML. The Chromium rendering engine preserves HTML structure when converting to PDF, translating HTML elements into corresponding PDF tags. Writing good HTML automatically produces good PDF structure.
Consider the following example that demonstrates proper semantic markup.
The code builds an HTML document with a clear heading hierarchy (h1 for the main title, h2 for sections, h3 for subsections), unordered lists (ul/li) for bullet points, and ordered lists (ol/li) for numbered sequences. The RenderHtmlAsPdfUA() method converts these semantic elements into corresponding PDF tags that assistive technologies can navigate.
:path=/static-assets/pdf/content-code-examples/tutorials/accessible-pdfs-government-compliance/semantic-structure.csusing IronPdf;
public class SemanticStructureExample
{
public void CreateStructuredDocument()
{
ChromePdfRenderer renderer = new ChromePdfRenderer();
string htmlContent = @"
<!DOCTYPE html>
<html lang='en'>
<head>
<title>Project Proposal</title>
<style>
body { font-family: Georgia, serif; line-height: 1.8; max-width: 800px; margin: 0 auto; padding: 20px; }
h1 { font-size: 28px; border-bottom: 2px solid #333; padding-bottom: 10px; }
h2 { font-size: 22px; color: #444; margin-top: 30px; }
h3 { font-size: 18px; color: #666; }
ul, ol { margin-left: 20px; }
li { margin-bottom: 8px; }
</style>
</head>
<body>
<h1>Website Redesign Proposal</h1>
<h2>Executive Summary</h2>
<p>This proposal outlines a comprehensive redesign of the corporate website to improve user experience, accessibility, and conversion rates.</p>
<h2>Project Objectives</h2>
<p>The redesign aims to achieve several key goals:</p>
<ul>
<li>Improve mobile responsiveness across all device types</li>
<li>Achieve WCAG 2.1 Level AA compliance for accessibility</li>
<li>Reduce page load times by 40 percent</li>
<li>Increase conversion rates through improved user flows</li>
</ul>
<h2>Implementation Timeline</h2>
<p>The project will proceed in three phases:</p>
<ol>
<li>Discovery and planning: weeks one through four</li>
<li>Design and development: weeks five through twelve</li>
<li>Testing and launch: weeks thirteen through sixteen</li>
</ol>
<h3>Phase One Details</h3>
<p>The discovery phase includes stakeholder interviews, competitive analysis, and technical assessment of the current platform.</p>
<h3>Phase Two Details</h3>
<p>Design and development will follow an agile methodology with two-week sprints and regular stakeholder reviews.</p>
<h2>Budget Considerations</h2>
<p>The proposed budget covers all aspects of the redesign including design, development, content migration, and quality assurance testing.</p>
</body>
</html>";
PdfDocument pdf = renderer.RenderHtmlAsPdfUA(htmlContent);
pdf.MetaData.Title = "Website Redesign Proposal";
pdf.MetaData.Author = "Digital Strategy Team";
pdf.SaveAs("proposal-accessible.pdf");
Console.WriteLine("Structured document created with proper heading hierarchy.");
}
}
Imports IronPdf
Public Class SemanticStructureExample
Public Sub CreateStructuredDocument()
Dim renderer As New ChromePdfRenderer()
Dim htmlContent As String = "
<!DOCTYPE html>
<html lang='en'>
<head>
<title>Project Proposal</title>
<style>
body { font-family: Georgia, serif; line-height: 1.8; max-width: 800px; margin: 0 auto; padding: 20px; }
h1 { font-size: 28px; border-bottom: 2px solid #333; padding-bottom: 10px; }
h2 { font-size: 22px; color: #444; margin-top: 30px; }
h3 { font-size: 18px; color: #666; }
ul, ol { margin-left: 20px; }
li { margin-bottom: 8px; }
</style>
</head>
<body>
<h1>Website Redesign Proposal</h1>
<h2>Executive Summary</h2>
<p>This proposal outlines a comprehensive redesign of the corporate website to improve user experience, accessibility, and conversion rates.</p>
<h2>Project Objectives</h2>
<p>The redesign aims to achieve several key goals:</p>
<ul>
<li>Improve mobile responsiveness across all device types</li>
<li>Achieve WCAG 2.1 Level AA compliance for accessibility</li>
<li>Reduce page load times by 40 percent</li>
<li>Increase conversion rates through improved user flows</li>
</ul>
<h2>Implementation Timeline</h2>
<p>The project will proceed in three phases:</p>
<ol>
<li>Discovery and planning: weeks one through four</li>
<li>Design and development: weeks five through twelve</li>
<li>Testing and launch: weeks thirteen through sixteen</li>
</ol>
<h3>Phase One Details</h3>
<p>The discovery phase includes stakeholder interviews, competitive analysis, and technical assessment of the current platform.</p>
<h3>Phase Two Details</h3>
<p>Design and development will follow an agile methodology with two-week sprints and regular stakeholder reviews.</p>
<h2>Budget Considerations</h2>
<p>The proposed budget covers all aspects of the redesign including design, development, content migration, and quality assurance testing.</p>
</body>
</html>"
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdfUA(htmlContent)
pdf.MetaData.Title = "Website Redesign Proposal"
pdf.MetaData.Author = "Digital Strategy Team"
pdf.SaveAs("proposal-accessible.pdf")
Console.WriteLine("Structured document created with proper heading hierarchy.")
End Sub
End ClassOutput PDF
This PDF maintains the heading hierarchy and list structure for navigation:
Notice the heading hierarchy in this example. The document has a single h1 for the main title, followed by h2 elements for major sections, and h3 elements for subsections. This hierarchy is essential for accessibility. Users of assistive technologies often navigate documents by jumping between headings, so a logical structure allows them to quickly find the content they need.
Lists receive semantic treatment with ul for unordered lists and ol for ordered lists. Each li element becomes a tagged list item in the PDF. Assistive technologies announce lists by indicating how many items they contain and then reading each item in sequence.
How do I Add Alt Text to Images for Screen Reader Compatibility?
Images present a fundamental accessibility challenge. Visual content cannot be perceived by users who are blind or have low vision. Alternative text, commonly called alt text, provides a textual description that can be announced in place of the image.
When generating PDFs from HTML, the alt attribute on img elements carries through to the PDF as alternative text.
The code creates a sales report with two chart images. Each img element includes a detailed alt attribute that describes the chart's data rather than just its type. For example, the alt text specifies actual sales figures and regional comparisons. The RenderHtmlAsPdfUA() method embeds these descriptions as alternative text in the PDF, allowing screen readers to convey the same insights that sighted users get from viewing the charts.
:path=/static-assets/pdf/content-code-examples/tutorials/accessible-pdfs-government-compliance/image-accessibility.csusing IronPdf;
public class ImageAccessibility
{
public void CreateDocumentWithAccessibleImages()
{
ChromePdfRenderer renderer = new ChromePdfRenderer();
string htmlContent = @"
<!DOCTYPE html>
<html lang='en'>
<head>
<title>Sales Performance Report</title>
<style>
body { font-family: Arial, sans-serif; padding: 20px; }
.chart-container { margin: 20px 0; text-align: center; }
img { max-width: 100%; height: auto; }
.caption { font-style: italic; color: #666; margin-top: 10px; }
</style>
</head>
<body>
<h1>Q3 Sales Performance Report</h1>
<h2>Regional Sales Comparison</h2>
<p>The following chart illustrates sales performance across regions for the third quarter.</p>
<div class='chart-container'>
<img src='https://example.com/charts/regional-sales-q3.png'
alt='Bar chart comparing Q3 sales across four regions: Northeast at 2.4 million dollars, Southeast at 1.8 million dollars, Midwest at 2.1 million dollars, and West at 3.2 million dollars. The West region shows the highest performance with a 15 percent increase from Q2.'
width='600' height='400'>
<p class='caption'>Figure 1: Regional Sales Comparison Q3 2024</p>
</div>
<h2>Monthly Trend Analysis</h2>
<p>Sales showed consistent growth throughout the quarter with acceleration in September.</p>
<div class='chart-container'>
<img src='https://example.com/charts/monthly-trend.png'
alt='Line graph showing monthly sales from July through September. July sales were 2.1 million dollars, August increased to 2.4 million dollars, and September reached 2.9 million dollars, representing a 38 percent total increase over the quarter.'
width='600' height='300'>
<p class='caption'>Figure 2: Monthly Sales Trend Q3 2024</p>
</div>
<h2>Key Findings</h2>
<p>Analysis indicates strong momentum heading into Q4, particularly in the Western region where new product launches drove significant customer acquisition.</p>
</body>
</html>";
PdfDocument pdf = renderer.RenderHtmlAsPdfUA(htmlContent);
pdf.MetaData.Title = "Q3 Sales Performance Report";
pdf.MetaData.Author = "Sales Analytics Team";
pdf.SaveAs("sales-report-accessible.pdf");
Console.WriteLine("Report created with accessible image descriptions.");
}
}
Imports IronPdf
Public Class ImageAccessibility
Public Sub CreateDocumentWithAccessibleImages()
Dim renderer As New ChromePdfRenderer()
Dim htmlContent As String = "
<!DOCTYPE html>
<html lang='en'>
<head>
<title>Sales Performance Report</title>
<style>
body { font-family: Arial, sans-serif; padding: 20px; }
.chart-container { margin: 20px 0; text-align: center; }
img { max-width: 100%; height: auto; }
.caption { font-style: italic; color: #666; margin-top: 10px; }
</style>
</head>
<body>
<h1>Q3 Sales Performance Report</h1>
<h2>Regional Sales Comparison</h2>
<p>The following chart illustrates sales performance across regions for the third quarter.</p>
<div class='chart-container'>
<img src='https://example.com/charts/regional-sales-q3.png'
alt='Bar chart comparing Q3 sales across four regions: Northeast at 2.4 million dollars, Southeast at 1.8 million dollars, Midwest at 2.1 million dollars, and West at 3.2 million dollars. The West region shows the highest performance with a 15 percent increase from Q2.'
width='600' height='400'>
<p class='caption'>Figure 1: Regional Sales Comparison Q3 2024</p>
</div>
<h2>Monthly Trend Analysis</h2>
<p>Sales showed consistent growth throughout the quarter with acceleration in September.</p>
<div class='chart-container'>
<img src='https://example.com/charts/monthly-trend.png'
alt='Line graph showing monthly sales from July through September. July sales were 2.1 million dollars, August increased to 2.4 million dollars, and September reached 2.9 million dollars, representing a 38 percent total increase over the quarter.'
width='600' height='300'>
<p class='caption'>Figure 2: Monthly Sales Trend Q3 2024</p>
</div>
<h2>Key Findings</h2>
<p>Analysis indicates strong momentum heading into Q4, particularly in the Western region where new product launches drove significant customer acquisition.</p>
</body>
</html>"
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdfUA(htmlContent)
pdf.MetaData.Title = "Q3 Sales Performance Report"
pdf.MetaData.Author = "Sales Analytics Team"
pdf.SaveAs("sales-report-accessible.pdf")
Console.WriteLine("Report created with accessible image descriptions.")
End Sub
End ClassWriting effective alt text requires understanding what information the image conveys. For charts and graphs, the alt text should describe the data being presented, not just state that a chart exists. Saying "bar chart" provides no useful information. Describing "bar chart comparing Q3 sales across four regions with West leading at 3.2 million dollars" gives users with visual impairments the same insight that sighted users gain from viewing the chart.
Decorative images that serve no informational purpose should have empty alt attributes. This signals to screen readers that the image can be skipped:
<img src="decorative-border.png" alt=""><img src="decorative-border.png" alt="">How do I Build Accessible Tables in PDF Documents?
Tables present complex accessibility considerations because they encode relationships between data in two dimensions. A sighted user can visually scan across rows and down columns to understand how cells relate to their headers. Users relying on assistive technologies need this relationship explicitly defined through correct markup.
HTML provides the structural elements needed for accessible tables. The key elements include th for header cells, td for data cells, and scope attributes that clarify whether headers apply to rows or columns.
The code creates an employee directory table with proper accessibility markup. The caption element provides a table title announced before content. Header cells use th with scope="col" to indicate they apply to all cells in their column. The thead and tbody elements separate structural sections. IronPDF's RenderHtmlAsPdfUA() preserves these relationships in the PDF structure, allowing screen readers to associate data cells with their column headers.
:path=/static-assets/pdf/content-code-examples/tutorials/accessible-pdfs-government-compliance/accessible-table.csusing IronPdf;
public class AccessibleTableExample
{
public void CreateDocumentWithAccessibleTable()
{
ChromePdfRenderer renderer = new ChromePdfRenderer();
string htmlContent = @"
<!DOCTYPE html>
<html lang='en'>
<head>
<title>Employee Directory</title>
<style>
body { font-family: Arial, sans-serif; padding: 20px; }
table { border-collapse: collapse; width: 100%; margin: 20px 0; }
th, td { border: 1px solid #ccc; padding: 12px; text-align: left; }
th { background-color: #f0f0f0; font-weight: bold; }
caption { font-size: 18px; font-weight: bold; margin-bottom: 10px; text-align: left; }
</style>
</head>
<body>
<h1>Department Staff Directory</h1>
<p>Contact information for all department personnel as of January 2024.</p>
<table>
<caption>Engineering Department Staff</caption>
<thead>
<tr>
<th scope='col'>Name</th>
<th scope='col'>Title</th>
<th scope='col'>Email</th>
<th scope='col'>Extension</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sarah Chen</td>
<td>Senior Software Engineer</td>
<td>schen@company.com</td>
<td>4521</td>
</tr>
<tr>
<td>Marcus Williams</td>
<td>DevOps Engineer</td>
<td>mwilliams@company.com</td>
<td>4522</td>
</tr>
<tr>
<td>Jennifer Park</td>
<td>QA Lead</td>
<td>jpark@company.com</td>
<td>4523</td>
</tr>
<tr>
<td>Robert Gonzalez</td>
<td>Technical Writer</td>
<td>rgonzalez@company.com</td>
<td>4524</td>
</tr>
</tbody>
</table>
<h2>Contact Guidelines</h2>
<p>Please use email for non-urgent matters. Phone extensions connect to voicemail outside business hours.</p>
</body>
</html>";
PdfDocument pdf = renderer.RenderHtmlAsPdfUA(htmlContent);
pdf.MetaData.Title = "Department Staff Directory";
pdf.SaveAs("directory-accessible.pdf");
Console.WriteLine("Directory created with accessible table structure.");
}
}
Imports IronPdf
Public Class AccessibleTableExample
Public Sub CreateDocumentWithAccessibleTable()
Dim renderer As New ChromePdfRenderer()
Dim htmlContent As String = "
<!DOCTYPE html>
<html lang='en'>
<head>
<title>Employee Directory</title>
<style>
body { font-family: Arial, sans-serif; padding: 20px; }
table { border-collapse: collapse; width: 100%; margin: 20px 0; }
th, td { border: 1px solid #ccc; padding: 12px; text-align: left; }
th { background-color: #f0f0f0; font-weight: bold; }
caption { font-size: 18px; font-weight: bold; margin-bottom: 10px; text-align: left; }
</style>
</head>
<body>
<h1>Department Staff Directory</h1>
<p>Contact information for all department personnel as of January 2024.</p>
<table>
<caption>Engineering Department Staff</caption>
<thead>
<tr>
<th scope='col'>Name</th>
<th scope='col'>Title</th>
<th scope='col'>Email</th>
<th scope='col'>Extension</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sarah Chen</td>
<td>Senior Software Engineer</td>
<td>schen@company.com</td>
<td>4521</td>
</tr>
<tr>
<td>Marcus Williams</td>
<td>DevOps Engineer</td>
<td>mwilliams@company.com</td>
<td>4522</td>
</tr>
<tr>
<td>Jennifer Park</td>
<td>QA Lead</td>
<td>jpark@company.com</td>
<td>4523</td>
</tr>
<tr>
<td>Robert Gonzalez</td>
<td>Technical Writer</td>
<td>rgonzalez@company.com</td>
<td>4524</td>
</tr>
</tbody>
</table>
<h2>Contact Guidelines</h2>
<p>Please use email for non-urgent matters. Phone extensions connect to voicemail outside business hours.</p>
</body>
</html>"
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdfUA(htmlContent)
pdf.MetaData.Title = "Department Staff Directory"
pdf.SaveAs("directory-accessible.pdf")
Console.WriteLine("Directory created with accessible table structure.")
End Sub
End ClassOutput PDF
The output contains a correctly structured table with header associations:
The scope attribute on th elements is critical. Setting scope="col" indicates that the header applies to all cells in that column. For tables where the first cell of each row serves as a row header, you would use scope="row" instead. Complex tables with both row and column headers require both attributes.
The caption element provides a title for the table that is announced before reading the table contents. This gives users context about what data they are about to hear.
For tables with merged cells or irregular structures, additional attributes like headers and id can explicitly connect data cells to their corresponding headers. However, simple table structures with consistent rows and columns are preferable from an accessibility standpoint.
How do I Add Bookmarks and Navigation for Document Accessibility?
Bookmarks provide navigational landmarks that help all users move through lengthy documents, but they are particularly valuable for accessibility. Users who cannot visually scan pages rely on bookmarks to find sections of interest. These structured outlines allow jumping directly to specific content.
IronPDF supports creating hierarchical bookmark structures programmatically.
The code renders an employee handbook with multiple chapters, then programmatically adds a bookmark hierarchy using the Bookmarks collection. Top-level bookmarks point to chapter start pages via AddBookMarkAtEnd() with a page index. Child bookmarks for subsections are added through the parent's Children property, creating a nested navigation tree. The page index parameter is zero-based, so page 0 is the first page.
:path=/static-assets/pdf/content-code-examples/tutorials/accessible-pdfs-government-compliance/bookmarks-navigation.csusing IronPdf;
public class BookmarkNavigation
{
public void CreateDocumentWithBookmarks()
{
ChromePdfRenderer renderer = new ChromePdfRenderer();
string htmlContent = @"
<!DOCTYPE html>
<html lang='en'>
<head>
<title>Employee Handbook</title>
<style>
body { font-family: Georgia, serif; line-height: 1.8; padding: 40px; }
h1 { page-break-before: always; }
h1:first-of-type { page-break-before: avoid; }
h2 { margin-top: 30px; }
</style>
</head>
<body>
<h1>Employee Handbook</h1>
<p>Welcome to our organization. This handbook contains policies and procedures for all employees.</p>
<h1>Chapter 1: Employment Policies</h1>
<h2>Equal Opportunity</h2>
<p>Our organization is committed to providing equal employment opportunities to all applicants and employees.</p>
<h2>At-Will Employment</h2>
<p>Employment with the organization is at-will unless otherwise specified in a written agreement.</p>
<h1>Chapter 2: Compensation and Benefits</h1>
<h2>Pay Periods</h2>
<p>Employees are paid on a bi-weekly basis, with pay dates falling on alternating Fridays.</p>
<h2>Health Insurance</h2>
<p>Full-time employees are eligible for health insurance coverage beginning the first of the month following hire date.</p>
<h2>Retirement Plans</h2>
<p>The organization offers a 401(k) plan with employer matching contributions up to four percent of salary.</p>
<h1>Chapter 3: Time Off Policies</h1>
<h2>Vacation</h2>
<p>Employees accrue vacation time based on length of service, starting at two weeks annually.</p>
<h2>Sick Leave</h2>
<p>Employees receive five days of paid sick leave per calendar year.</p>
</body>
</html>";
PdfDocument pdf = renderer.RenderHtmlAsPdfUA(htmlContent);
// Add top-level bookmarks for main sections
var introBookmark = pdf.Bookmarks.AddBookMarkAtEnd("Introduction", 0);
var chapter1Bookmark = pdf.Bookmarks.AddBookMarkAtEnd("Chapter 1: Employment Policies", 1);
// Add child bookmarks for subsections
chapter1Bookmark.Children.AddBookMarkAtEnd("Equal Opportunity", 1);
chapter1Bookmark.Children.AddBookMarkAtEnd("At-Will Employment", 1);
var chapter2Bookmark = pdf.Bookmarks.AddBookMarkAtEnd("Chapter 2: Compensation and Benefits", 2);
chapter2Bookmark.Children.AddBookMarkAtEnd("Pay Periods", 2);
chapter2Bookmark.Children.AddBookMarkAtEnd("Health Insurance", 2);
chapter2Bookmark.Children.AddBookMarkAtEnd("Retirement Plans", 2);
var chapter3Bookmark = pdf.Bookmarks.AddBookMarkAtEnd("Chapter 3: Time Off Policies", 3);
chapter3Bookmark.Children.AddBookMarkAtEnd("Vacation", 3);
chapter3Bookmark.Children.AddBookMarkAtEnd("Sick Leave", 3);
pdf.MetaData.Title = "Employee Handbook";
pdf.MetaData.Author = "Human Resources";
pdf.SaveAs("handbook-with-bookmarks.pdf");
Console.WriteLine("Handbook created with navigational bookmarks.");
}
}
Imports IronPdf
Public Class BookmarkNavigation
Public Sub CreateDocumentWithBookmarks()
Dim renderer As New ChromePdfRenderer()
Dim htmlContent As String = "
<!DOCTYPE html>
<html lang='en'>
<head>
<title>Employee Handbook</title>
<style>
body { font-family: Georgia, serif; line-height: 1.8; padding: 40px; }
h1 { page-break-before: always; }
h1:first-of-type { page-break-before: avoid; }
h2 { margin-top: 30px; }
</style>
</head>
<body>
<h1>Employee Handbook</h1>
<p>Welcome to our organization. This handbook contains policies and procedures for all employees.</p>
<h1>Chapter 1: Employment Policies</h1>
<h2>Equal Opportunity</h2>
<p>Our organization is committed to providing equal employment opportunities to all applicants and employees.</p>
<h2>At-Will Employment</h2>
<p>Employment with the organization is at-will unless otherwise specified in a written agreement.</p>
<h1>Chapter 2: Compensation and Benefits</h1>
<h2>Pay Periods</h2>
<p>Employees are paid on a bi-weekly basis, with pay dates falling on alternating Fridays.</p>
<h2>Health Insurance</h2>
<p>Full-time employees are eligible for health insurance coverage beginning the first of the month following hire date.</p>
<h2>Retirement Plans</h2>
<p>The organization offers a 401(k) plan with employer matching contributions up to four percent of salary.</p>
<h1>Chapter 3: Time Off Policies</h1>
<h2>Vacation</h2>
<p>Employees accrue vacation time based on length of service, starting at two weeks annually.</p>
<h2>Sick Leave</h2>
<p>Employees receive five days of paid sick leave per calendar year.</p>
</body>
</html>"
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdfUA(htmlContent)
' Add top-level bookmarks for main sections
Dim introBookmark = pdf.Bookmarks.AddBookMarkAtEnd("Introduction", 0)
Dim chapter1Bookmark = pdf.Bookmarks.AddBookMarkAtEnd("Chapter 1: Employment Policies", 1)
' Add child bookmarks for subsections
chapter1Bookmark.Children.AddBookMarkAtEnd("Equal Opportunity", 1)
chapter1Bookmark.Children.AddBookMarkAtEnd("At-Will Employment", 1)
Dim chapter2Bookmark = pdf.Bookmarks.AddBookMarkAtEnd("Chapter 2: Compensation and Benefits", 2)
chapter2Bookmark.Children.AddBookMarkAtEnd("Pay Periods", 2)
chapter2Bookmark.Children.AddBookMarkAtEnd("Health Insurance", 2)
chapter2Bookmark.Children.AddBookMarkAtEnd("Retirement Plans", 2)
Dim chapter3Bookmark = pdf.Bookmarks.AddBookMarkAtEnd("Chapter 3: Time Off Policies", 3)
chapter3Bookmark.Children.AddBookMarkAtEnd("Vacation", 3)
chapter3Bookmark.Children.AddBookMarkAtEnd("Sick Leave", 3)
pdf.MetaData.Title = "Employee Handbook"
pdf.MetaData.Author = "Human Resources"
pdf.SaveAs("handbook-with-bookmarks.pdf")
Console.WriteLine("Handbook created with navigational bookmarks.")
End Sub
End ClassOutput PDF
The generated PDF includes a navigable bookmark panel for quick section access:
The page index parameter in AddBookMarkAtEnd uses zero-based indexing, where page 0 is the first page of the document. Nested bookmarks created through the Children property establish a hierarchy that mirrors the document structure.
For HTML documents with correct heading structure, IronPDF can automatically generate a table of contents that includes linked navigation.
The code enables automatic TOC generation by setting RenderingOptions.TableOfContents to TableOfContentsTypes.WithPageNumbers. The HTML includes a placeholder div with id="ironpdf-toc" where the generated table of contents will be inserted. IronPDF scans the heading elements (h1, h2, etc.), builds a hierarchical TOC with page numbers, and inserts it at the placeholder location.
:path=/static-assets/pdf/content-code-examples/tutorials/accessible-pdfs-government-compliance/table-of-contents.csusing IronPdf;
public class AutomaticTableOfContents
{
public void CreateWithTableOfContents()
{
ChromePdfRenderer renderer = new ChromePdfRenderer();
// Enable automatic table of contents generation
renderer.RenderingOptions.TableOfContents = TableOfContentsTypes.WithPageNumbers;
string htmlContent = @"
<!DOCTYPE html>
<html lang='en'>
<head><title>Technical Manual</title></head>
<body>
<div id='ironpdf-toc'></div>
<h1>System Administration Guide</h1>
<p>Comprehensive guide to system configuration and maintenance.</p>
<h2>Installation</h2>
<p>Step-by-step installation procedures for all supported platforms.</p>
<h2>Configuration</h2>
<p>Detailed configuration options and recommended settings.</p>
<h2>Troubleshooting</h2>
<p>Common issues and their resolutions.</p>
</body>
</html>";
PdfDocument pdf = renderer.RenderHtmlAsPdfUA(htmlContent);
pdf.MetaData.Title = "System Administration Guide";
pdf.SaveAs("manual-with-toc.pdf");
}
}
Imports IronPdf
Public Class AutomaticTableOfContents
Public Sub CreateWithTableOfContents()
Dim renderer As New ChromePdfRenderer()
' Enable automatic table of contents generation
renderer.RenderingOptions.TableOfContents = TableOfContentsTypes.WithPageNumbers
Dim htmlContent As String = "
<!DOCTYPE html>
<html lang='en'>
<head><title>Technical Manual</title></head>
<body>
<div id='ironpdf-toc'></div>
<h1>System Administration Guide</h1>
<p>Comprehensive guide to system configuration and maintenance.</p>
<h2>Installation</h2>
<p>Step-by-step installation procedures for all supported platforms.</p>
<h2>Configuration</h2>
<p>Detailed configuration options and recommended settings.</p>
<h2>Troubleshooting</h2>
<p>Common issues and their resolutions.</p>
</body>
</html>"
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdfUA(htmlContent)
pdf.MetaData.Title = "System Administration Guide"
pdf.SaveAs("manual-with-toc.pdf")
End Sub
End ClassThe div element with id="ironpdf-toc" marks where the generated table of contents will appear. IronPDF builds the TOC from heading elements, creating clickable links that jump to each section.
How do I Create Accessible PDF Forms with Proper Labels?
Interactive forms require special attention for accessibility. Every input field must have a programmatically associated label so the expected input can be announced. Visual labels alone are insufficient because they lack the underlying connection that assistive technologies need to interpret the form correctly.
IronPDF renders HTML form elements as interactive PDF form fields. Proper HTML form markup translates into accessible PDF forms.
The code enables form field creation by setting RenderingOptions.CreatePdfFormsFromHtml = true. The HTML form uses proper accessibility patterns: each input has a unique id that matches its label's for attribute, radio buttons are grouped in a fieldset with a descriptive legend, and checkboxes have associated labels. The RenderHtmlAsPdfUA() method converts these elements into interactive PDF form fields with the label associations preserved for screen readers.
:path=/static-assets/pdf/content-code-examples/tutorials/accessible-pdfs-government-compliance/accessible-form.csusing IronPdf;
public class AccessibleFormExample
{
public void CreateAccessibleForm()
{
ChromePdfRenderer renderer = new ChromePdfRenderer();
// Enable form field creation from HTML forms
renderer.RenderingOptions.CreatePdfFormsFromHtml = true;
string htmlContent = @"
<!DOCTYPE html>
<html lang='en'>
<head>
<title>Contact Request Form</title>
<style>
body { font-family: Arial, sans-serif; padding: 30px; max-width: 600px; }
.form-group { margin-bottom: 20px; }
label { display: block; margin-bottom: 5px; font-weight: bold; }
input[type='text'], input[type='email'], textarea {
width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px;
}
textarea { height: 120px; resize: vertical; }
.checkbox-group { margin: 15px 0; }
.checkbox-group label { display: inline; font-weight: normal; margin-left: 8px; }
fieldset { border: 1px solid #ddd; padding: 15px; margin-bottom: 20px; }
legend { font-weight: bold; padding: 0 10px; }
</style>
</head>
<body>
<h1>Contact Request Form</h1>
<p>Please complete all required fields marked with an asterisk.</p>
<form>
<div class='form-group'>
<label for='fullname'>Full Name *</label>
<input type='text' id='fullname' name='fullname' required>
</div>
<div class='form-group'>
<label for='email'>Email Address *</label>
<input type='email' id='email' name='email' required>
</div>
<div class='form-group'>
<label for='phone'>Phone Number</label>
<input type='text' id='phone' name='phone'>
</div>
<fieldset>
<legend>Preferred Contact Method</legend>
<div class='checkbox-group'>
<input type='radio' id='contact-email' name='contact-method' value='email'>
<label for='contact-email'>Email</label>
</div>
<div class='checkbox-group'>
<input type='radio' id='contact-phone' name='contact-method' value='phone'>
<label for='contact-phone'>Phone</label>
</div>
</fieldset>
<div class='form-group'>
<label for='message'>Message *</label>
<textarea id='message' name='message' required></textarea>
</div>
<div class='checkbox-group'>
<input type='checkbox' id='newsletter' name='newsletter'>
<label for='newsletter'>Subscribe to our newsletter</label>
</div>
</form>
</body>
</html>";
PdfDocument pdf = renderer.RenderHtmlAsPdfUA(htmlContent);
pdf.MetaData.Title = "Contact Request Form";
pdf.SaveAs("contact-form-accessible.pdf");
Console.WriteLine("Accessible form created with proper field labels.");
}
}
Imports IronPdf
Public Class AccessibleFormExample
Public Sub CreateAccessibleForm()
Dim renderer As New ChromePdfRenderer()
' Enable form field creation from HTML forms
renderer.RenderingOptions.CreatePdfFormsFromHtml = True
Dim htmlContent As String = "
<!DOCTYPE html>
<html lang='en'>
<head>
<title>Contact Request Form</title>
<style>
body { font-family: Arial, sans-serif; padding: 30px; max-width: 600px; }
.form-group { margin-bottom: 20px; }
label { display: block; margin-bottom: 5px; font-weight: bold; }
input[type='text'], input[type='email'], textarea {
width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px;
}
textarea { height: 120px; resize: vertical; }
.checkbox-group { margin: 15px 0; }
.checkbox-group label { display: inline; font-weight: normal; margin-left: 8px; }
fieldset { border: 1px solid #ddd; padding: 15px; margin-bottom: 20px; }
legend { font-weight: bold; padding: 0 10px; }
</style>
</head>
<body>
<h1>Contact Request Form</h1>
<p>Please complete all required fields marked with an asterisk.</p>
<form>
<div class='form-group'>
<label for='fullname'>Full Name *</label>
<input type='text' id='fullname' name='fullname' required>
</div>
<div class='form-group'>
<label for='email'>Email Address *</label>
<input type='email' id='email' name='email' required>
</div>
<div class='form-group'>
<label for='phone'>Phone Number</label>
<input type='text' id='phone' name='phone'>
</div>
<fieldset>
<legend>Preferred Contact Method</legend>
<div class='checkbox-group'>
<input type='radio' id='contact-email' name='contact-method' value='email'>
<label for='contact-email'>Email</label>
</div>
<div class='checkbox-group'>
<input type='radio' id='contact-phone' name='contact-method' value='phone'>
<label for='contact-phone'>Phone</label>
</div>
</fieldset>
<div class='form-group'>
<label for='message'>Message *</label>
<textarea id='message' name='message' required></textarea>
</div>
<div class='checkbox-group'>
<input type='checkbox' id='newsletter' name='newsletter'>
<label for='newsletter'>Subscribe to our newsletter</label>
</div>
</form>
</body>
</html>"
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdfUA(htmlContent)
pdf.MetaData.Title = "Contact Request Form"
pdf.SaveAs("contact-form-accessible.pdf")
Console.WriteLine("Accessible form created with proper field labels.")
End Sub
End ClassOutput PDF
The generated PDF includes interactive form fields with correct label associations:
Several accessibility patterns appear in this form example. Each input has a unique id attribute that matches the for attribute of its label. This connection allows "Full Name, edit text" to be announced when a user tabs to that field. Radio buttons are grouped within a fieldset with a legend that describes the group's purpose. Checkboxes have labels positioned after the input element, following standard form conventions.
The CreatePdfFormsFromHtml rendering option must be enabled for IronPDF to create interactive form fields rather than static representations of the form.
How do I Validate PDF/UA Compliance after Generation?
Creating PDFs with accessibility features is only part of the process. Validation confirms that the generated documents actually meet the technical requirements of the PDF/UA standard. Several tools exist for this purpose, with veraPDF being the most widely recognized open-source validator.
While IronPDF does not include built-in validation, you can integrate validation into your workflow using external tools. The veraPDF validator is available as a command-line application that can be called from C# code.
The code demonstrates two parts: first, it generates a test PDF using RenderHtmlAsPdfUA() with metadata configured. Second, the ValidateWithVeraPdf() method shows how to invoke veraPDF from C# using Process.Start(). The method configures the process to run veraPDF with the --flavour ua1 flag for PDF/UA-1 validation, captures the output, and returns a boolean indicating pass/fail based on the exit code.
:path=/static-assets/pdf/content-code-examples/tutorials/accessible-pdfs-government-compliance/validation.csusing System;
using System.Diagnostics;
using IronPdf;
public class AccessibilityValidation
{
public void GenerateAndValidate()
{
// First, create the accessible PDF
ChromePdfRenderer renderer = new ChromePdfRenderer();
string htmlContent = @"
<!DOCTYPE html>
<html lang='en'>
<head><title>Test Document</title></head>
<body>
<h1>Validation Test</h1>
<p>This document will be validated for PDF/UA compliance.</p>
</body>
</html>";
PdfDocument pdf = renderer.RenderHtmlAsPdfUA(htmlContent);
pdf.MetaData.Title = "Validation Test Document";
string outputPath = "test-document.pdf";
pdf.SaveAs(outputPath);
Console.WriteLine($"PDF created at: {outputPath}");
Console.WriteLine("Run veraPDF validation with:");
Console.WriteLine($" verapdf --flavour ua1 {outputPath}");
}
public bool ValidateWithVeraPdf(string pdfPath, string verapdfPath)
{
try
{
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = verapdfPath,
Arguments = $"--flavour ua1 \"{pdfPath}\"",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
using (Process process = Process.Start(startInfo))
{
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
// veraPDF returns 0 for valid documents
bool isValid = process.ExitCode == 0;
Console.WriteLine(isValid ? "Document passes PDF/UA validation." : "Document has validation issues.");
Console.WriteLine(output);
return isValid;
}
}
catch (Exception ex)
{
Console.WriteLine($"Validation error: {ex.Message}");
return false;
}
}
}
Imports System
Imports System.Diagnostics
Imports IronPdf
Public Class AccessibilityValidation
Public Sub GenerateAndValidate()
' First, create the accessible PDF
Dim renderer As New ChromePdfRenderer()
Dim htmlContent As String = "
<!DOCTYPE html>
<html lang='en'>
<head><title>Test Document</title></head>
<body>
<h1>Validation Test</h1>
<p>This document will be validated for PDF/UA compliance.</p>
</body>
</html>"
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdfUA(htmlContent)
pdf.MetaData.Title = "Validation Test Document"
Dim outputPath As String = "test-document.pdf"
pdf.SaveAs(outputPath)
Console.WriteLine($"PDF created at: {outputPath}")
Console.WriteLine("Run veraPDF validation with:")
Console.WriteLine($" verapdf --flavour ua1 {outputPath}")
End Sub
Public Function ValidateWithVeraPdf(pdfPath As String, verapdfPath As String) As Boolean
Try
Dim startInfo As New ProcessStartInfo With {
.FileName = verapdfPath,
.Arguments = $"--flavour ua1 ""{pdfPath}""",
.RedirectStandardOutput = True,
.RedirectStandardError = True,
.UseShellExecute = False,
.CreateNoWindow = True
}
Using process As Process = Process.Start(startInfo)
Dim output As String = process.StandardOutput.ReadToEnd()
process.WaitForExit()
' veraPDF returns 0 for valid documents
Dim isValid As Boolean = process.ExitCode = 0
Console.WriteLine(If(isValid, "Document passes PDF/UA validation.", "Document has validation issues."))
Console.WriteLine(output)
Return isValid
End Using
Catch ex As Exception
Console.WriteLine($"Validation error: {ex.Message}")
Return False
End Try
End Function
End ClassAdobe Acrobat Pro also includes accessibility checking features. The Accessibility Checker in Acrobat Pro performs comprehensive tests including reading order verification, alternative text validation, and form field accessibility. While not free, Acrobat Pro is commonly available in enterprise environments and provides detailed reports on accessibility issues.
For automated testing pipelines, the PAC (PDF Accessibility Checker) tool from the PDF/UA Foundation offers another validation option. PAC provides both a graphical interface and command-line capabilities, making it suitable for integration into continuous integration workflows.
What are Best Practices for Maintaining Accessible PDFs in Enterprise Applications?
Building individual accessible documents is straightforward once you understand the techniques. Maintaining accessibility at scale across an enterprise requires systematic approaches and organizational discipline.
Template standardization reduces variability and ensures consistency. Creating a library of approved HTML templates with semantic structure, accessible form patterns, and consistent styling gives developers a foundation that produces compliant output by default.
The code implements a reusable AccessibleDocumentService class that encapsulates PDF generation patterns. The constructor initializes a shared ChromePdfRenderer with form creation enabled. Public methods like CreateReport() and CreateForm() accept content parameters and apply standardized HTML templates with consistent styling and semantic structure. A private ConfigureStandardMetadata() method ensures every document receives proper title, author, creator, and date information. This service pattern enforces accessibility compliance across all generated documents.
:path=/static-assets/pdf/content-code-examples/tutorials/accessible-pdfs-government-compliance/enterprise-service.csusing IronPdf;
using System;
public class AccessibleDocumentService
{
private readonly ChromePdfRenderer _renderer;
public AccessibleDocumentService()
{
_renderer = new ChromePdfRenderer();
_renderer.RenderingOptions.CreatePdfFormsFromHtml = true;
}
public PdfDocument CreateReport(string title, string content, string author)
{
string html = GetReportTemplate(title, content);
PdfDocument pdf = _renderer.RenderHtmlAsPdfUA(html);
ConfigureStandardMetadata(pdf, title, author);
return pdf;
}
public PdfDocument CreateForm(string title, string formHtml, string author)
{
string html = GetFormTemplate(title, formHtml);
PdfDocument pdf = _renderer.RenderHtmlAsPdfUA(html);
ConfigureStandardMetadata(pdf, title, author);
return pdf;
}
private string GetReportTemplate(string title, string content)
{
return $@"
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<title>{System.Web.HttpUtility.HtmlEncode(title)}</title>
<style>
body {{
font-family: 'Segoe UI', Arial, sans-serif;
line-height: 1.6;
max-width: 800px;
margin: 0 auto;
padding: 40px;
color: #333;
}}
h1 {{ font-size: 28px; color: #1a1a1a; border-bottom: 2px solid #0066cc; padding-bottom: 10px; }}
h2 {{ font-size: 22px; color: #333; margin-top: 30px; }}
h3 {{ font-size: 18px; color: #555; }}
p {{ margin-bottom: 15px; }}
table {{ border-collapse: collapse; width: 100%; margin: 20px 0; }}
th, td {{ border: 1px solid #ddd; padding: 12px; text-align: left; }}
th {{ background-color: #f5f5f5; }}
</style>
</head>
<body>
<h1>{System.Web.HttpUtility.HtmlEncode(title)}</h1>
{content}
</body>
</html>";
}
private string GetFormTemplate(string title, string formContent)
{
return $@"
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<title>{System.Web.HttpUtility.HtmlEncode(title)}</title>
<style>
body {{
font-family: 'Segoe UI', Arial, sans-serif;
line-height: 1.6;
padding: 40px;
color: #333;
}}
h1 {{ font-size: 24px; margin-bottom: 20px; }}
.form-group {{ margin-bottom: 20px; }}
label {{ display: block; margin-bottom: 5px; font-weight: 600; }}
input[type='text'], input[type='email'], textarea, select {{
width: 100%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 14px;
}}
fieldset {{ border: 1px solid #ddd; padding: 15px; margin: 20px 0; }}
legend {{ font-weight: 600; padding: 0 10px; }}
</style>
</head>
<body>
<h1>{System.Web.HttpUtility.HtmlEncode(title)}</h1>
<form>
{formContent}
</form>
</body>
</html>";
}
private void ConfigureStandardMetadata(PdfDocument pdf, string title, string author)
{
pdf.MetaData.Title = title;
pdf.MetaData.Author = author;
pdf.MetaData.Creator = "Enterprise Document System";
pdf.MetaData.CreationDate = DateTime.Now;
pdf.MetaData.ModifiedDate = DateTime.Now;
}
}
Imports IronPdf
Imports System
Public Class AccessibleDocumentService
Private ReadOnly _renderer As ChromePdfRenderer
Public Sub New()
_renderer = New ChromePdfRenderer()
_renderer.RenderingOptions.CreatePdfFormsFromHtml = True
End Sub
Public Function CreateReport(title As String, content As String, author As String) As PdfDocument
Dim html As String = GetReportTemplate(title, content)
Dim pdf As PdfDocument = _renderer.RenderHtmlAsPdfUA(html)
ConfigureStandardMetadata(pdf, title, author)
Return pdf
End Function
Public Function CreateForm(title As String, formHtml As String, author As String) As PdfDocument
Dim html As String = GetFormTemplate(title, formHtml)
Dim pdf As PdfDocument = _renderer.RenderHtmlAsPdfUA(html)
ConfigureStandardMetadata(pdf, title, author)
Return pdf
End Function
Private Function GetReportTemplate(title As String, content As String) As String
Return $"
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<title>{System.Web.HttpUtility.HtmlEncode(title)}</title>
<style>
body {{
font-family: 'Segoe UI', Arial, sans-serif;
line-height: 1.6;
max-width: 800px;
margin: 0 auto;
padding: 40px;
color: #333;
}}
h1 {{ font-size: 28px; color: #1a1a1a; border-bottom: 2px solid #0066cc; padding-bottom: 10px; }}
h2 {{ font-size: 22px; color: #333; margin-top: 30px; }}
h3 {{ font-size: 18px; color: #555; }}
p {{ margin-bottom: 15px; }}
table {{ border-collapse: collapse; width: 100%; margin: 20px 0; }}
th, td {{ border: 1px solid #ddd; padding: 12px; text-align: left; }}
th {{ background-color: #f5f5f5; }}
</style>
</head>
<body>
<h1>{System.Web.HttpUtility.HtmlEncode(title)}</h1>
{content}
</body>
</html>"
End Function
Private Function GetFormTemplate(title As String, formContent As String) As String
Return $"
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<title>{System.Web.HttpUtility.HtmlEncode(title)}</title>
<style>
body {{
font-family: 'Segoe UI', Arial, sans-serif;
line-height: 1.6;
padding: 40px;
color: #333;
}}
h1 {{ font-size: 24px; margin-bottom: 20px; }}
.form-group {{ margin-bottom: 20px; }}
label {{ display: block; margin-bottom: 5px; font-weight: 600; }}
input[type='text'], input[type='email'], textarea, select {{
width: 100%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 14px;
}}
fieldset {{ border: 1px solid #ddd; padding: 15px; margin: 20px 0; }}
legend {{ font-weight: 600; padding: 0 10px; }}
</style>
</head>
<body>
<h1>{System.Web.HttpUtility.HtmlEncode(title)}</h1>
<form>
{formContent}
</form>
</body>
</html>"
End Function
Private Sub ConfigureStandardMetadata(pdf As PdfDocument, title As String, author As String)
pdf.MetaData.Title = title
pdf.MetaData.Author = author
pdf.MetaData.Creator = "Enterprise Document System"
pdf.MetaData.CreationDate = DateTime.Now
pdf.MetaData.ModifiedDate = DateTime.Now
End Sub
End ClassAutomated testing should be part of your continuous integration pipeline. Any process that generates PDFs should include validation steps that fail the build when accessibility requirements are not met. This prevents inaccessible documents from reaching production.
Staff training matters as much as technical implementation. Content authors need to understand why accessibility matters and how their choices affect the final output. Teaching writers to use heading levels correctly, provide meaningful image descriptions, and structure tables well produces better source material that converts to compliant PDFs.
Version control for templates and regular accessibility audits help maintain compliance over time. As business requirements evolve and templates are modified, periodic reviews ensure that changes have not inadvertently introduced accessibility barriers.
Documentation of your accessibility approach creates institutional knowledge that survives staff turnover. Recording which standards you follow, what tools you use for validation, and what remediation procedures exist for identified issues helps maintain consistent practices across the organization.
Accessibility is not a one-time achievement but an ongoing commitment. Standards evolve, assistive technologies improve, and user needs change. Organizations that build accessibility into their standard workflows rather than treating it as an afterthought are best positioned to meet both current requirements and future expectations.
The techniques covered in this guide provide a solid foundation for creating Section 508 compliant PDFs using IronPDF. By combining proper HTML structure, appropriate metadata, navigational aids, and validation testing, .NET developers can produce documents that meet legal requirements while genuinely serving users who depend on accessible content.
Conclusion
This tutorial demonstrated how to create Section 508 compliant and PDF/UA accessible documents using IronPDF in C#. The key capabilities covered include:
- Converting existing PDFs to PDF/UA format with the
SaveAsPdfUAmethod - Rendering HTML directly to accessible PDFs using
RenderHtmlAsPdfUA - Setting document metadata and language specifications for screen reader compatibility
- Creating correctly tagged document structures from semantic HTML
- Building accessible tables, forms, and navigation with bookmarks
- Validating PDF/UA compliance using external tools like veraPDF
IronPDF simplifies the complexity of PDF accessibility standards, allowing .NET developers to focus on content while the library handles the underlying PDF/UA structure requirements.
Ready to start creating accessible PDFs? Download IronPDF to begin your free trial, or explore the PDF/UA how-to guide for more detailed examples.
If you have questions about IronPDF or need assistance with accessibility implementation, please contact our support team.
Frequently Asked Questions
What is Section 508 compliance for PDFs?
Section 508 compliance ensures that electronic and information technology, such as PDFs, are accessible to people with disabilities. IronPDF helps create PDFs that meet these standards by allowing you to add alt text, build accessible tables, and more.
How can I use IronPDF to convert existing PDFs to PDF/UA?
IronPDF offers features to convert existing PDFs to PDF/UA, ensuring they meet accessibility standards. This includes adding necessary metadata and structuring elements to make content accessible.
Can IronPDF help with rendering accessible HTML?
Yes, IronPDF can render HTML content that is accessible and compliant with PDF/UA standards, making it easier to create accessible documents from web content.
How do I add alt text to images in PDFs using IronPDF?
IronPDF allows you to add alt text to images within PDFs, which is crucial for accessibility. This feature ensures that images are described for users relying on screen readers.
What features does IronPDF offer for building accessible tables and forms?
IronPDF provides tools for creating structured tables and forms that are accessible, helping ensure that data and input fields are navigable and understandable for all users.
How can I validate the compliance of my PDFs with government requirements using IronPDF?
IronPDF includes validation tools to check if your PDFs comply with Section 508 and PDF/UA requirements, helping you ensure that your documents meet necessary accessibility standards.
Is it possible to automate the creation of accessible PDFs with IronPDF?
Yes, IronPDF can be integrated into automated workflows to consistently produce accessible PDFs, streamlining the process of meeting compliance standards.
What programming languages are compatible with IronPDF for creating accessible PDFs?
IronPDF is designed to work with C#, allowing developers to create accessible PDFs directly within the .NET framework.
Are there any tutorials available for learning how to use IronPDF?
Yes, IronPDF provides comprehensive tutorials and documentation to guide you through the process of creating accessible PDFs and utilizing all of its features effectively.
Can IronPDF assist with multilingual PDF accessibility?
IronPDF supports the creation of multilingual accessible PDFs by handling Unicode text and languages, ensuring accessibility across different language documents.






