How to Create Section 508 Compliant and Accessible PDFs in C# with IronPDF

Accessible PDF generation in C# .NET with IronPDF produces PDF/UA compliant documents that meet Section 508 and WCAG 2.0 AA requirements out of the box. IronPDF's RenderHtmlAsPdfUA method automatically adds tagged content structure, reading order, alternative text handling, and accessibility metadata to PDFs generated from HTML, letting .NET developers build screen-reader-compatible documents for government agencies, healthcare providers, and any organization working with federal contracts.

TL;DR: Quickstart Guide

This tutorial covers creating Section 508 compliant and PDF/UA accessible documents in C# .NET, from tagged structure generation to form accessibility and compliance validation.

  • Who this is for: .NET developers on government contracts, federal projects, or healthcare/education systems where PDF accessibility is legally required.
  • What you'll build: PDF/UA generation from HTML, legacy PDF conversion to PDF/UA, language tagging, tagged structure from semantic HTML, alt text for images, accessible tables, bookmark navigation, and labeled form fields.
  • Where it runs: .NET 10, .NET 8 LTS, .NET Framework 4.6.2+, and .NET Standard 2.0.
  • When to use this approach: When your PDFs must pass Section 508 audits, PDF/UA (ISO 14289) validation, or WCAG 2.0 Level AA requirements.
  • Why it matters technically: Standard PDFs lack semantic structure. IronPDF builds the tagged content tree that screen readers need automatically from well-formed HTML.

Create a Section 508 compliant PDF/UA document with just a few lines of code:

  1. Install IronPDF with NuGet Package Manager

    PM > Install-Package IronPdf
  2. 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");
  3. Deploy to test on your live environment

    Start using IronPDF in your project today with a free trial

    arrow pointer

After you've purchased or signed up for a 30-day trial of IronPDF, add your license key at the start of your application.

IronPdf.License.LicenseKey = "KEY";
IronPdf.License.LicenseKey = "KEY";
Imports IronPdf

IronPdf.License.LicenseKey = "KEY"
$vbLabelText   $csharpLabel

Start using IronPDF in your project today with a free trial.

First Step:
green arrow pointer
NuGet Install with NuGet

PM >  Install-Package IronPdf

Check out IronPDF on NuGet for quick installation. With over 10 million downloads, it’s transforming PDF development with C#. You can also download the DLL or Windows installer.

Table of Contents


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.cs
using IronPdf;
using System;

string inputPath = "document.pdf";
string outputPath = "document-accessible.pdf";

// 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
Imports System

Dim inputPath As String = "document.pdf"
Dim outputPath As String = "document-accessible.pdf"

' 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.")
$vbLabelText   $csharpLabel

For documents that were originally rendered from HTML with a lang attribute, the language specification is preserved in the PDF/UA structure. The following example shows how language tagging carries through from the HTML source.

Input PDF

This example uses benefits-summary.pdf, a benefits document that needs accessibility conversion with the language preserved from its original HTML source.

The code loads the PDF and calls SaveAsPdfUA() to convert it. The language specification from the original HTML lang attribute is preserved in the PDF/UA structure, ensuring screen readers use correct pronunciation rules.

:path=/static-assets/pdf/content-code-examples/tutorials/accessible-pdfs-government-compliance/convert-with-language.cs
using IronPdf;
using System;

string inputPath = "document.pdf";
string outputPath = "document-accessible.pdf";

PdfDocument pdf = PdfDocument.FromFile(inputPath);

// Language is specified via the lang attribute in the HTML source.
// The PDF/UA structure preserves the language for screen readers.
pdf.SaveAsPdfUA(outputPath);

Console.WriteLine("Conversion complete with language specification.");
Imports IronPdf
Imports System

Module Program
    Sub Main()
        Dim inputPath As String = "document.pdf"
        Dim outputPath As String = "document-accessible.pdf"

        Dim pdf As PdfDocument = PdfDocument.FromFile(inputPath)

        ' Language is specified via the lang attribute in the HTML source.
        ' The PDF/UA structure preserves the language for screen readers.
        pdf.SaveAsPdfUA(outputPath)

        Console.WriteLine("Conversion complete with language specification.")
    End Sub
End Module
$vbLabelText   $csharpLabel

IronPDF 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.cs
using IronPdf;
using System;

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
Imports System

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.")
$vbLabelText   $csharpLabel

