Documentation page: PD4ML v42 — HTML5 Element Support Matrix. This page is also available as Markdown at html5-element-support-matrix.md.

PD4ML v42 — HTML5 Element Support Matrix

Every row below was verified directly against the v42 engine's own source (com.pd4ml.html.engine — the CSS cascade, the built-in user-agent stylesheet, the legacy-attribute presentational hints, and the layout/paint code) rather than inferred from documentation. Where an attribute or CSS property is parsed but produces no visible effect, it's marked accordingly instead of left ambiguous.

Canonical tag/attribute/CSS-property lists per the WHATWG HTML Living Standard and the CSS specifications. Comparisons against the older v40 engine are stated only where the v42 source itself carries an explicit comment documenting the change — nothing below is an assumption about v40 behavior.

Key cross-cutting findings

The dozen or so facts most worth knowing before relying on this engine for a given document — pulled out of the full matrix below because they cut across many tags or are easy to miss inside a single row.

  • Needs verification<form> family — PD4ML.generateForms() (real AcroForm field generation) has zero references anywhere under the v42 html.engine package; it appears wired only to the legacy v40 pipeline. Form controls may render as flat static graphics only under v42 despite the Programmer's Manual describing this as a supported feature. Worth an independent live check before depending on it.
  • Real gap<meta charset> / http-equiv is not read anywhere — source encoding is decided purely by BOM sniffing or a charset the calling code supplies explicitly.
  • Real gap<q> generates no automatic quotation marks (no ::before/::after content rule in the UA stylesheet) — every real browser adds them by default.
  • Real gap<bdi> never gets the implicit unicode-bidi: isolate real browsers give it automatically; the isolation machinery exists in the engine but nothing applies it to a bare <bdi>.
  • Real gap<plaintext> doesn't switch the tokenizer into a permanent raw-text state — markup after it is still parsed normally, unlike every real browser's (admittedly bizarre) spec-mandated behavior.
  • Real gap<dialog open> is a complete no-op — content renders identically with or without the attribute, unlike the browser default of dialog:not([open]){display:none}.
  • Placeholder only<iframe>, <embed>, <object>, <canvas>, <video> all fall through the same generic branch: a sized gray box with a centered label, no fetch/decode/render of the referenced content at all.
  • Known limitation<ol reversed> ignores any sibling <li value=N> override — the reversed-numbering path counts total children only, unlike the forward-counting path.
  • Known limitationtab-size parses into the cascade but the tab-expansion code has an 8-space width hardcoded — an authored value is never actually consulted.
  • Known limitation — The HTML5 "strip one leading newline after the opening tag" rule is implemented for <textarea> only — <pre> and <listing> both show a spurious leading blank line real browsers suppress.
  • Known limitation<meter> ignores low/high/optimum entirely — the fill is always a fixed green regardless of value zone.
  • Known limitation<th scope> is parsed but never inspected — PDF/UA table-header structure tagging picks TH vs. TD purely from tag name.
  • Unverified, likely gap<wbr> has no dedicated soft-break-opportunity marker in the line-breaking code, unlike <br>'s explicit hard-break flag — probably doesn't offer a genuine break point mid-word the way Chrome's does.
  • Known limitation — No real HTML image-map support: <area shape/coords> produces no per-region PDF link annotations — only whole-image or whole-anchor hyperlinks work.
  • Genuinely implemented — Flexbox and CSS Grid are real, working layout modes (dedicated FlexLayout/GridLayout), not just parsed-and-ignored. <svg> renders true vector output and <math> renders real MathML via JEuclid — neither is a placeholder.
  • Genuinely implemented<details>/<summary> disclosure markers, <fieldset>/<legend> notched borders, <picture>/<source> media-query selection, table colspan/rowspan with per-segment collapsed borders, and <select> dropdown/listbox modes are all real, specifically-built implementations, not incidental side effects.

Document metadata, sectioning & grouping content

The document skeleton, landmarks, headings, and block-level grouping elements.

