Skip to content

PDF accessible

Créez des PDF accessibles qui fonctionnent avec les lecteurs d'écran et les technologies d'assistance en utilisant structure balisée, texte alternatif et balisage de langue.

Qu'est-ce qui rend un PDF accessible ?

ExigencePourquoi c'est important
Balises de structureLes lecteurs d'écran utilisent les balises titre/paragraphe/liste pour navigation
Texte alternatifDécrit les images aux utilisateurs qui ne peuvent pas les voir
Balise de langueIndique au lecteur comment prononcer le texte
Ordre de lectureOrdre logique indépendant de la mise en page visuelle
En-têtes de tableauAssocie les cellules de données à leur contexte colonne/ligne
SignetsNavigation au clavier pour documents longs

Standards

StandardPortée
PDF/UA-2 (ISO 14289-2)Accessibilité universelle PDF
WCAG 2.1Web Content Accessibility Guidelines
Section 508Accessibilité fédérale US
EN 301 549Exigences d'accessibilité UE

Exemple de code complet

php
<?php

declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

use TcpdfNext\Document;
use TcpdfNext\Enums\Alignment;
use TcpdfNext\Accessibility\TagManager;

// ── 1. Activer PDF balisé ───────────────────────────────────────────────
$pdf = Document::create()
    ->setTitle('Accessibility Report 2026')
    ->setAuthor('Acme Corp')
    ->setLanguage('en-US')
    ->setTagged(true)
    ->setDisplayDocTitle(true)
    ->addPage();

$tag = $pdf->getTagManager();

// ── 2. Titre (H1) ───────────────────────────────────────────────────
$tag->beginTag('H1');
$pdf->setFont('helvetica', style: 'B', size: 24)
    ->cell(0, 14, 'Accessibility Report 2026', newLine: true);
$tag->endTag();

// ── 3. Paragraphe ──────────────────────────────────────────────────────
$tag->beginTag('P');
$pdf->setFont('times', size: 12)
    ->multiCell(0, 7, 'Acme Corp is committed to producing documents that '
        . 'meet PDF/UA and WCAG 2.1 AA standards, ensuring equal access '
        . 'for all users regardless of ability.');
$tag->endTag();

// ── 4. Sous-titre (H2) ──────────────────────────────────────────────
$tag->beginTag('H2');
$pdf->setFont('helvetica', style: 'B', size: 18)
    ->cell(0, 12, 'Key Metrics', newLine: true);
$tag->endTag();

// ── 5. Liste balisée ────────────────────────────────────────────────────
$items = [
    'Documents audited: 1,240',
    'Compliance rate: 98.7%',
    'Issues resolved: 412',
];

$tag->beginTag('L');
foreach ($items as $item) {
    $tag->beginTag('LI');

    $tag->beginTag('Lbl');
    $pdf->setFont('helvetica', size: 11)
        ->cell(8, 7, "\u{2022}");
    $tag->endTag(); // Lbl

    $tag->beginTag('LBody');
    $pdf->cell(0, 7, $item, newLine: true);
    $tag->endTag(); // LBody

    $tag->endTag(); // LI
}
$tag->endTag(); // L

// ── 6. Image avec texte alternatif ────────────────────────────────────────────
$tag->beginTag('Figure');
$pdf->image(
    file:    __DIR__ . '/assets/compliance-chart.png',
    x:       null,
    y:       null,
    width:   120,
    height:  null,
    altText: 'Bar chart showing compliance rate rising from 91% in 2023 '
           . 'to 98.7% in 2026 across four consecutive years.',
);
$tag->beginTag('Caption');
$pdf->setFont('helvetica', style: 'I', size: 9)
    ->cell(0, 6, 'Figure 1: Compliance trend 2023-2026', newLine: true);
$tag->endTag(); // Caption
$tag->endTag(); // Figure

// ── 7. Élément décoratif comme artefact (ignoré par lecteurs d'écran) ─────
$tag->beginArtifact('Layout');
$pdf->setDrawColor(200, 200, 200)
    ->line(15, $pdf->getY(), 195, $pdf->getY());