Output 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.cs
using IronPdf;

ChromePdfRenderer renderer = new ChromePdfRenderer();

// Render from an HTML file on disk
PdfDocument pdfFromFile = renderer.RenderHtmlFileAsPdf("report.html");

// Convert the rendered PDF to PDF/UA format
pdfFromFile.SaveAsPdfUA("report-accessible.pdf");

// Render from a web URL
PdfDocument pdfFromUrl = renderer.RenderUrlAsPdf("https://example.com");

// Convert to accessible format
pdfFromUrl.SaveAsPdfUA("webpage-accessible.pdf");
Imports IronPdf

Dim renderer As New ChromePdfRenderer()

' Render from an HTML file on disk
Dim pdfFromFile As PdfDocument = renderer.RenderHtmlFileAsPdf("report.html")

' Convert the rendered PDF to PDF/UA format
pdfFromFile.SaveAsPdfUA("report-accessible.pdf")

' Render from a web URL
Dim pdfFromUrl As PdfDocument = renderer.RenderUrlAsPdf("https://example.com")

' Convert to accessible format
pdfFromUrl.SaveAsPdfUA("webpage-accessible.pdf")
$vbLabelText   $csharpLabel

How 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.cs
using IronPdf;
using System;

PdfDocument pdf = PdfDocument.FromFile("document.pdf");

// 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("document-accessible.pdf");

Console.WriteLine("Document metadata configured for accessibility.");
Imports IronPdf
Imports System

Dim pdf As PdfDocument = PdfDocument.FromFile("document.pdf")

' 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("document-accessible.pdf")

Console.WriteLine("Document metadata configured for accessibility.")
$vbLabelText   $csharpLabel

The 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.cs
using IronPdf;
using System;

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

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")
$vbLabelText   $csharpLabel

How 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 lang attribute in the HTML source, which is preserved in the PDF/UA output.

The code demonstrates two language scenarios. The first renders English HTML content with lang='en' on the html element, and the second handles Spanish content with lang='es'. The RenderHtmlAsPdfUA() method preserves the language attribute from the HTML, and SaveAsPdfUA() maintains it in the output. This 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.cs
using IronPdf;

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);

// Language is set via lang='en' in the HTML; SaveAsPdfUA preserves it
pdf.SaveAsPdfUA("annual-report.pdf");

string htmlContentEs = @"
<!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 pdfEs = renderer.RenderHtmlAsPdfUA(htmlContentEs);

// Language is set via lang='es' in the HTML; SaveAsPdfUA preserves it
pdfEs.SaveAsPdfUA("informe-anual.pdf");
Imports IronPdf

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)

' Language is set via lang='en' in the HTML; SaveAsPdfUA preserves it
pdf.SaveAsPdfUA("annual-report.pdf")

Dim htmlContentEs 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 pdfEs As PdfDocument = renderer.RenderHtmlAsPdfUA(htmlContentEs)

' Language is set via lang='es' in the HTML; SaveAsPdfUA preserves it
pdfEs.SaveAsPdfUA("informe-anual.pdf")
$vbLabelText   $csharpLabel

IronPDF supports language specification through the standard HTML lang attribute. Common language codes include en (English), es (Spanish), fr (French), de (German), pt (Portuguese), zh (Chinese), ja (Japanese), ko (Korean), and ar (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.cs
using IronPdf;
using System;

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
Imports System

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.")
$vbLabelText   $csharpLabel

Output 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.cs
using IronPdf;
using System;

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
Imports System

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.")
$vbLabelText   $csharpLabel

Writing 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="">
HTML

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.cs
using IronPdf;
using System;

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
Imports System

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.")
$vbLabelText   $csharpLabel

Output 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.cs
using IronPdf;
using System;

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);
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
Imports System

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)
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.")
$vbLabelText   $csharpLabel

Output 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.cs
using IronPdf;

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

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")
$vbLabelText   $csharpLabel

The 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.cs
using IronPdf;
using System;

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
Imports System

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.")
$vbLabelText   $csharpLabel

Output 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 a complete validation workflow. First, it generates a test PDF using RenderHtmlAsPdfUA() with metadata configured. Then it invokes veraPDF from C# using Process.Start(), configuring the process to run with the --flavour ua1 flag for PDF/UA-1 validation. The output is captured and the exit code determines whether the document passes validation.