Tag Status Attributes CSS properties Comments
<html> Full lang (read generically for bidi/hyphenation elsewhere); dir="rtl"|"ltr" (case-insensitive) UA default: block, serif 16px — matches Chrome's actual default font, not a generic sans guess Auto-inserted by the tree builder if omitted.
<head> Full none read display:none Auto-inserted if missing; base/basefont/bgsound/link/meta/title/style/script/template are forced into it regardless of source position.
<title> Full none display:none Content genuinely consumed — Document.getTitle() returns the first <title>'s trimmed, entity-decoded text (RCDATA parsing, tags inside not recognized). Used e.g. for CLI output filenames. A stray second <title> is ignored.
<base> Full href (real relative-URL resolution); target (no navigation concept in PDF output) display:none Only the first <base href> in the document is honored, matching the HTML5 rule.
<link> Partial rel="stylesheet" (real external CSS loading, gated by config.loadExternalResources); href, media both honored; rel="alternate stylesheet" correctly excluded; other rel values (icon, preload, manifest…) inert display:none The one rel value that matters for a print/PDF target is fully wired.
<meta> Partial charset, http-equiv, name="viewport" — none read anywhere in the engine display:none Real gap: encoding correctness for meta-charset-only documents depends entirely on BOM sniffing or the caller supplying the right charset. viewport having no effect is correct/expected for a paged renderer.
<style> Full type (must be empty/text/css or the block is skipped), media display:none; content parsed as an author-origin stylesheet, incl. @import Cleanly wired into the cascade.
<body> Partial text→color, bgcolor→background-color, background→background-image url(), link→ a --link-color variable; vlink, alink not read UA default display:block; margin:8px Legacy presentational attributes well covered except visited/active link colors.
<article> <section> <nav> <aside> <header> <footer> <address> <main> Full none tag-specific block (UA); address also gets font-style:italic Flex/grid containers work identically here (layout mode is display-driven, not tag-specific). PDF/UA tagging is coarser than the full landmark set — section/nav/main/article map to a generic "Paragraph"-kind struct tag; aside/header/footer/address get no dedicated PDF role. Accessibility-tagging nuance only, not a visual gap.
<h1><h6> Full none Per-level font-size/weight/margin matching Chrome's own defaults exactly (h1 2em…h6 0.67em) Tagged as "Paragraph"-kind for PDF/UA, not a distinct H1–H6 heading structure type.
<hgroup> Full none display:block only Plain block container — no special heading/subtitle grouping or outline behavior, which is an acceptable simplification for a static renderer.
<p> Full none display:block; margin:1em 0 Implicit-close set (on encountering pre/table/headings/lists/hr/etc.) closely matches the HTML5 spec's own optional-tag rules.
<hr> Partial size→height (confirmed not to flatten into a solid bar, matching Chrome); noshadeborder-style:solid; width/height legacy attrs; color (not read at all — a legacy color="red" is a no-op) UA default border:1px inset #808080; height:0 size/noshade/width genuinely wired; color is the one legacy attribute left unimplemented.
<pre> Partial none tag-specific font-family:monospace; white-space:pre; tab-size parses into the cascade but tab-expansion is hardcoded to 8 spaces — an authored value has no effect No leading-newline-after-opening-tag stripping (unlike <textarea>, which does this correctly) — a real spec deviation, produces a spurious leading blank line.
<blockquote> Full cite (parsed, never read — correct, real browsers also give it no visual effect) margin:1em 40px
<ol> Partial start (parsed int, default 1); reversed (counts down from total <li> count); type="1"|"a"|"A"|"i"|"I"→list-style-type list-style-type:decimal; padding-left:40px Known bug: reversed ignores any sibling <li value=N> override, unlike the forward-counting path. Marker glyph support covers decimal/alpha/roman/greek/disc/circle/square/disclosure — other CSS keywords (armenian, georgian, hebrew, cjk-decimal…) silently fall back to plain decimal even if they parse.
<ul> Full type="disc"|"circle"|"square"|"none" list-style-type:disc; nested ul ul→circle, 3-deep→square Same marker-glyph coverage caveat as <ol> above.
<menu> Full grouped identically to <ul> same as <ul> Matches the modern spec's treatment of <menu> as a <ul> synonym.
<li> Full value (own numbering + bumps subsequent forward-counted siblings); type display:list-item; text-align:start An orphan <li> with no list ancestor and no room for an outside marker falls back to inside-style positioning (documented prior fix).
<dl> Full none margin:1em 0
<dt> Full none font-weight:normal
<dd> Full none margin-left:40px
<figure> Full none margin:1em 40px
<figcaption> Full none display:block, no special margin An ordinary block child — correctly NOT split into a separate out-of-flow box the way <table>``<caption> is (that's a CSS2.1-specific requirement figcaption doesn't share).
<div> Full none display:block; works identically as a flex/grid container Generic container — full CSS property registry applies.
<search> Full none display:block Newer HTML5 landmark — confirmed present in both the UA stylesheet and the parser's known-element/implicit-close sets, not falling back to inline.