$tag->endArtifact();

// ── 8. Tableau balisé ───────────────────────────────────────────────────
$tag->beginTag('H2');
$pdf->setFont('helvetica', style: 'B', size: 18)
    ->cell(0, 12, 'Quarterly Results', newLine: true);
$tag->endTag();

$tag->beginTag('Table');

// Ligne d'en-tête
$tag->beginTag('TR');
foreach (['Quarter', 'Audited', 'Passed', 'Rate'] as $header) {
    $tag->beginTag('TH', attributes: ['scope' => 'col']);
    $pdf->setFont('helvetica', style: 'B', size: 10)
        ->cell(45, 8, $header, border: 1);
    $tag->endTag();
}
$tag->endTag(); // TR

// Lignes de données
$rows = [
    ['Q1', '310', '305', '98.4%'],
    ['Q2', '320', '316', '98.8%'],
    ['Q3', '305', '302', '99.0%'],
    ['Q4', '305', '301', '98.7%'],
];
foreach ($rows as $row) {
    $tag->beginTag('TR');
    foreach ($row as $i => $cell) {
        $tagName = $i === 0 ? 'TH' : 'TD';
        $attrs   = $i === 0 ? ['scope' => 'row'] : [];
        $tag->beginTag($tagName, attributes: $attrs);
        $pdf->setFont('times', size: 10)
            ->cell(45, 8, $cell, border: 1);
        $tag->endTag();
    }
    $tag->endTag(); // TR
}
$tag->endTag(); // Table

// ── 9. Balisage de langue pour texte étranger ──────────────────────────────────────
$tag->beginTag('P', attributes: ['lang' => 'de-DE']);
$pdf->setFont('times', size: 11)
    ->multiCell(0, 7, 'Barrierefreiheit ist ein grundlegendes Recht.');
$tag->endTag();

// ── 10. Sauvegarder ──────────────────────────────────────────────────────────
$pdf->save(__DIR__ . '/accessible-report.pdf');

echo 'Accessible PDF created.' . PHP_EOL;

Auto-balisage HTML

TCPDF-Next peut générer des balises de structure automatiquement depuis HTML sémantique :

php
$pdf = Document::create()
    ->setTagged(true)
    ->setLanguage('en-US')
    ->addPage();

$pdf->setAutoTagging(true)
    ->writeHtml(<<<'HTML'
        <h1>Report</h1>
        <p>Summary paragraph.</p>
        <img src="chart.png" alt="Revenue chart showing 15% growth" />
        <table>
            <tr><th>Q</th><th>Revenue</th></tr>
            <tr><td>Q1</td><td>$548M</td></tr>
        </table>
    HTML);
Élément HTMLBalise PDF
<h1>--<h6>H1--H6
<p>P
<img alt="...">Figure
<table>Table
<th>TH
<td>TD
<ul>, <ol>L
<li>LI
<a>Link

Liste de contrôle d'accessibilité

  • [ ] setTitle() -- titre du document défini
  • [ ] setDisplayDocTitle(true) -- visualiseur affiche titre, pas nom de fichier
  • [ ] setLanguage('en-US') -- langue du document déclarée
  • [ ] Tout contenu enveloppé dans balises de structure
  • [ ] Titres en ordre séquentiel (H1, H2, H3 -- pas de sauts)
  • [ ] Toutes les images significatives ont altText
  • [ ] Images décoratives marquées comme artefacts
  • [ ] Tableaux ont cellules TH avec attribut scope
  • [ ] Ordre de lecture correspond à l'ordre logique
  • [ ] Ratio de contraste de couleur au moins 4.5:1

Validation

bash
# Utiliser PAC (PDF Accessibility Checker) pour validation PDF/UA
# https://pdfua.foundation/en/pac-download/

Lecture complémentaire

Distribué sous licence LGPL-3.0-or-later.