:path=/static-assets/pdf/content-code-examples/tutorials/accessible-pdfs-government-compliance/validation.cs
using IronPdf;
using System;
using System.Diagnostics;

// 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}");

// Validate using veraPDF
string verapdfPath = "verapdf";
ProcessStartInfo startInfo = new ProcessStartInfo
{
    FileName = verapdfPath,
    Arguments = $"--flavour ua1 \"{outputPath}\"",
    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);
}
Imports IronPdf
Imports System
Imports System.Diagnostics

' 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}")

' Validate using veraPDF
Dim verapdfPath As String = "verapdf"
Dim startInfo As New ProcessStartInfo With {
    .FileName = verapdfPath,
    .Arguments = $"--flavour ua1 ""{outputPath}""",
    .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)
End Using
$vbLabelText   $csharpLabel

Adobe 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 demonstrates an enterprise report generation pattern. It initializes a ChromePdfRenderer with form creation enabled, then builds an HTML report from template variables using HttpUtility.HtmlEncode() for safe content insertion. The report HTML includes consistent styling and semantic structure. After rendering with RenderHtmlAsPdfUA(), standard metadata properties (title, author, creator, and dates) are configured before saving. This pattern can be wrapped into a reusable service to enforce accessibility compliance across all generated documents.

:path=/static-assets/pdf/content-code-examples/tutorials/accessible-pdfs-government-compliance/enterprise-service.cs
using IronPdf;
using System;
using System.Web;

ChromePdfRenderer renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CreatePdfFormsFromHtml = true;

string title = "Quarterly Report";
string author = "Finance Team";
string content = "<p>Financial performance overview for Q4 2024.</p>";

// Build report HTML from template
string reportHtml = $@"
<!DOCTYPE html>
<html lang='en'>
<head>
    <meta charset='UTF-8'>
    <title>{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; }}
        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>{HttpUtility.HtmlEncode(title)}</h1>
    {content}
</body>
</html>";

PdfDocument pdf = renderer.RenderHtmlAsPdfUA(reportHtml);

// Configure standard metadata
pdf.MetaData.Title = title;
pdf.MetaData.Author = author;
pdf.MetaData.Creator = "Enterprise Document System";
pdf.MetaData.CreationDate = DateTime.Now;
pdf.MetaData.ModifiedDate = DateTime.Now;

pdf.SaveAs("quarterly-report-accessible.pdf");
Imports IronPdf
Imports System
Imports System.Web

Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.CreatePdfFormsFromHtml = True

Dim title As String = "Quarterly Report"
Dim author As String = "Finance Team"
Dim content As String = "<p>Financial performance overview for Q4 2024.</p>"

' Build report HTML from template
Dim reportHtml As String = $"
<!DOCTYPE html>
<html lang='en'>
<head>
    <meta charset='UTF-8'>
    <title>{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; }}
        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>{HttpUtility.HtmlEncode(title)}</h1>
    {content}
</body>
</html>"

Dim pdf As PdfDocument = renderer.RenderHtmlAsPdfUA(reportHtml)

' Configure standard metadata
pdf.MetaData.Title = title
pdf.MetaData.Author = author
pdf.MetaData.Creator = "Enterprise Document System"
pdf.MetaData.CreationDate = DateTime.Now
pdf.MetaData.ModifiedDate = DateTime.Now

pdf.SaveAs("quarterly-report-accessible.pdf")
$vbLabelText   $csharpLabel

Automated 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

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. This tutorial covered converting existing PDFs to PDF/UA format, rendering HTML directly to accessible PDFs, setting document metadata and language specifications for screen reader compatibility, creating tagged document structures from semantic HTML, building accessible forms and navigation with bookmarks, and validating compliance using external tools like veraPDF.

When accessibility is part of a broader document lifecycle, these patterns pair naturally with PDF/A archival compliance for long-term preservation and batch processing for generating accessible documents at scale across government or healthcare systems.

Ready to start building? Download IronPDF and try it with a free trial. The same library handles everything from single accessible document generation to enterprise-wide PDF/UA compliance pipelines. If you have questions about accessibility implementation or Section 508 requirements, reach out to our engineering 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.

Curtis Chau
Technical Writer

Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.

...

Read More
Ready to Get Started?
Nuget Downloads 18,049,106 | Version: 2026.4 just released
Still Scrolling Icon

Still Scrolling?

Want proof fast? PM > Install-Package IronPdf
run a sample watch your HTML become a PDF.