Text-level semantics & embedded/media content

Inline formatting, edits, and everything that embeds external or generated content — images, frames, media, vector/math graphics.

Tag Status Attributes CSS properties Comments
<a> Full href (real PDF hyperlink annotation); title (PDF text annotation/tooltip); target, download (no-op — no window/download concept in PDF) a:any-link{color:#0000ee;text-decoration:underline}, a:visited{color:#551a8b} — a real :any-link match, so a bare <a name> with no href is deliberately NOT link-styled :any-link also matches area[href]/link[href].
<em> <cite> <dfn> <var> Full none font-style:italic Inline text formatting only.
<strong> Full none font-weight:bold
<small> Full none font-size:smaller
<s> Full none text-decoration:line-through Shares its UA rule with obsolete <strike>.
<q> Partial none special display:inline only Real gap: no auto-generated quotation marks — no ::before/::after content:open-quote/close-quote rule anywhere in the UA sheet. The quotes property and generated-content open-quote/close-quote values ARE implemented generically, so an author who writes the rule themselves gets real quote marks — the UA default just never supplies one.
<abbr> Full title [title]{text-decoration:dotted underline} — only fires when title is present
<ruby> Partial none display:inline Plain container — no real ruby-column layout algorithm, relies entirely on <rt>'s superscript trick.
<rt> Partial none display:inline; font-size:0.6em; vertical-align:super Approximated via superscript, not a distinct above-base-text line.
<rp> Full none display:none Correct fallback-parenthesis suppression.
<data> Full value (inert, as in real browsers) none tag-specific Plain inline element, no special-casing found.
<time> Full datetime (inert) none tag-specific Same treatment as <data>.
<code> <samp> <kbd> Full none font-family:monospace Inline text formatting only.
<sub> <sup> Full none vertical-align + reduced font-size per UA rule Inline text formatting only.
<i> <b> Full none italic / bold
<u> <ins> Full none text-decoration:underline
<del> Full none text-decoration:line-through
<mark> Full none background-color:#ffff00; color:#000
<bdi> Partial dir no implicit unicode-bidi:isolate Real gap: no UA rule sets isolation for a bare <bdi>, even though the isolation machinery (InlineLayout.resolveBidiLevels()) exists and is used elsewhere. An explicit dir attribute still works for direction via the generic [dir=rtl i]/[dir=ltr i] rules — only the automatic isolation half is missing.
<bdo> Full dir unicode-bidi:bidi-override Real forced-direction override, feeding the same bidi machinery.
<span> Full none none tag-specific Plain generic inline container.
<br> Full clear (legacy, maps to CSS clear) display:inline Gets a real forcedBreak=true flag — a genuine hard line break.
<wbr> Partial, unverified none display:inline No dedicated soft-break-opportunity flag found anywhere (contrast with <br>'s explicit hard-break flag) — likely doesn't act as a genuine mid-word break point the way Chrome's does. Absence-of-evidence finding, not confirmed by render diff.
<picture> Partial none tag-specific display:inline-block Real source selection: walks <source> children in order, evaluates each media query, picks the first match's srcset/src. type (MIME) matching on <source> is NOT checked — a type="image/webp" source is accepted regardless of whether the format can actually be decoded.
<source> Partial srcset, media, src — read only inside a <picture> parent n/a No dedicated handling inside <video>/<audio> (which never load any media at all — see below), so a <source> there is inert.
<img> Full src, srcset (real 1x/density and w-descriptor selection), alt (used only as a broken-image fallback, not painted over a successfully loaded image), width/height, hspace/vspace/border/align (legacy, mapped) object-fit/object-position-x/-y genuinely implemented and used at paint time Real decode via javax.imageio.ImageIO (JPEG/PNG/GIF/BMP per JVM plugins — no WebP, no animated-GIF frames beyond ImageIO's single-frame default). JPEG EXIF orientation is read and baked in at load time. <img src="*.svg"> is rasterized through the same SVG parser as inline <svg> but comes back opaque/white-background, not transparent. A broken image deliberately shows no placeholder icon or alt text (a document meant for print shouldn't visibly show a broken link) but still reserves its declared box space.
<iframe> Placeholder only src, srcdoc (not read); title shown as the placeholder's centered label; width/height (legacy, mapped) border:2px inset default Confirmed inert: no nested-document fetch or render of any kind — a flat gray fill with a border, the tag's title (or bare tag name) centered as text.
<embed> Placeholder only src (not read); title shown as placeholder label; width/height mapped display:inline-block Same generic gray-box placeholder as <iframe>/<object>/<canvas>/<video> — no fetch/render of the embedded resource.
<object> Placeholder only data (not read); title shown as placeholder label; width/height/hspace/vspace/border/align legacy attrs mapped display:inline-block Same placeholder-box treatment — no PDF/image embedding of data is attempted.
<param> N/A name, value (not read) n/a Entirely inert since its parent <object> never renders real content.
<video> Placeholder only width/height (legacy, mapped); src, poster, controls (not read) display:inline-block, default 300×150 box No frame decode, no poster extraction, no playback — a labeled gray box only.
<audio> Placeholder only controls (not read); width/height excluded from the legacy-attribute mapping tag list display:inline-block Own dedicated default sizing (300×54, matching Chrome's native control-bar height) but still no audio decode/playback — a sized placeholder only.
<track> N/A none read n/a Recognized only as a void element; no caption/subtitle text ever surfaced — consistent with video/audio never actually playing.
<map> Not supported name n/a Recognized as a structural tag; no layout/paint code references it.
<area> Not supported href (link-styled via :any-link); shape, coords, usemap, ismap (no evidence any of these do anything) n/a No real HTML image-map support — only whole-image/whole-anchor hyperlinks work, not per-region clickable areas.
<math> Full rendered via JEuclid, sized with the surrounding element's resolved font-size display:inline-block Genuine MathML rendering, not a placeholder — silently skipped (0×0) if disabled, JEuclid isn't on the classpath, or the formula fails to parse. Tagged as an Artifact (not Figure) for PDF/UA, since raw glyphs convey nothing to a screen reader.
<svg> Full width/height (legacy + CSS), viewbox display:inline-block; with a viewBox but no width/height, only the aspect ratio is derived (default 300 width) — deliberately does not auto-size to content the way a referenced <img src=*.svg> does Real vector rendering, painted directly onto the live graphics context (true vector PDF output, not rasterized). Malformed/unsupported SVG is silently skipped, not fatal. Known caveat: narrow adjacent table cells with SVG can lose content.
<canvas> Placeholder only width/height (legacy + CSS, real box sizing) display:inline-block, default 300×150 Confirmed no real 2D drawing context of any kind — same generic gray-box-with-label fallback as iframe/embed/object/video. Architecturally expected: there is no JS engine to run canvas-drawing script against.

Tables

Table structure, spanning, captions, and the collapsed/separated border models.

Tag Status Attributes CSS properties Comments
<table> Full border=N (1px outset gray border unless "0"; frame="void" clears border-style); cellspacing→border-spacing; width/height; align (left/right→float, center/middle→margin:auto) display:table; border-collapse; border-spacing-x/-y; table-layout; box-sizing:border-box align="center" centers the table box itself via margin:auto — a genuinely different code path from a replaced element's align (which uses vertical-align).
<caption> Full none special; width/height legacy attrs excluded caption-side:top|bottom — genuinely implemented CSS2.1 box-model split honored: caption is painted in its own band OUTSIDE the table's own border, not merged into it.
<colgroup> Full width (legacy px) display:table-column-group
<col> Full width display:table-column Contributes a genuine per-column width hint to the column-width distribution algorithm.
<thead> Full width/height excluded display:table-header-group; vertical-align:middle; border-color:inherit Tagged as PDF/UA THead structure.
<tbody> Full same exclusion as thead display:table-row-group Tagged TBody.
<tfoot> Full same exclusion display:table-footer-group Tagged TFoot.
<tr> Full width/height work display:table-row
<td> Full colspan/rowspan (incl. rowspan="0" = span to end of row-group, clamped to [1,1000]); inherited cellpadding/border from ancestor <table>; nowrap→white-space:nowrap; width/height per-segment collapsed-border resolution for rowspan/colspan cells A colspan-split synthetic column is weighted differently from a genuine one so it doesn't over-shrink.
<th> Partial same as <td> plus scope ("col"/"row"/"colgroup"/"rowgroup" — parsed but never read anywhere) font-weight:bold; text-align:center Real gap: scope is inert for accessibility tagging — PDF/UA picks TH vs TD purely from tag name, not scope.

Forms

Form controls and their rendering as static graphics — and the one open question about real interactive PDF form fields.

Tag Status Attributes CSS properties Comments
<form> Needs verification action, method (not read — plain block container, no submission) none special PD4ML.generateForms() (real AcroForm generation) has zero references anywhere under html.engine — wired only to the legacy v40 pipeline as far as source shows. For v42-rendered documents this flag may be a no-op; form controls paint as flat static graphics only. Flagged for independent live verification.
<label> Partial for (no association code found) cursor:default (inert in static PDF) Purely a visual container; click-association is moot without real interactivity.
<input> Full type: checkbox/radio (native 13×13 box, checkmark/dot only when checked), range (dedicated slider paint), color (swatch), image (real replaced element), submit/reset/button (grey chrome), file (dedicated control), hidden (display:none), password (masked); email/number/date/search/tel/url/week/month/time have no dedicated branch — fall back to plain type=text rendering, same as real browsers do for unsupported types; checked, disabled, value, placeholder (greyed when empty) all read; readonly/required only as CSS pseudo-classes; maxlength, name not read for rendering checkbox/radio/range/color/image intrinsic sizing overrides
<button> Partial type=submit|button|resetno functional difference (no real form submission in static PDF) grey button chrome, shared with input[type=submit/button/reset/file] Always renders its child content inside the button chrome regardless of type.
<select> Full multiple and size (genuinely switch dropdown vs. listbox rendering, default 4 rows if multiple); HTML5 "last <option selected> wins" enforced for non-multiple selects gray (not blue) row highlight in listbox mode — deliberate, matches unfocused-control rendering
<datalist> N/A <input list> association — no code found display:none Correctly invisible; inert as expected (no interactivity in static output), matching real browsers when JS-driven autocomplete isn't relevant.
<optgroup> Full label display:block; font-weight:bold Rendered as a bold row header inside the listbox/dropdown.
<option> Partial selected (last-wins rule); value (not used for visual rendering, only text content shown); disabled (no per-option greyed rendering found) display:block
<textarea> Full rows/cols (both directly size the box); placeholder; HTML5 leading-LF-after-opening-tag correctly stripped white-space:pre-wrap; font-family:monospace; padding:2px Word-wraps content at box width; wrap granularity approximate vs. Chrome's char-count algorithm but functionally correct.
<output> Full none special none special Renders as an ordinary inline element showing its text content — correct, real browsers give <output> no special rendering either.
<progress> Full value/max (genuinely drive fill-bar ratio); no value → fixed indeterminate segment display:inline-block; height:8px, 160px width Fill color sampled directly from Chrome per code comment.
<meter> Partial value/min/max (drive fill ratio); low, high, optimum (not read — fill is a fixed green regardless of zone) same box model as progress, 80px width Real browsers vary meter color by low/high/optimum zone; this engine does not.
<fieldset> Full none special margin:0 2px; padding:.35em .75em .625em; border:2px groove #c0c0c0 Legend-centered-on-border + border-notch built from scratch, for every border style (not just solid). Known limitation noted in source: a float inside the legend, or a child laid out before the legend, isn't reserved for.
<legend> Full none special display:block; padding:0 2px Sized to its own text width, straddles the border midline — the "engraved" look.
<keygen> N/A obsolete, no crash none special Removed from the HTML5 spec in real browsers too — correctly a no-op void element.

Interactive & scripting elements

Disclosure widgets, dialogs, and everything that depends on script execution or Shadow DOM — neither of which exists in this engine.

Tag Status Attributes CSS properties Comments
<details> Full open (boolean, genuinely functional) display:block Closed state is real element-specific logic (not a CSS class): every child but the first <summary> is skipped outright during tree construction when open is absent. Static conversion only — no interactive toggle in PDF output, fixed at render time.
<summary> Full none tag-specific display:list-item + list-style-type:disclosure-open|disclosure-closed + list-style-position:inside, applied only to the first <summary> child Marker glyphs are real Unicode triangles (U+25BC open, U+25BA closed — substituted for U+25B6 which is missing from common Windows fonts). Documented bug fix: a block-level first child (e.g. <summary><p>) now correctly reserves a line height for the marker instead of the triangle overlapping the child's first character.
<dialog> Partial opencomplete no-op display:block, no special rule Real divergence from spec: unlike real browsers' dialog:not([open]){display:none}, content renders identically with or without open. No modal top-layer/backdrop/auto-centering either — correctly and deliberately absent since that has no equivalent in static PDF output.
<script> N/A by design src, type, async, defer — all inert display:none No scripting engine exists anywhere in the codebase — content is tokenized as HTML5 raw text (so embedded JS syntax can't confuse the parser) then hidden, never executed. Any content a client-side script would inject is invisible to PD4ML.
<noscript> Full none display:inline The spec-correct "scripting disabled" branch — since PD4ML never executes scripts, this is the only behavior that makes sense, and it's what real browsers with JS off do too.
<template> Partial none tag-specific display:none No dedicated inert-DocumentFragment representation — falls through the ordinary display:none child-skip branch. Functionally equivalent to "not part of the rendered tree" for a non-interactive renderer, just implemented generically rather than as a special fragment type.
<slot> N/A name — inert none (generic default) No Shadow DOM support of any kind exists — treated exactly like any unknown tag, light-DOM children just render in place with no slot-projection semantics.

Obsolete & deprecated elements

Legacy HTML tags no longer part of the living standard — kept here because real-world documents (especially generated by old tools or Word) still contain plenty of them.

Tag Status Attributes CSS properties Comments
<center> Full none text-align:-webkit-center — a proprietary keyword implemented specifically so <center> also centers a normal-flow block child with its own definite width, not just inline content Matches real Chrome/Safari behavior, including the non-obvious block-centering quirk, rather than the CSS-spec-only text-align:center which would leave a block child flush left.
<dir> Partial type (not mapped to list-style-type the way it is for ol/ul/li — PresentationalHints only checks tag ol/ul/li) grouped with ul/menu: list-style-type:disc; padding-left:40px Rendered as a <ul> synonym for layout purposes, matching the spec's own "treat as ul" guidance — only its own rarely-used type attribute is left untranslated.
<font> Full color, face, size (1–7 legacy scale → 10/13/16/18/24/32/48px, base=3, +N/-N relative forms supported) maps to color/font-family/font-size Fully implemented legacy-attribute-to-CSS translation.
<basefont> Partial color, size (same 1–7 mapping as <font>); face not read for basefont specifically display:none — so the color/size mapping has no visible effect anyway Real legacy semantics (setting a default for following sibling content) not replicated, but moot since the element is hidden either way.
<big> Full none font-size:larger Paired UA rule with <small>.
<tt> Full none font-family:monospace
<strike> Full none text-decoration:line-through Shares its rule with <s>/<del>.
<acronym> Full title [title]{text-decoration:dotted underline} Treated identically to <abbr> — correct parity with its historical merge into abbr's role.
<nobr> Full none white-space:nowrap Also gets real HTML5 "active formatting element" parsing semantics (auto-close-on-reopen), grouped with b/big/code/em/font/i/s/small/strike/strong/tt/u.
<xmp> Full none font-family:monospace; white-space:pre Correctly given HTML5's RAWTEXT tokenizer treatment — nested tags inside are literal text, not parsed as markup, matching the real spec/legacy-browser behavior.
<listing> Full none shares the pre/xmp/plaintext monospace/pre rule Deliberately NOT given raw-text treatment — and that's spec-correct: per the real WHATWG tokenizer, listing is not a RAWTEXT-state element (only script/style/xmp/iframe/noembed/noframes are). Easy to assume it behaves like xmp; it doesn't, in real browsers either. (The shared "strip one leading newline" rule isn't implemented for it, same gap as <pre>.)
<plaintext> Real gap none shares the same monospace/pre rule Genuine spec-compliance gap: HTML5 requires <plaintext> to permanently switch the tokenizer into a raw state for the rest of the document (no more tags recognized at all, ever, until EOF). This engine has no such state — content after <plaintext> continues to be parsed as ordinary markup, a real behavioral difference from every browser's (admittedly bizarre) handling of this tag.
<applet> N/A code, archive, width, height — all inert no UA rule at all — plain inline, not even boxed as a replaced element No Java-applet execution of any kind, confirmed absent (PD4ML being JVM-based does not imply an embedded applet runtime). Fallback content inside renders as plain inline text.
<bgsound> N/A src, loop — inert display:none Correctly hidden; no audio playback attempted (impossible in PDF output anyway).
<blink> N/A none no UA rule; unknown-element generic inline default Text content still shows, just no blink effect — expected/acceptable for a static PDF target, and already dropped from all real browsers.
<marquee> N/A by design behavior, direction, scrollamount — all inert display:block No scrolling/animation logic of any kind — renders as ordinary static block content, correct and deliberate for static PDF output, not a bug.
<frame> N/A src, name, noresize — all inert display:block No cross-document/navigation handling — renders as an empty block, no content loaded from src. Frame navigation has no single-document PDF equivalent, correctly not attempted.
<frameset> N/A rows, cols — inert display:block No special composition logic — just stacks its (empty) <frame> children as ordinary blocks.
<noframes> Full none display:none Correctly hidden, mirroring a frame-capable browser's treatment.
<noembed> Partial none no UA rule — missing from the display:none list that covers its rawtext siblings (noframes, basefont, bgsound, etc.) Minor inconsistency: given true raw-text tokenizer treatment (like script/style/xmp), but since nothing hides it, its literal text content renders visibly by default.
<menuitem> N/A inert no UA rule; unknown-element default Not referenced anywhere — consistent with real modern browsers, which also dropped this abandoned proposal.
<content> N/A select — inert none (unknown element default) Shadow DOM v0 tag; no shadow DOM support exists at all (see <slot>) — falls through as a plain unknown element, matching modern browsers.
<shadow> N/A none none (unknown element default) Shadow DOM v0's deprecated insertion-point tag, removed even earlier than <slot>/<content> — correctly falls through as unknown, matching every real modern browser.
<rb> <rtc> N/A none none (unknown element default) Not in the parser's known-element list — falls through as plain unknown inline elements, matching real browsers since both were formally dropped from the Ruby markup spec in 2021.