OfficeIMO.Html
3.5.2
Prefix Reserved
dotnet add package OfficeIMO.Html --version 3.5.2
NuGet\Install-Package OfficeIMO.Html -Version 3.5.2
<PackageReference Include="OfficeIMO.Html" Version="3.5.2" />
<PackageVersion Include="OfficeIMO.Html" Version="3.5.2" />
<PackageReference Include="OfficeIMO.Html" />
paket add OfficeIMO.Html --version 3.5.2
#r "nuget: OfficeIMO.Html, 3.5.2"
#:package OfficeIMO.Html@3.5.2
#addin nuget:?package=OfficeIMO.Html&version=3.5.2
#tool nuget:?package=OfficeIMO.Html&version=3.5.2
OfficeIMO.Html
OfficeIMO.Html contains the shared HTML parser, resource policy, layout scene, and direct PNG/JPEG/TIFF/SVG/WebP rendering APIs used by OfficeIMO converters.
It owns the reusable parts that should behave consistently across HTML-to-Markdown, HTML-to-Office, image, and PDF workflows:
- trust-aware parsing profiles and shared source, DOM, CSS, selector, responsive-image, and semantic-metadata limits
- shared HTML, CSS, and data-URI charset handling, including legacy web encodings
- URL policy evaluation and base URI resolution
- owned document snapshots, node queries and edits, with replaceable parser and charset providers
- DOM traversal facts and node/depth limit tracking
- image source discovery and deterministic responsive candidate selection for
img, lazy-loading attributes,srcset,sizes, andpicture/source - image data URI parsing and media-type extension mapping
- deterministic accessible-name, ARIA heading, EPUB structural-semantic, and logical quote/code/footnote projection
- browser-free HTML layout for continuous and paged output
- structured Presentation MathML routed through the shared OfficeIMO.Core expression and vector-rendering model
- bounded CSS length math, caller stylesheets, deterministic media preferences, running strings and elements, and Unicode-range-aware font fallback packs
- first-party TrueType/WOFF 1, .NET 8+ single-face WOFF 2, CFF/CFF2, and variable-font programs, plus an optional complete OpenType shaping provider
- direct PNG, JPEG, TIFF, SVG, and lossless WebP export over
OfficeIMO.Drawing - one typed semantic document projection shared by Excel, PowerPoint, and OneNote importers
- executable target capability contracts, preflight analysis, and source-to-target diagnostic provenance
- one operation-scoped resource session for policy, resolution, MIME checks, caching, deduplication, budgets, timeouts, and digests
- fidelity scoring across structure, text, styles, resources, annotations, formulas, charts, geometry, and reopened native artifacts
Markdown, Word, Excel, PowerPoint, RTF, Email, MHTML, and PDF models remain in their owning packages. Those projections are explicit: for example, HTML becomes a WordDocument through OfficeIMO.Word.Html and a MarkdownDoc through OfficeIMO.Markdown.Html.
To save a source HTML copy in another directory while retaining its relative resource paths:
HtmlConversionDocument report = HtmlConversionDocument.Load("reports/service-review.html");
File.WriteAllText("exports/service-review.html", report.ExportSourceHtml());
ExportSourceHtml() records the original effective base URI in the document. It preserves source markup; referenced files remain at their original locations. Use SourceHtml for the exact original text or HtmlForConversion for policy-normalized conversion HTML.
Load a ZIP site bundle
HtmlSiteBundle loads an HTML page and its archived stylesheets, fonts and images
without extracting files or granting network access. Root index.html takes
precedence over index.htm; otherwise a single HTML entry is selected. Specify
EntryPath when the archive contains several possible pages.
using OfficeIMO.Html;
using Stream source = File.OpenRead("saved-site.zip");
HtmlSiteBundle bundle = await HtmlSiteBundle.LoadAsync(source,
new HtmlSiteBundleOptions { EntryPath = "articles/report.html" });
HtmlRenderRequest request = bundle.CreateRenderRequest(HtmlRenderRequest.Create(
HtmlRenderIntentProfile.PrintPaged, HtmlRenderEncoder.Svg));
HtmlRenderResult rendered = await HtmlRenderEngine.ExecuteAsync(bundle.HtmlDocument, request);
rendered.RequireNoLoss();
int pageNumber = 1;
foreach (var page in rendered.ExportImages()) {
File.WriteAllBytes($"report-{pageNumber++:D3}.svg", page.Bytes);
}
The loader supports stored and Deflate ZIP entries. It checks encoded size, entry count,
actual decoded entry and total sizes, compression ratios and ZIP checksums. It normalizes
leading ./ and backslashes, and rejects traversal, duplicate normalized names and
non-regular entries. Caller streams remain open; seekable streams retain
their original position. HTML parser limits and cancellation also apply.
ArchiveBaseUri assigns a virtual HTTP(S) directory to the archive. It changes
relative URL resolution, not resource permissions. Archived resources are served
from snapshots. An explicitly supplied render resolver remains the fallback;
missing resources produce the existing conversion diagnostics. Resource requests
still use the renderer's URL, byte, count and timeout limits.
For PDF output use the HTML site-bundle conversion API, which also enforces the PDF embedded-package resource policy. MHTML uses the separate OfficeIMO.Mhtml MIME reader and CID resolver.
Inspect and edit owned HTML
using OfficeIMO.Html;
using OfficeIMO.Html.Dom;
using OfficeIMO.Markdown.Html;
HtmlDocument source = HtmlDocumentEngine.Default.ParseDocument(
"<table><tbody><tr id='items'><th>Item</th></tr></tbody></table>");
HtmlElement row = source.QuerySelector("#items")!;
HtmlDocumentFragment cells = HtmlDocumentEngine.Default.ParseFragment(
"<td>Quarterly report</td><td>Approved</td>", row);
HtmlDocument edited = source.Edit(document => {
HtmlElement targetRow = document.QuerySelector("#items")!;
targetRow.AppendChild(document.ImportNode(cells));
});
HtmlConversionDocument conversion = HtmlConversionDocument.FromDocument(edited);
string markdown = conversion.ToMarkdown();
byte[] preview = conversion.ToPng();
HtmlDocumentEngine is the provider-neutral document entry point. The default engine
uses the packaged AngleSharp provider, while its constructor accepts any
IHtmlParserProvider. Full documents and contextual fragments are immutable owned
snapshots. Fragment parsing uses the supplied element and ancestor context, including
table insertion modes, foreign namespaces and ancestor forms. Import a returned
fragment into a mutable destination before insertion; appending it splices its children.
HtmlConversionDocument.Document is also an immutable source snapshot. Edit clones it and freezes the result;
the original document, retained node handles and cached conversion results remain
unchanged. Clone returns a mutable tree for a single owner, while
HtmlConversionDocument.FromDocument captures the attached tree, including template
contents, as an immutable conversion snapshot.
CreateDocumentForConversion returns a mutable, policy-normalized owned tree.
Use NodeId within an edit lineage and SnapshotId to distinguish tree instances.
General-purpose HtmlDocument.Clone retains detached nodes and original source
offsets. Conversion capture and conversion edits omit detached editing history;
attached nodes retain their IDs and source offsets. Edited HTML is serialized
from the tree; it does not preserve the original spelling of entities or whitespace
inside tags. Template contents are exposed separately through TemplateContent.
The lightweight contracts live in OfficeIMO.Html.Core, which has no parser,
graphics, font or browser dependency. OfficeIMO.Html.AngleSharp supplies the
current parser, selectors, serializer and web charset labels. Applications needing
only HTML inspection can use those two packages. The conversion/rendering package
still uses AngleSharp and AngleSharp.Css internally; selecting another parser does
not remove those runtime dependencies.
Set HtmlConversionDocumentOptions.ParserProvider for an alternative inert parser
and InputEncodingProvider for source-byte charset resolution. Explicit Encoding
arguments on Load override sniffing. Resource decoding is configured separately:
HtmlResourcePipeline.TryDecodeStylesheet and HtmlDataUri.DecodeText accept a charset
provider. The default provider retains legacy code-page support and its existing
process-wide .NET code-page registration. HarfBuzz remains an optional typography
provider through OfficeIMO.Drawing.HarfBuzz.
The current structural adapter retains a native tree alongside an owned tree when
owned nodes are requested. Conversion-only parsing keeps the owned projection lazy.
Source length is checked before parsing; node/depth limits, including template
contents, are checked after the native parser constructs its tree. For owned input,
MaxInputCharacters also bounds aggregate attached names, attribute values, text,
comments and doctype identifiers before copying or native projection. Canonical
source serialization stops when its expanded output exceeds that limit. These are
separate checks: an owned tree can contain data that HTML serialization omits, such
as children of void elements. Cancellation is cooperative, not a hard worker
memory or execution-time limit. Context reconstruction needed by the retained provider
is isolated inside OfficeIMO.Html.AngleSharp; consumers retain the same owned API when
the provider changes. Provider-independent CSS execution is being adopted in qualified
vertical slices while the retained CSS provider covers the remaining grammar.
The owned property grammar covers CSS-wide keywords and selected display, visibility,
opacity, color, physical width and height constraints, and physical margin and padding
longhands. It represents constant number/percentage calculations, contextual length-percentage
expressions, and legacy or modern sRGB, HSL, and HWB functions as typed values. Computed
opacity is converted to a clamped number, while functional colors use the shared OfficeColor
conversion. Width and spacing percentages remain typed at computed-value time and resolve
against the layout reference at used-value time. Inline declarations enter the managed
cascade through the lossless owned style-block parser.
Qualified rules whose declarations stay inside that property slice retain their original
OfficeIMO syntax nodes and selector AST through the cascade, including nested qualified rules
inside style rules and supported @media, @supports, @layer, and @container groups.
Direct declaration runs preserve their authored position around nested rules. The owned matcher
handles atomic selector lists, stylesheet namespace bindings, type, universal, id, class,
and attribute selectors, the four structural combinators, selected child/of-type and An+B
pseudo-classes, a single-range :lang(), and :is(), :where(), and :not(). Grouped rules use the owned path only
when every selector and declaration is qualified, so a partially understood list cannot
silently change which elements match. For a namespace-qualified selector that also needs a
wider pseudo-class, the owned matcher retains the stylesheet namespace and combinator envelope
while the provider evaluates that pseudo-class against the current element. :is() and :where()
use forgiving lists, while :not() stays strict. :empty follows deployed browser behavior:
whitespace text makes an element non-empty and comments do not.
ID and class selectors use ASCII-insensitive matching in quirks documents and
case-sensitive matching in standards and limited-quirks documents. Attribute
selectors keep their own case rules. :lang() uses element and ancestor language
declarations, gives xml:lang precedence over lang, and stops inheritance at an
explicit empty language. A range matches the same language or a hyphenated subtag.
AngleSharp.Css remains in the default package for wider property grammars, dynamic and
relational pseudo-classes, filtered :nth-child(... of S), conditional-group evaluation,
pseudo-elements, unknown at-rules, and other fallback cases. Retained declarations can still use an owned
selector match, including namespace-qualified selectors. OfficeIMO keeps rule order, cascade
layers, computed-style projection, and fallback selection stable while the owned subset grows.
Declaration preservation uses parsed name spans, so declaration-like text inside
URLs or custom-property components stays intact. Provider fallback retains custom
property values, case-sensitive names and importance from the original rule.
Cascade explanations are opt-in so normal rendering does not retain candidate graphs for every element:
using OfficeIMO.Html.Css;
HtmlConversionDocument source = HtmlConversionDocument.Parse(
"<style>@layer theme { .status { color: blue; width:calc(24px + 25%) } }</style>" +
"<p class='status' style='color:lime'>Ready</p>");
var styles = HtmlComputedStyleEngine.Compute(source, new HtmlComputedStyleOptions {
IncludeCascadeTraces = true
});
HtmlCssCascadeTrace trace = styles[source.Document.QuerySelector(".status")!]
.GetCascadeTrace("color")!;
HtmlCssCascadeCandidate winner = trace.Candidates.Single(candidate =>
candidate.Decision == HtmlCssCascadeDecision.Selected);
HtmlComputedStyle statusStyle = styles[source.Document.QuerySelector(".status")!];
if (statusStyle.TryGetTypedValue("width", out HtmlCssPropertyValue? width)) {
HtmlCssLengthResolutionResult used = HtmlCssMathResolver.ResolveLength(
width.MathExpression!,
new HtmlCssLengthResolutionContext { PercentageReference = 640 });
}
The trace uses OfficeIMO types only. It reports computed value, inheritance/reset state,
source kind, selector, layer, specificity, importance, source order, winner decision, and
the owned grammar status of each retained candidate. IsEffective identifies the authored
declaration that won the local cascade. InvalidAtComputedValue identifies a failed custom-property
substitution whose result fell back to inheritance or the property's initial value. A retained provider may normalize a
stylesheet declaration before the cascade sees it; inspect HtmlCssStyleSheet when exact
authored spelling and source spans are required. Traces are currently available for the
properties in HtmlCssPropertyCatalog. Inline syntax parsing uses the conversion operation's
CSS byte, token, syntax-node, declaration, nesting, and resolved-selector expansion limits; the explicitly unbounded document overload does
not introduce the standalone CSS parser's default input ceiling.
See the migration guide for the replaced public DOM signatures.
Shared Office HTML document shell
Office adapters use OfficeHtmlDocumentShell and OfficeVisualThemeKind for consistent semantic, editable round-trip, positioned-review, and print-review output. The embedded stylesheet supplies explicit palettes, readable typography, responsive page regions, tables, forms, figures, code, adapter panels, and print rules without making each adapter maintain a separate CSS implementation.
using OfficeIMO.Drawing;
using OfficeIMO.Html;
string review = OfficeHtmlDocumentShell.WrapBody(
"<main class=\"officeimo-document\"><h1>Review</h1></main>",
new OfficeHtmlDocumentOptions {
EmitDocumentShell = true,
Title = "Conversion review",
Language = "en-GB",
Theme = OfficeVisualThemeKind.Report,
IncludeDefaultStyles = true,
BodyClass = "customer-review",
NewLine = "\n"
});
Set EmitDocumentShell = false to return a fragment. Adapter save options expose this object through DocumentOutput; their older title, language, theme, style, fragment, and newline properties remain synchronized aliases. Adapter-required body classes are retained and BodyClass values are appended with stable de-duplication. The shell is presentation only. Parsing, resource policy, layout interpretation, conversion diagnostics, and static execution boundaries remain owned by the managed HTML engine and the destination adapter.
HtmlTargetCapabilityContracts describes conversion routes directionally. HtmlToTarget and TargetToHtml have independent entry points, result contracts, I/O boundaries, diagnostics, profiles, and feature classifications; a missing reverse route is represented by TargetToHtml == null. Catalog collections and finalized gallery or conversion results are defensive snapshots; mutable reports remain available only while callers or converters assemble a result.
Responsive image selection
Use the DOM-independent selector when a crawler, resource broker, or another host needs the same candidate decision as the renderer:
HtmlResponsiveImageSelection selected = HtmlResponsiveImageSelector.Select(
"small.webp 400w, medium.webp 800w, large.webp 1200w",
"(max-width: 600px) 100vw, 50vw",
defaultSource: "fallback.webp",
new HtmlResponsiveImageSelectionOptions {
ViewportWidth = 800,
ViewportHeight = 600,
DevicePixelRatio = 2
});
string selectedUrl = selected.Candidate.Url; // medium.webp
The selector supports density descriptors and width descriptors normalized by a
bounded sizes list. MaxSizesCharacters bounds direct selector calls, while
HtmlConversionLimits.MaxResponsiveImageSizesCharacters applies the shared conversion
boundary. It evaluates supported media conditions through the shared CSS
media engine, resolves supported CSS lengths and math, keeps the first duplicate
density, reports whether a default src supplied the selected candidate, and falls back
to 100vw when no supported size matches. Resource policy is applied before candidate
selection. Static rendering derives device density from
HtmlRenderMediaFeatures.ResolutionDpi.
Density descriptors must be positive finite numbers, such as 1.5x, .5x or
1e2x. A leading +, a trailing decimal point, zero, negative values and nonfinite
values are invalid. Candidates with invalid descriptors are discarded before
responsive selection.
Direct HTML rendering
using OfficeIMO.Drawing;
using OfficeIMO.Html;
string html = "<h1>Status</h1><p>Generated by OfficeIMO.</p>";
HtmlConversionDocument source = HtmlConversionDocument.Parse(html);
var options = new HtmlRenderOptions {
ViewportWidth = 720,
Margins = HtmlRenderMargins.All(24),
Scale = 1.5,
MediaFeatures = new HtmlRenderMediaFeatures {
PreferredColorScheme = HtmlPreferredColorScheme.Light,
ReducedMotion = HtmlReducedMotionPreference.Reduce
}
};
options.AdditionalStylesheets.Add("body { color: hsl(215 35% 20%); }");
byte[] png = source.ToPng(options);
byte[] jpeg = source.ToJpeg(options);
byte[] tiff = source.ToTiff(options);
string svg = source.ToSvg(options);
byte[] webp = source.ToWebp(options);
OfficeImageExportResult pngSave = source.SaveAsPng("status.png", options);
IReadOnlyList<OfficeImageExportResult> webpPages = source
.ToImages(options)
.Paged()
.AsWebp()
.Save("status-pages");
The default style mode keeps OfficeIMO's established document layout: an uninset body and Arial fallback. Select the bounded browser user-agent defaults when a screen or application capture should begin with the conventional eight-pixel body margin and generic serif family:
var browserOptions = new HtmlRenderOptions {
ViewportWidth = 816,
Margins = HtmlRenderMargins.All(0)
};
browserOptions.UseBrowserUserAgentStyles();
Authored CSS such as body { margin: 0 } still overrides that margin. The
browser mode is a versioned subset of common user-agent defaults; it does not
claim a complete Chromium stylesheet or cross-platform system-font identity.
Set DefaultFontFamily after calling the helper when the application supplies
or requires a particular font family.
Browser mode gives pre, code, kbd and samp a generic monospace family
before their children inherit styles. Its fixed medium size is 13 CSS pixels;
DefaultFontSize sets the separate standard medium size. Authored absolute
sizes remain absolute: code inside a 20px parent stays at 20px. Relative sizes
retain their origin, so code inside a parent sized at 1.25em uses 16.25px with
the default settings. Root-relative dimensions and container queries use the
same resolved sizes. Ruby annotation sizing honors authored font settings, and
nested inline text inherits the reduced size. Font selection and fallback still
follow the resource policy.
Unavailable @font-face declarations remain in the diagnostic report. They
count as font approximation when rendered text requests the unavailable face;
unused declarations and fallback faces that are never reached are informational.
This attribution uses the original family, weight, style, stretch and Unicode
coverage request before fallback. Resource-policy failures and execution limits
retain their own diagnostics.
Use a named render request when CSS media, viewport behavior, pagination, page selection, and output format must be independently reviewable. The request takes an immutable options snapshot. The retained result records the exact profile, surfaces, source offsets, clipping, requested scale and background, declared providers, and loss diagnostics before an encoder consumes it.
var request = HtmlRenderRequest.Create(
HtmlRenderIntentProfile.ScreenSnapshotPaged,
HtmlRenderEncoder.Png,
new HtmlRenderOptions {
ViewportWidth = 816,
PageSize = OfficePageSizes.A4,
Scale = 1.5
},
HtmlRenderDocumentState.EditedSnapshot)
.WithPageSet(HtmlRenderPageSet.Pages(firstPageIndex: 0, pageCount: 2));
HtmlRenderResult retained = HtmlRenderEngine.Execute(source, request);
IReadOnlyList<OfficeImageExportResult> pages = retained.ExportImages();
HtmlRenderSurface firstSurface = retained.GetSurface(0);
OfficeDrawing preview = firstSurface.CreateDrawing();
HtmlRenderHitTestReport hits = firstSurface.HitTest(120, 80, new HtmlRenderHitTestOptions {
InteractiveOnly = true,
MaximumResults = 8
});
firstSurface.TryMapToSource(120, 80, out HtmlRenderSourcePoint? sourcePoint);
HtmlRenderArchiveResult archive = retained.ExportArchive(new HtmlRenderArchiveOptions {
MaximumArchiveBytes = 128 * 1024 * 1024
});
File.WriteAllBytes("screen-pages.zip", archive.Bytes);
Default rendering and image export use paged print layout, including @page margin boxes. Paged PNG/JPEG/SVG output uses the generated PDF page scene and its embedded fonts. Use Mode = HtmlRenderMode.Continuous, .Continuous(), or ScreenFullPage explicitly for one long screenshot. Both modes use the same font fallback policy.
Named profiles are immutable defaults. Use WithCssMedia(...),
WithLayoutSurface(...), and WithPagination(...) to form a coherent custom
combination; use WithLayout(...) or WithAxes(...) when two coupled geometry
axes must change atomically. MatchesNamedProfile becomes false and Coverage becomes
Unqualified when those effective axes no longer match the named profile.
The encoder and page-set admission rules still apply.
The built-in profiles are ScreenViewport, ScreenFullPage, PrintPaged,
ScreenMediaPaged, ScreenSnapshotPaged, and ContinuousVector.
ScreenMediaPaged applies screen CSS and performs paged reflow.
ScreenSnapshotPaged completes one continuous screen layout and slices it into
fixed page canvases, so it may split elements. PrintPaged applies print CSS and
normal fragmentation. Separate pages, one selected page, a range, and stitched
output are available now. SourcePlacements records every source page or slice
and its output offset in a stitched surface. Projection is cancellable and bounded
by MaxProjectedVisuals, MaxPageCount, MaxSurfaceWidth, and
MaxSurfaceHeight.
HtmlRenderResult.OutputSurfaces exposes immutable executable surface views for
preview drawings, output-to-source coordinate mapping, and bounded topmost-first
hit testing. Hit testing applies retained transforms and rectangle, rounded, and
path clips, and reports whether each result used transformed bounds or clip-aware
transformed bounds. It does not claim exact glyph, stroke, or arbitrary shape
paint containment.
ExportArchive() packages the already selected, ranged, separate, or stitched
PNG/SVG surfaces. The deterministic ZIP contains ordered pages/page-NNNN.*
entries plus manifest.json; the manifest records request axes and range values, qualification,
dimensions, encoded hashes, clipping, source placements, requested scale and
background, provider IDs, retained HTML diagnostics with source-to-target
provenance, and per-page scale, font, and codec diagnostics. Page encoding loss
participates in both the page and manifest HasLoss values. Container adapters
can attach their own evidence without mutating the retained result through
WithAdditionalDiagnostics(...). Image byte limits continue
to come from HtmlRenderOptions, while HtmlRenderArchiveOptions independently
bounds the final ZIP and manifest. Element-aware placement remains an explicit
unsupported boundary. Inspect HtmlRenderProfileContracts.All
or officeimo html capabilities --format json for current qualification and encoder
availability.
Set FidelityPolicy when diagnosed fallback is not acceptable. The renderer collects the complete report, then rejects any warning, error, approximation, omission, or failure instead of returning a silently simplified scene.
var strict = new HtmlRenderOptions {
ViewportWidth = 720,
FidelityPolicy = HtmlRenderFidelityPolicy.RequireNoLoss
};
OfficeImageExportResult image = source.ExportImage(OfficeImageExportFormat.Png, strict);
The static contract includes normal-flow, flex, grid with column and row subgrid, deterministic stacking, positioned clip rectangles, basic-shape clip-path, paged fragmentation, named pages, running strings and elements, SVG, tagged-PDF semantics, and CSS-controlled PDF bookmarks. Browser-only execution such as JavaScript, animation timelines, live scroll state, and interactive layout is not attempted. Unsupported values that reach the declared feature handlers produce stable diagnostics; selectors outside the bounded selector subset simply do not match. Inspect HtmlRenderCapabilityCatalog.All, HtmlRenderProfileContracts.All, or the generated support matrix for the exact declared subset.
At supported ordinary-flow sibling boundaries, authored page breaks and a named-page
change share one transition. A plain page break retains an accompanying left or
right requirement; when both sides specify a page side, the following child's
side takes precedence. The destination keeps its page name, including across a
column-flex gap. An empty page needed to reach the requested side counts toward
MaxPageCount.
In supported paged flows, an explicit page break or effective named-page change ends adjoining sibling-margin collapse. The incoming block retains its top margin, including when an ordinary wrapper propagates a descendant's break. Siblings and formatting contexts that ignore that page control keep their existing margin-collapse behavior.
Legacy clip: rect(top, right, bottom, left) clips the whole border box of an
absolute or fixed element, including its background, border and link area. Each
edge accepts a finite length or auto; comma-separated and historical
whitespace-separated rectangles are supported. Ancestor rectangles also clip fixed
descendants. Empty rectangles suppress paint and PDF link annotations while
preserving the source DOM, named destinations and heading navigation, including
when screen output is split into pages or stitched into one surface.
clip: auto leaves overflow visible; rect(auto, auto, auto, auto) clips at the
border box. Clipped form controls use the diagnosed static fallback because PDF
widgets cannot preserve that authored clipping; strict loss policy rejects it.
An unsupported applicable rectangle reports HtmlRenderClipValueUnsupported.
CSS transforms and individual scale apply to transformable boxes, including
inline-blocks, replaced content and inline elements blockified by floats, absolute
positioning, flex or grid layout. Ordinary non-replaced inline text,
display:contents, table columns and column groups keep their computed transform
declarations but ignore them for layout and paint.
A transformable box with a non-none CSS transform establishes a local padding-box containing block for absolute and fixed descendants. These fixed descendants follow that box through pagination; viewport-fixed boxes repeat on print pages. Heading destinations retain the coordinates produced by enclosing transforms.
Shrink-to-fit sizing for inline blocks, floats and absolute-positioned boxes measures styled child text, generated content and replaced images or SVG. Atomic child widths remain intact when adjacent labels or whitespace are normalized.
Inline SVG CSS font sizes use the surrounding HTML font context and the SVG
parent's presentation size when resolving relative units. CSS declarations,
including inherit, unset, and initial, take precedence over presentation
attributes. Unsupported SVG syntax remains visible in the conversion diagnostics.
Inline SVG without intrinsic dimensions uses its resolved painted object size as the
vector viewport, including object-fit sizing and cropping. The element's CSS
background and the SVG's supported strokes remain in the same retained scene
for screen, print, and screen-to-page output. The
HTML support matrix lists supported
SVG capabilities and known limits. Font and page defaults can change geometry
across these output intents.
When a caller supplies an SVG raster codec, inline SVG reaches that fallback only
if the shared SVG safety predicate accepts its authored dimensions and resource
work. Rejected inline content receives an omission diagnostic.
Iframe srcdoc content is laid out as an independent replaced viewport with the
browser default 300 by 150 CSS-pixel intrinsic size, overridden by CSS or width
and height attributes. The child uses the selected screen or print media context,
keeps its own base URI and styles, clips overflow at the iframe content box, and
retains searchable text in PDF output. MaxFrameDepth defaults to eight and may be
lowered for stricter workloads. Layout-operation and repeated-background tile limits
apply cumulatively to the root and all rendered frame viewports. Static rendering does not fetch an iframe src;
the runtime application workflow supplies captured same-origin frame bodies through
an isolated render clone.
CSS display: table, inline-table, table-row, table-cell, and table row groups use the same grid as native HTML tables. Adjacent cells in ordinary block flow receive anonymous table and row boxes; ordinary content inside rows receives anonymous cells. These boxes preserve the original DOM's selectors, inherited text styles and links, and fit beside neighboring floats. An inline-table remains an atomic box between surrounding text. CSS presentation alone does not give these boxes accessibility table roles; native elements and explicit ARIA roles retain their semantics.
In-flow ::before and ::after text on tables, rows, row groups, cells and captions participates in layout. Printed link destinations such as content: attr(href) retain their text and link actions. Generated blocks include their authored widths, padding, borders and margins.
Preformatted blocks preserve spaces and line breaks through nested styled text and generated content. Set white-space: normal when that text should use ordinary whitespace.
Paged tables use the same layout and retained scene for PDF, SVG, and raster output. Tables fragment at legal row boundaries unless whole-table break-inside:avoid is authored. Ordinary scroll containers with overflow:auto or scroll flow across pages at legal boundaries. Use break-inside:avoid to keep a panel together; authored clipping and bounded scroll snapshots still apply. The final repeated footer completes the table; a following authored page break, page-name change or page-side request does not generate another table continuation. Distinct empty successor boundaries remain separate.
Negative child margins retain their signed flow advance inside cells. Visible paint beyond the final row can continue through safe page cuts without enlarging that row. Ordinary horizontal cell content uses the final row or rowspan geometry for authored overflow clipping, while cell backgrounds, borders and outlines retain their own paint. Exact browser appearance for clipped cell fragments is not qualified.
With table-layout:fixed and a definite table width, absolute column and first-row cell widths remain minimums. With zero borders and spacing, two 80px columns expand a 100px table to 160px. Declared column widths take precedence over cell widths; percentage requests share the space remaining after absolute minimums. Inline placement, centering, clipping and page continuations use the resulting table width. Intrinsic measurement uses the same row order and border insets as painting, keeping following inline content outside the table's used box.
Auto layout considers styled cell text and generated content, block line boundaries, atomic inline boxes, replaced images, column spans, and fixed-width visible descendants without feeding percentage widths back into intrinsic track sizing. Auto columns retain unbreakable content minimums and distribute surplus in proportion to preferred content widths, with automatic, absolute and percentage width requests retaining their allocation priorities. Conflicting percentage requests fit within the used table width in source-column order while preserving content minimums. A percentage on a spanning cell retains existing column percentages and distributes only its remaining request, weighted by the other columns' preferred widths. Empty tracks share that request equally; internal spacing is counted once. Empty cells contribute their authored edges without an invented content width; a zero-padding empty column can have zero width. These rules also apply when a minimum width, caption or flex container determines the table width. A repeated col declaration supplies its width to each column; a spanning cell includes the spacing between its columns. Continuations retain the original table's column contributions when page height changes. Rowspans can continue at row boundaries and at safe content positions within a row. The shared paginator can consume available blank source space after cell content, while every overlapping cell can veto a cut. Ordinary rows that fit a fresh body slot prefer their existing row boundaries; oversized rows and rows crossed by a span expose safe interior intervals. Content-free rows retain their discrete boundaries. Text line carriers, atomic content, nested block keeps and paragraph widows/orphans protect unsafe cuts; authored cell, row and row-group keeps retain cohesive spans. Spanning fragments retain source text and structure identity. Cell content keeps its source alignment; fragment-specific middle/bottom realignment, transformed or vertical cell content, and nested table repetition across these cuts are not qualified. A width-changing continuation across a rowspan retains its source layout with HtmlRenderPagePseudoGeometryPending. break-inside: avoid on rows and row groups, break-before and break-after on rows, and aligned line breaks inside oversized multi-cell rows participate in pagination. thead/tfoot use their CSS table-group defaults; any row group can opt into or out of repetition with display: table-header-group, table-footer-group, or table-row-group. Only the first source group of each header/footer kind receives that placement and repetition behavior; subsequent groups retain ordinary row-group order. Repeated fragments retain the original table, row, and cell structure identity for tagged PDF. When an avoided or otherwise atomic row is taller than an empty page, the paginator makes bounded progress and reports HtmlRenderForcedFragment against the table source.
Column sets outside the ordinary auto-fill and terminal spanning-set subsets described below retain their source column arrangement across physical pages. Text and paragraph constraints survive page cuts, but per-page inter-column reflow is not qualified for those sets; content placement and page counts can differ from browser print output.
Generated content on table, row and row-group boxes is omitted with HtmlRenderTableValueUnsupported; cells and captions retain generated content. CSS-only column boxes, display: contents within a table boundary and orphan internal table boxes inside inline flow receive an approximation diagnostic. Additional captions receive an omission diagnostic. RequireNoLoss rejects these losses.
Floated tables retain row breaks and repetition metadata through anonymous, inline and list wrappers. In one horizontal nowrap flex row or one ordinary auto grid row, top-aligned, auto-height items paginate their tables independently. Each item reserves space for its own repeated header and footer; the shorter flow stops repeating when it ends, and following content stays after its final row. PDF, PNG and SVG consume the same paged scene.
This parallel subset requires constant page geometry and reserved body space. Nested parallel regions, wrapped/reversed or cross-aligned flex rows, multi-row/spanning grids, bounded heights, transformed/clipped items and internal forced page breaks retain their existing fragmentation limits. Changing page geometry retains source layout with HtmlRenderPagePseudoGeometryPending. Outside the subset, source groups may remain unrepeated. Detached table groups retain their source occurrences when repetition cannot preserve ancestor opacity, transforms or paint clipping. Fragmentation reports the same repetition-suppression diagnostics as shared-offset conflicts: HtmlRenderTableHeaderRepeatSuppressed or HtmlRenderTableFooterRepeatSuppressed. RequireNoLoss rejects those approximations.
Collapsed tables resolve competing cell, row, row-group, column, column-group and table edges before measurement. Cells use half of each winning border for intrinsic widths, heights, content placement and percentage bases; the table reserves the outside halves. Table padding is ignored in this model. Column width hints exclude column padding and borders, and row or column rules do not cross a spanning cell's interior. Repeated headers and footers reserve the outside half borders and paint shared rules over cell backgrounds.
Ordinary table continuations retain source cell insets when page height changes. Reusable headers retain their source border winners independently of the resumed body. At a legal row cut, the outgoing fragment clips a grid rule at its centerline; the next fragment retains the complete starting rule, including both components of a double border.
Plain opaque, auto-height table backgrounds and their own solid separate-border sides continue through unused space at safe row cuts; row-group, row and cell paint stays above the table color. See the paged table paint contract and its limits. Decorated or translucent fragment backgrounds, complex border junctions, three-dimensional shading and raster edge coverage can still differ from browser output. Replaced images and controls with an internal table display value use inline boxes inside anonymous cells, retaining their own borders and outlines.
Plain opaque, auto-height rectangular block backgrounds and solid side borders also continue through unused space at safe page and column cuts with box-decoration-break:slice. Opening and closing borders retain their source edges. This applies to static boxes without transforms, background images, shadows or clipping.
Authored table widths honor box-sizing and horizontal auto margins. Native HTML tables default to border-box sizing in both style modes; flex and grid allocations apply padding, borders and maximum widths once. Absolute table, row, and cell heights are minimums. Extra table height is distributed evenly among rows and retained when pagination reflows a continuation. Cell vertical-align: top, middle, and bottom uses the final row or rowspan height. Browser style mode supplies middle alignment inherited through row groups and rows; authored values and CSS-wide resets override those defaults. RTL tables place the first logical column on the right while preserving source text and tagged-PDF order. Authored zero padding overrides the cell defaults.
With a definite table height, percentage row and single-row cell heights allocate shares of the height available to rows after table padding, borders and spacing. The larger row or cell request applies, while content and absolute height minimums remain intact. Cell padding and borders fit inside the percentage share. Auto rows receive the remaining height; when every row has a specified share, the shares scale to fill the grid. For example, a 200px table with 25% and 75% rows allocates 50px and 150px. If the first row needs 80px for its content, the rows receive 80px and 120px. A table whose height resolves to auto keeps auto sizing. Width and height calculations mixing percentages with nonzero lengths on internal table boxes behave as auto; pure calculated percentages and calculations whose length terms cancel to zero retain their percentage shares. Percentage rowspans and percentage row shares whose sum exceeds the available grid use an approximation reported as HtmlRenderTableValueUnsupported; RequireNoLoss rejects that fallback.
Ordinary horizontal block and inline-block descendants in non-anonymous single-row cells resolve percentage height, min-height and max-height against the final cell content height when the table or cell has a definite height. Nested percentage-height chains, inline and display:contents wrappers, ordinary generated text boxes, CSS variables, calculated lengths and logical block-size aliases use the same basis. Non-replaced inline and display:contents wrappers preserve the containing-height basis during initial cell layout too, including image sizing against an absolute cell height. Their authored heights do not make an auto-height cell definite; an actual inline-block retains its independent height basis. Content and absolute minima are measured before this final sizing pass; padding and borders are deducted once. A height:100% status block therefore fills its final cell without expanding the row for the percentage alone. Consequential percentage content in rowspans, anonymous cells or specialized formatting contexts uses a source/property approximation reported as HtmlRenderTableValueUnsupported. Effective nonzero percentage row-group heights in a definite table receive the same diagnostic because group height allocation is not implemented. Auto or invalid values, internal-table calculations that compute to auto, and genuinely indefinite percentages retain auto sizing. RequireNoLoss rejects the diagnosed approximations. General browser-relative row compression and mixed-font baselines remain outside this qualified subset.
Continuous, ordinary horizontal column-fill:auto regions fill sequentially at the measured column width. An indefinite region uses the height of its longest authored forced run; without forced boundaries, its content stays in the first column. A maximum height can advance content into additional columns. Minimum height and content-box or border-box insets retain their normal sizing rules. Balanced filling keeps its separate content distribution.
A full-width column-span:all block separates column sets. Spanners can be direct children or descendants through ordinary block, inline and display:contents ancestors in the same formatting context. Source fragments keep the original selectors, inherited styles, generated content, links and semantic identities; slice decorations and navigation anchors occur at their owning edges. Independent formatting contexts and transformed containing blocks stop descendant extraction. Every set before a spanner balances, while the final set follows column-fill. Sets share the owner's declared or maximum content height: preceding sets and spanners consume that height before the final set is sized. Ordinary column forces and keeps apply within each set; an edge force next to a spanner does not invent an empty column. Leading, adjacent and trailing spanners add no empty-set height.
Ordinary source ancestors consume authored height, min-height, max-height and aspect-ratio once across their fragments, retaining the original percentage-height basis. Absolute descendants retain their containing block and appear once at their source-owned position. Ancestor opacity is composed over its source fragments; display:contents creates no opacity group. Native-browser paint can differ where ancestor opacity covers an extracted spanner and in column-rule extents at fragmented spanners.
In paged output, ordinary non-spanning auto-fill regions with visible overflow fill the available columns on each physical page. Layout uses the space remaining where the region starts, then fresh page bodies. Auto-height sets retain unused column height before following content; authored heights retain their blank tail. Ordinary flex and grid containers preserve the column items' measured allocation, including blank intervals after projected content. Percentage-height descendants retain the used flex/grid height basis. Paragraph constraints and atomic content can defer a complete set when neither partial column fits. Source text, links and destinations use the same paged scene for PDF and image export.
The ordinary final auto-fill set after spanners uses the same physical page bands, starting with the space left after the preceding sets and spanners. Eligible ordinary horizontal regions with auto or balanced filling use the shared page planner for a spanner's own page controls, fitting keeps, internal page breaks and natural paragraph fragmentation. At an ordinary sibling boundary before or after the column owner, authored page breaks, named-page changes and page-side requests share one transition. Distinct empty spanners retain their separate page transitions; adjacent before/after declarations at one source boundary share a transition. Terminal auto-fill columns start at the resulting physical page position, including space consumed by widows, orphans or forced breaks. Advancing into another column consumes the full available band before following content. A padded fixed-height owner retains its authored blank tail. Earlier sets retain their source balancing across physical page cuts.
At document entry, an empty leading spanner with ordinary page breaks before and after it does not add a page. A blank page between distinct empty boundaries does not borrow paint from a following spanner, including a collapsed table. The bounded page-control evidence records the qualified examples and remaining browser differences in page-side selection, forced or kept spanner placement, and screen-media table layout.
An authored height limits the final physical band. Additional columns overflow inline in that band, including when the owner occupies exactly one page. A maximum height constrains normal flow without discarding visible overflow paint. Following content retains its normal-flow position even when it overlaps that overflow. Visible overflow from finite-height ordinary blocks continues through the same column layout in paged, continuous and snapshot output without expanding their normal-flow advance. Ordinary column owners use the same finite-band and paint-extent rules; measured flex/grid allocations and reserved column notes or figures retain their separate continuation contracts.
In physical page bands, column rules extend through that band's allocated column height and appear between adjacent occupied columns. Extra inline columns in the final band do not add rules to earlier pages, and a single-column continuation has no rule.
Balanced spanning sets that overflow the requested columns across physical pages retain an approximation for overflowing paint and following flow. For example, a short maximum-height owner can finish in normal flow before its overflow finishes painting. This combination reports HtmlRenderMultiColumnValueUnsupported; RequireNoLoss rejects it.
Ordinary horizontal column content honors break-before:column and break-after:column at sibling boundaries, including propagation through ordinary decorated wrappers. A boundary authored on both sides advances once; distinct empty siblings retain distinct boundaries. A first-child before value or last-child after value alone does not add an empty column. Balanced filling respects forced runs even when they require more columns than requested.
avoid-column keeps fitting content together in columns; avoid-page does not impose a column keep, while avoid applies to both fragmentation types. Boundary keeps carry the preceding paragraph's final substantive fragment with the following content. An oversized column keep starts in a fresh column before relaxing to make progress. Forced column boundaries override keeps. Column break values outside a column context do not create page breaks or mask authored table-row page breaks.
Short fixed-height sets retain inline overflow columns; physical page bounds can clip that overflow. Changing page geometry or reserved body space, and vertical alignment that can move a region as its height changes, retain source layout with HtmlRenderPagePseudoGeometryPending. Authored page breaks inside ordinary column content, page controls on ineligible spanner hosts, block box-decoration-break:clone across column/page boundaries, and column-break constraints in specialized, nested-column or floating contexts retain an approximation reported as HtmlRenderMultiColumnValueUnsupported; RequireNoLoss rejects it. Full ancestor clip-path composition across extracted column/page fragments is unsupported: a clipped source ancestor retains its original flow with the same diagnostic and strict-loss rejection. Nested column regions, atomic or floating hosts, tall column notes and figures, and broader flex/grid intrinsic block sizing remain outside this qualification.
Horizontal, normal-flow block and inline-block boxes support min-content, max-content, fit-content and fit-content(<length>) for width, min-width and max-width, including logical inline-size aliases. Measurements preserve styled text, atomic inline content and nested ordinary-box constraints. A cyclic descendant percentage is indefinite during intrinsic measurement; definite minimum and maximum constraints still apply. Cyclic margin and padding percentages resolve against zero while retaining absolute terms, including negative margins. Keyword widths measure content-box edges regardless of box-sizing; the argument of fit-content() follows the authored box sizing. Minimum widths take precedence over conflicting maximum widths, and auto margins use the resolved width.
In ordinary horizontal flow, non-replaced inline and display:contents wrappers preserve the enclosing block's content-height basis. Their authored heights do not establish a new containing block. Percentage-height images use that basis during intrinsic measurement and final layout, so a shrink-to-fit wrapper and its following content agree with the image's used width. An actual block or inline-block, including a blockified flex/grid item, retains its own height basis; an indefinite height stays indefinite.
For ordinary horizontal text, missing CSS line height and line-height: normal use the selected face's ascent, descent and line gap. Mixed sizes and empty inline struts contribute to the same line box, including inside table cells. Authored numeric, length and percentage line heights keep their own CSS rules. Explicitly set DefaultLineHeight to retain a fixed fallback multiplier; leaving it unset uses font metrics when available and the 1.2 multiplier otherwise. Browser style mode gives tables no default outer margin; document style mode retains its spacing defaults.
Generated page-margin text uses the same leading and selected-face baseline rules. Margin declarations honor line-height, including the font shorthand's value and reset behavior. Wrapped headers and footers retain their complete scene text, align each measured line once, and keep glyph-paint frames independent of short or zero line advances. Reserved-height overflow and shared text-layout truncation produce omission diagnostics. Captured running elements retain their own styles.
Generated margin text inherits typography from its matching @page context, which inherits from html. Body styles do not supply that parent. Page and margin declarations cascade independently: a local margin declaration overrides an inherited value even when the parent used !important. Font family, size, weight, style, stretch, color and line height use the ordinary CSS owners, including resets, relative sizes, layers and custom properties. Inherited percentage and length line heights keep their computed length; unitless leading scales with the receiving font. rem refers to the document root. Omitted text alignment keeps the margin position's default; explicit inheritance selects the page alignment.
Horizontal top and bottom margin boxes support length and percentage values for content-box width, min-width and max-width, plus padding and rectangular solid borders. Automatic widths use intrinsic content; the centre box stays centred while edge boxes share space. Padding and borders contribute once to the outer box, and text and running elements use its inner content frame. An empty string still generates a box and retains its border; content:none removes it. Container units keep the configured print-paper fallback. Page counters and running strings resolve before sizing, and overflow retains typed diagnostics.
Intrinsic width keywords, authored heights and margins, box-sizing, side/corner geometry, vertical writing, backgrounds, border radii and other painted border styles remain outside this profile. The page-margin geometry qualification separates owned PDF/image agreement from same-font Edge observations. Edge differs when three boxes compete under min/max constraints and in percentage-padding text placement; those cases remain outside native agreement. Zero-height content is clipped with an omission diagnostic where Edge can still paint text.
Ordinary horizontal block flow retains signed top and bottom margins, including when a block's net advance is negative. Following content can move above that block's start while its visible paint retains its own clipping and pagination extent. Full-page image height includes retained visible overflow. With constant page geometry and reserved body space, visible overflow from ordinary fixed-height blocks continues across pages independently of following content. Effective maximum heights and aspect-ratio allocations use the same owner. Paragraph keeps, widows and orphans, collapsed margins, text and links retain their source ownership. Fragment gaps count toward the authored height. Eligible solid paragraph backgrounds fill the outgoing fragment to the page edge.
Nested ordinary blocks paginate their visible overflow independently while following siblings retain their normal-flow positions. Auto-height and transparent display:contents wrappers preserve that behavior. A fitting break-inside:avoid box moves as one unit. Authored break-before:avoid and break-after:avoid keep adjacent siblings together, including when the kept range begins partway through an ancestor. Descendants use the resulting physical page origin; authored collapsed margins remain separate from inserted page spacing.
Within this ordinary subset, internal break-before:page and break-after:page use the shared page planner. A before break moves content inside the box while following siblings retain the box's authored allocation. An after break also advances following flow to its realized page boundary, including through constrained ancestors and zero-height owners. Visible overflow remains intact when following content moves, including at the box's final after break.
A before and after declaration at the same sibling boundary advance once. At the start of a constrained source, adjacent empty blocks share one page advance before the first content. Distinct empty siblings after real content retain separate boundaries and can produce blank pages. A first-child before declaration alone does not add an empty page. The forced-break evidence records the qualified source and output boundaries.
Specialized formatting contexts, positioned or transformed sources, internal left/right or named-page transitions, forced fragments of unsplittable content, repeated groups and changing page bands retain their existing fragmentation limits. Leading page-side controls retain the outer paginator's initial-page policy; they do not establish browser-equivalent initial-page parity. Unqualified independent overflow pagination reports HtmlRenderConstrainedOverflowPaginationPending; RequireNoLoss rejects that approximation. Authored overflow:hidden and clip retain their clipping; hidden content does not create extra pages. Oversized clipped owners and exact browser appearance of clipped fragments remain outside this qualification.
Ordinary horizontal LTR inline margins, padding and borders participate in intrinsic contributions and line placement. Signed margins affect the advance without producing negative paint widths. Token fitting includes opening and closing edges; wrapping, emergency breaks, tabs and ellipsis use the same advances. With box-decoration-break:slice, only the first and last fragments consume the outer edges. With clone, each fragment consumes its own padding and borders. Empty decorated spans retain their box advances.
Ordinary words retain their text adjacency across inline style changes, including superscripts. A joined word moves together after preceding text, or overflows an empty line when normal wrapping supplies no break. Fitting includes empty inline box edges and available manual or automatic hyphenation prefixes, including the inserted hyphen glyph and applicable character and consecutive-line limits. Authored spaces, explicit breaks, preferred text breaks and emergency wrapping retain their respective policies. Float exclusion bands and ::first-line styling use the same word boundaries; their combined style placement remains outside the qualified profile. Repeated overflow-wrap and word-break declarations retain source order, importance and valid-value filtering.
Legacy HTML <nobr> keeps its inline content together, including superscripts and text with different fonts, and contributes the whole range to minimum-content width. A nested <wbr> supplies a break opportunity. Author white-space declarations can override these defaults; explicit inheritance and resets retain their CSS meaning. For new content, use CSS white-space: nowrap.
Horizontal lines containing ordinary same-face empty inline-blocks retain the surrounding font strut and the inline-block's bottom-edge baseline. Empty inline wrappers and nowrap scopes contribute their struts without creating content or a line on their own. The shared metrics apply before fitting around floats and placing following lines. Mixed-face, replaced-element, content-derived and vertical baselines retain separate qualification limits.
Backgrounds and borders on ordinary same-face horizontal LTR inline text and empty boxes follow the selected font box and its text or strut baseline, including lines shorter than the font size. A tall empty inline-block inside a span retains its own height without stretching the span's decoration to that height. Visible ancestor decoration remains when descendants hide their text or atomic content, and when a leader has no drawable width; each owner follows its own visibility. Generated leaders, mixed faces, bidi, vertical writing, displaced text and replaced elements retain their specialized paint routes and qualification limits. Font metrics and rasterizer edge coverage can differ from browser output.
Intrinsic heights, percentage fit-content() arguments, and widths on replaced, table, flex/grid, positioned, floated, pseudo, root, vertical, column or containment boxes remain outside this subset. Ordinary boxes with replaced elements, specialized formatting descendants, percentage inline insets or decorated RTL descendants retain the fallback. Applicable dimensions report HtmlRenderIntrinsicSizeUnsupported when they fall back to auto sizing or omit a minimum or maximum constraint. RequireNoLoss rejects that approximation. These declarations do not size ordinary non-replaced inline or display:contents boxes and do not report this loss. Intrinsic grid-track sizing has a separate supported contract. Broader inline font-box and atomic-baseline appearance requires separate qualification.
The body inherits the document element's computed typography and custom properties, including during page continuations. Authored body overrides retain their CSS meaning. Explicit body margins, padding, and borders participate in layout and painting. A body background propagated to the canvas is painted once; when the HTML element supplies the canvas background, the body retains its own background box. Overflow propagated from the body clips at the viewport; body-local clipping remains active when the HTML element owns viewport overflow.
Block elements inside inline wrappers, including maps and links, retain their block boxes. Surrounding inline text continues before and after the block, while borders, padding, adjoining margins, ancestor opacity, and explicit page breaks remain in the shared scene used by HTML and EPUB image exports.
Visibility follows the active CSS media and computed display. The hidden attribute supplies a display:none default that author CSS can override, including print rules that reveal report sections. Hidden inline breaks and table cells do not participate in layout. CSS initial, unset, inherit, and cascade reversion retain their distinct display behavior.
Text-decoration shorthands retain underline, overline and strike-through style and
color with explicit thickness, for example text-decoration: underline 0.05em dashed gray.
Thickness participates in shorthand resets, declaration order, explicit inheritance
and custom-property substitution. Ordinary horizontal text paints explicit thickness
and text-underline-offset with shared vector geometry; overline is also painted.
Same-size in-flow inline descendants and anonymous flex text retain the ancestor's
band and color. display:contents forwards ancestor bands without originating its
own, and ancestor decoration stops at absolute, fixed and floated descendants.
From-font metrics, specialized bidi/vertical/baseline contexts, underline/overline
ink skipping, special positioning, shadows, mixed-size or independently decorated
descendants, non-solid pattern geometry, and continuity across descendant inline
margins, borders and padding report HtmlRenderTextDecorationThicknessApproximated.
Specialized text retains automatic underline/strike paint and reports
HtmlRenderTextDecorationLineUnsupported when overline is omitted. Descendant
text-decoration:none preserves an ancestor band without adding an approximation.
In ordinary horizontal flow, ::first-letter selects its original in-flow letter
before suppressing text at font-size:0, including generated ::before text.
A font size that resolves above zero restores only the selected fragment; the
remaining zero-size text stays suppressed. Font and color properties not overridden
by the pseudo-element retain the selected descendant's values. Intrinsic min/max
sizing measures the same restored content used by the shared scene and PDF output.
Supported inline SVG font and paint presentation attributes participate in the CSS cascade before layout. A label's font-family, font-size and font-weight attributes can override inherited HTML fonts, while author CSS and inline declarations retain their cascade priority. Relative font weights resolve once before inheritance, and nested text adds a baseline shift only when that element declares one.
An authored <details> disclosure without open renders its first <summary> and hides its remaining content. Hidden disclosure content does not size table columns, flex/grid tracks or shrink-to-fit boxes, consume image resources, advance generated counters or footnote numbering, or contribute PDF bookmarks. Adding open includes the body; a closed outer disclosure also hides nested disclosures. For a complete report export, prepare script-free HTML with the intended disclosures explicitly open and all required sections and dataset rows materialized. The static renderer does not execute beforeprint handlers.
CSS corner radii scale proportionally to fit the used box before creating rounded shapes and clips. Fractional dimensions and narrow form-control tracks retain rounded geometry within the shared drawing bounds.
HTML <button> descendants retain their own fonts, visibility and block, flex or grid layout in static image and PDF output. Buttons with normal-flow child content center that content vertically when their height leaves spare space; authored flex and grid alignment controls those layouts. Automatic inline-block widths measure styled descendants, including their padding and borders, so larger child text reserves its own space. Hidden buttons follow the same display rules as other elements.
Superscript and subscript resolve their font size once in the shared layout scene,
including nested scripts. Authored font sizes remain effective. Font-relative
vertical-align lengths use the element's resolved font size; percentages use its
computed line height. Generated footnote calls default to 70% of the surrounding
font size before resolving these dependent values. Keyword baseline shifts use
bounded offsets; mixed-font line boxes and browser-relative baseline fidelity remain
limited.
Horizontal text-only lines combine each run's selected-face ascent and descent, half-leading and resolved vertical offset when advancing following content, including beside floats. Mixed sizes retain the paragraph paint anchor and lift it by any extra top extent. Font-metric rounding, keyword shifts, mixed faces and atomic baselines retain their browser-relative qualification limits.
The PDF adapter paints the scene's resolved size and vertical offset. Logical
replacement text owns its painted content once, so independent PDF text extraction
does not repeat the visible glyphs alongside their replacement. Page image exports
retain the same scene geometry and page count; font rasterization can differ between
viewers.
OfficeImageExportOptions.MaximumRasterPixels limits HTML raster export,
including intermediate effect surfaces. HtmlToPdfOptions.MaximumRasterPixels
also applies to managed raster fallback during PDF conversion. Encoded-byte
limits remain separate.
Raster decoding preserves encoded color channels and does not automatically apply embedded ICC or PNG gamma conversion. Normalize source colors explicitly when color-managed output is required.
The same managed path renders inline or block Presentation MathML as vector content. Fractions, roots, scripts, limits, fences, matrices, enclosures, and annotations retain logical text in the shared scene and searchable PDF output. Tagged PDF output retains a Formula container and its accessible description, including transformed and vertical equations. Unsupported structures use a diagnosed child-content fallback.
MathML roots default to font-family: math with regular weight and style, while
inheriting the surrounding font size. Supply a face named math, or a supported
mathematical family such as STIX Two Math, through HtmlRenderOptions.Fonts for
predictable output. When AllowSystemFontFallback is enabled, the renderer can
load supported installed mathematical TrueType or CFF faces within the existing
font-source, decoded-byte and cancellation limits. SVG foreign-object viewports share
the parent operation's resource-byte and resource-count budgets, including decoded
fonts, without invoking external resolvers. Installed families vary by host;
an unavailable face produces a diagnostic and follows the font fallback path.
HTML-to-PDF also applies HtmlToPdfOptions.ResourcePolicy: the balanced PDF policy
permits renderer-selected mathematical families while blocking document-named host
fonts. Portable deterministic policy disables installed-font discovery; explicitly
supplied mathematical faces remain available.
Authored CSS overrides the defaults. To retain surrounding typography, use
math { font-family: inherit; font-weight: inherit; font-style: inherit; }.
Single-letter identifiers use text-transform: math-auto unless overridden by
MathML or CSS. Scoped static math fonts supply MATH constants for fraction geometry,
right/left script placement and scale, limits and bars through the shared Core renderer.
The managed static font readers supply designed radical, fence and large-operator
variants, bounded connector assemblies, italic correction, per-corner script
kerning and accent attachment. Explicit stretchy="false" and largeop="false"
retain natural operators. Direct operators in ordinary rows use the shared
finite form/spacing dictionary. Supported form values are prefix, infix,
and postfix. Independent lspace/rspace sides accept nonnegative em, px,
%, and unitless zero.
For example, lspace="0" rspace="0.25em" changes the two sides independently;
percentages scale each dictionary side. HTML keeps authored pixels in CSS-pixel
scene units. Unsupported side syntax and detected authored spacing in unqualified
embellished contexts produce HtmlRenderMathMlContentUnsupported approximation diagnostics.
Missing or unusable font records use deterministic fallback geometry. Variable
MATH metrics, complete operator dictionaries, embellished contexts, complete
matrix/stack typesetting and the full MathML attribute/CSS grammar remain outside
this subset. See the
shared math contract for limits and
the caller's font-metric opt-out.
For documents that opt into hyphens:auto, the managed renderer selects embedded US English
(lang="en-US" or en) and reformed German (lang="de-DE", de, de-1996 or de-DE-1996)
patterns for each text run. Nested language attributes override the inherited language; an empty
or unsupported language produces no automatic breaks. Other regional English and German spelling
tags are unsupported. Pattern resources retain their source notices and use no external runtime.
Supply an application lexicon or callback to override the embedded patterns, including returning no breaks. The same immutable lexicon can be shared with the PDF text engine:
options.UseTextHyphenationLexicon(new OfficeTextHyphenationLexicon(new[] {
"ty-pog-ra-phy",
"de-ter-min-is-tic"
}));
The managed renderer also honors author soft hyphens and the bounded CSS controls hyphenate-character, hyphenate-limit-chars, hyphenate-limit-lines, hyphenate-limit-last: always, and hyphenate-limit-zone. Inserted hyphen glyphs do not replace the source word in logical text.
text-indent accepts positive and negative lengths, percentages, and supported
CSS length math. It affects the first formatted line, including wrapping beside
floats and right-to-left alignment. Inherited lengths retain the declaring
element's font context; percentages use the receiving block's inline size. Page
continuations do not restart the indent. Intrinsic widths include the first-line
indent once per paragraph, including table cells and captions. Percentage terms
contribute zero during intrinsic measurement; absolute terms in length math
remain. Nested blocks and atomic inline boxes measure their own paragraphs.
The hanging and each-line keywords
are not implemented and produce TextIndentValueUnsupported diagnostics.
Character-relative ch lengths use the rendered zero glyph's advance, including
scoped fonts and active OpenType features, in supported layout and paint values
and CSS length math. Letter and word spacing do not enlarge that measurement.
Inherited text spacing, explicit line heights, border spacing and text-shadow
offsets retain their computed lengths when a descendant changes font; unitless
line heights continue to scale with the descendant's font.
Horizontal block flow shares float exclusions across ordinary nested and sibling
blocks. Side-specific clear advances the following block; independent formatting
contexts fit beside a float or move below it when their width cannot fit. Block
backgrounds paint below floats, and normal text paints above them. Float paint
metadata survives page fragmentation without repeating its text label. A float can move whole to the next page; browser-style float splitting and placement beside adjacent tables are not qualified.
Dependency footprint
- External: AngleSharp and AngleSharp.Css for DOM and CSS parsing; System.Text.Encoding.CodePages for legacy web encodings.
- OfficeIMO:
OfficeIMO.Core,OfficeIMO.Html.Core,OfficeIMO.Html.AngleSharpandOfficeIMO.Pdf. Resource policy, layout, PDF generation, image replay and diagnostics are first-party.
See the complete OfficeIMO package map for related formats and conversion paths.
ToPng(), ToJpeg(), ToTiff(), ToSvg(), and ToWebp() return in-memory output. ExportImage() and ExportImages() return encoded output plus dimensions and diagnostics. Format-specific save methods and the shared ToImage() / ToImages() fluent builders write to files or caller-owned streams and return the same structured evidence.
HTML-to-PDF generation is included in OfficeIMO.Html. The public types retain the OfficeIMO.Html.Pdf namespace. HtmlToPdfOptions derives from HtmlRenderOptions, so the same configured instance drives PDF and all five image formats. See HTML to PDF and paged images for resource policies, fonts, paged-media semantics and complete examples.
using OfficeIMO.Html.Pdf;
var options = new HtmlToPdfOptions {
Margins = HtmlRenderMargins.All(32)
};
byte[] pdf = source.ToPdfBytes(options);
byte[] png = source.ToPng(options);
string svg = source.ToSvg(options);
Optional bridges
Install only the bridge required by the application:
OfficeIMO.Html.Rtffor semantic HTML/RTF conversion.OfficeIMO.Mhtmlfor MHT/MHTML archives and embedded MIME resources.OfficeIMO.Email.Imagefor email-body image rendering.OfficeIMO.Html.Pdffor PDF-to-HTML conversion.OfficeIMO.Mhtml.Pdffor MHTML/PDF conversion.
The public HTML/RTF and email-image namespaces remain familiar; the package references now describe the actual cross-format capability.
URL Policy
var policy = HtmlUrlPolicy.CreateWebOnlyProfile();
string href = HtmlUrlPolicyEvaluator.ResolveUrl(
"/docs/start.html",
new Uri("https://example.com/"),
policy);
Parsing And Base URIs
HtmlConversionDocument document = HtmlConversionDocument.Parse(
html,
new HtmlConversionDocumentOptions {
BaseUri = new Uri("https://example.com/articles/")
});
Uri? baseUri = document.BaseUri;
HtmlConversionDocument.Load and LoadAsync detect byte-order marks and HTML meta charset declarations. Pass the optional Encoding argument when transport metadata or application configuration is authoritative. CSS resources use their content-type charset, BOM, or @charset; textual data URIs use their declared charset and default to UTF-8.
Trust and conversion limits
var options = HtmlConversionDocumentOptions.CreateUntrustedProfile();
options.Limits.MaxInputCharacters = 2_000_000;
options.Limits.MaxHtmlNodes = 50_000;
options.Limits.MaxSelectorEvaluations = 1_000_000;
HtmlConversionDocument source = HtmlConversionDocument.Parse(html, options);
The untrusted profile is the default. It rejects local-file navigation, does not fetch external resources by itself, and applies one shared set of limits before adapters allocate native Office objects. Embedded data: resources remain available through the separate resource policy and are still subject to renderer or adapter byte budgets. Use CreateTrustedProfile() only when the caller controls the HTML and resource locations.
HtmlConversionLimits is the common source for parser and CSS complexity decisions. CSS byte volume, rules, declarations, inline lexical tokens, inline syntax nodes, nesting depth, selectors per rule, resolved selector characters, and selector evaluations have separate limits and stable diagnostics. Word forwards its compatibility limit properties to this object; Excel, PowerPoint, and OneNote use HtmlImportLimits for native artifact counts, image bytes, chart dimensions, table cells, and geometry. This keeps shared HTML decisions in OfficeIMO.Html while leaving format-specific constraints with the target model.
Shared Diagnostics And Gallery Contracts
Renderer diagnostics carry OfficeConversionLossKind independently of severity.
Unsupported transforms and failed image resources remain loss-bearing even when
reported at informational severity. Both FidelityPolicy.RequireNoLoss and image
export Policy.RequireNoLoss reject these cases. Harmless informational diagnostics
remain accepted.
Gallery JSON uses schema version 1.1. Artifact evidence records observed page
geometry, loss diagnostics, and executed checks when the producer supplies them;
it is null for descriptors without those observations. The expectations array
contains caller declarations, marked declared-not-executed, and is separate from
the artifact checks.
var report = new HtmlDiagnosticReport();
report.Add("OfficeIMO.Word.Html", "HtmlCommentSkipped", "Comment skipped");
var scenario = new HtmlCapabilityGalleryScenario(
"quarterly-report",
"Quarterly Report",
"Word HTML",
"HTML import, DOCX validation, and round-trip export proof");
HtmlDiagnosticReport and the capability-gallery contracts provide a common shape for HTML converters, PDF bridges, readers, tests, and documentation generators. Existing gallery producers can keep using HtmlCapabilityGalleryResult.AddArtifact and Diagnostics.Add while assembling a scenario. Constructing an HtmlCapabilityGalleryManifest takes a defensive, read-only snapshot; the sequence-based result constructor also creates a frozen snapshot directly.
Native adapters use HtmlConversionResult<TArtifact> when callers need conversion evidence. Each diagnostic has a stable code, severity, and LossKind (Approximation, Omission, or Failure). Convenience methods still return the native artifact directly; they throw HtmlConversionException when required semantic content is missing. Result methods retain the artifact and diagnostics so applications can decide how to handle the failure.
Conversion Document And Normalized HTML
var conversion = HtmlConversionDocumentBuilder.Build(html, new HtmlConversionDocumentOptions {
Profile = HtmlConversionProfile.Document,
Trust = HtmlInputTrust.Untrusted,
BaseUri = new Uri("https://example.com/reports/"),
UrlPolicy = HtmlUrlPolicy.CreateWebOnlyProfile()
});
string normalized = conversion.NormalizedHtml;
var resources = conversion.ResourcePlan.GetSummary(HtmlResourceKind.Image);
var styles = conversion.StyleSummary;
HtmlConversionDocument is the shared conversion contract for OfficeIMO HTML workflows. It parses once and retains one source DOM. Adapter DOMs, logical structure, computed styles, resources, and normalized output are created lazily when requested, then reused. This avoids paying for visual analysis during a semantic-only conversion and avoids retaining multiple eager document copies.
Target packages accept this shared document while keeping target-specific conversion in their owning packages. The prepared DOM can be sent to Word, Markdown, RTF, Excel, PowerPoint, OneNote, PDF, PNG, JPEG, TIFF, SVG, and WebP without inventing adapter-specific parsing rules. Excel and PowerPoint default to their versioned semantic envelopes for round trips and expose generic import mode for ordinary HTML. OneNote imports ordinary document sections directly.
Reuse the same document for analysis too: HtmlComputedStyleEngine.Compute(conversion) and HtmlRoundTripScorer.Compare(source, target) accept retained conversion documents. Their string overloads enter through the same bounded parser, so low-level helpers do not create competing trust or limit defaults.
One report, several output formats
Prepare the report once and reuse the same source document with the format adapters:
using OfficeIMO.Html;
var report = HtmlConversionDocument.Load("service-review.html");
File.WriteAllText("service-review-copy.html", report.SourceHtml);
See the owning packages for PDF export, editable Word output, and typed Excel tables. The HTML support matrix describes target coverage.
Run the complete service review example with --multi-format-report. Its HTML source includes grouped rows, totals, leading-zero references, dates, approval values, links, and a second table. Report content stays in ordinary HTML; the adapters own conversion behavior.
Use --report-source <path.html> to run another source through the same example. The output index links all exported files and every preview page, and records conversion notes. Saved PDF previews are labelled separately from editable Word and Excel layouts. The conversion consistency tool checks native exports with an independent PDF rasterizer, required content, and page geometry.
Semantic IR and target preflight
const string semanticHtml = """
<h1>Quarterly checklist</h1>
<ol start="3"><li>Publish report</li></ol>
<input name="owner" value="Finance">
""";
HtmlConversionDocument source = HtmlConversionDocument.Parse(semanticHtml);
HtmlSemanticDocument semantics = source.SemanticDocument;
HtmlConversionPreflight excel = source.AnalyzeFor(HtmlConversionTarget.Excel);
HtmlSemanticBlock list = semantics.Sections
.SelectMany(section => section.Blocks)
.First(block => block.List != null);
Console.WriteLine($"{list.List!.Kind}: start={list.List.Start}, reversed={list.List.IsReversed}");
HtmlSemanticFormControl control = semantics.Sections
.SelectMany(section => section.Blocks)
.First(block => block.FormControl != null)
.FormControl!;
foreach (string value in control.Values) Console.WriteLine(value);
foreach (HtmlFeaturePreflightResult feature in excel.Features) {
Console.WriteLine($"{feature.Feature}: {feature.Outcome} ({feature.OccurrenceCount})");
}
HtmlSemanticDocument is the single interpretation of sections, rich runs, nested lists, tables, links, forms, notes, resources, computed styles, and source locations. List state retains ordered, unordered, and definition kinds, effective start and reverse direction, and each item's effective or explicit ordinal. Form controls expose specification-normalized types, one or more selected values, checked/disabled/required/readonly state, and resolved form ownership. Generic Excel, PowerPoint, and OneNote importers consume this model instead of independently deciding what the same DOM means. AnalyzeFor(target) uses the executable target registry to report Supported, Approximated, or Omitted before artifact creation. Diagnostics carry source and target provenance so applications can map a warning back to both sides of a conversion.
The generated HTML support matrix is checked against those executable contracts in the test suite. Run Build/Export-HtmlSupportMatrix.ps1 -Check to verify it or omit -Check to regenerate it.
Applications can inspect the same versioned contract through HtmlRenderCapabilityCatalog.ProfileManifests and HtmlRenderCapabilityCatalog.All. A profile manifest pins its admitted providers, specifications, evidence, platforms, outputs, version, and promotion state. Each capability reports the stages where the claim applies, its exact feature subset, and separate coverage, handling, maturity, required or optional provider, specification, evidence, limitation, and diagnostic fields.
HtmlCapabilityProfileManifest profile = HtmlRenderCapabilityCatalog.GetProfile(
HtmlCapabilityProfileIds.StaticScreenV1);
HtmlRenderCapability grid = HtmlRenderCapabilityCatalog.Get("layout-grid");
HtmlCapabilityProfileBinding support = grid.GetProfileBinding(profile.Id);
Console.WriteLine($"{profile.Id} {profile.Version}: {profile.Promotion}");
Console.WriteLine($"{grid.Stages}: {support.Coverage}/{support.Handling}");
Console.WriteLine(string.Join(", ", support.ProviderIds));
Qualified describes the listed subset and stages; it does not mean an entire HTML or CSS specification. Fallback, Ignored, and Rejected are handling outcomes and carry stable diagnostics when content is changed or refused. HtmlRenderCapabilityCatalog.Validate() checks manifest references, ordering, promotion consistency, diagnostic coverage, and release evidence for stable-default bindings.
Resource sessions
var renderOptions = new HtmlRenderOptions {
ResourceResolver = async (request, cancellationToken) =>
await ResolveApprovedResourceAsync(request, cancellationToken)
};
HtmlResourceSession session = await HtmlResourceSession.ResolveAsync(
source.ResourceManifest,
renderOptions,
cancellationToken: cancellationToken);
foreach (HtmlResourceSessionEntry resource in session.Resources) {
Console.WriteLine($"{resource.CanonicalSource} {resource.ContentType} {resource.Sha256}");
}
The session owns one immutable policy and limit snapshot for the operation. It deduplicates canonical requests, validates MIME types, enforces request/count/per-resource/total-byte/import-depth budgets, and records accepted resource digests. Synchronous rendering uses the configured synchronous package resolver; application/network resolution remains an explicit asynchronous boundary.
The session checks its resource URL policy before invoking a resolver, even when a
manifest was planned under a more permissive policy. It also checks reported final
URIs before accepting content. URL transforms preserve the manifest's rewrite;
when the operation policy includes the planning transform, it resolves the original
input instead of transforming the planned URI again. Reusing the same transform
in intersected policies avoids duplicate URL rewrites. Resolvers must enforce that policy while following
redirects. ResourceTimeout cancels the resolver's token; cancellation is
cooperative, so a callback that ignores the token delays completion until it returns.
Content returned after the deadline is rejected. Use an isolated worker when a hard
termination boundary is required.
When an implicit section takes its title from a heading, section.TitleHeading
retains that heading's level, rich runs, style and source location. It remains
separate from section.Blocks, which contains the section body. If the heading
already belongs to the body, TitleHeading is null; read it from Blocks.
Semantic envelope v2 and fidelity scoring
Current OfficeIMO semantic exports identify schema 2 and public-safe restoration metadata. Public-safe envelopes can be imported from untrusted input. A target-specific envelope marked trusted-target restores private target metadata only when the prepared input is trusted; otherwise the adapter uses the shared generic semantic path and reports the boundary. Schema 1 remains readable.
HtmlRoundTripScore score = HtmlRoundTripScorer.Compare(sourceHtml, exportedHtml);
Console.WriteLine(score.Dimensions["structure"]);
Console.WriteLine(score.Dimensions["styles"]);
// After the caller saves, reopens, and exports a native artifact:
HtmlArtifactReloadEvidence reload = HtmlArtifactReloadEvidence.Succeeded("DOCX", reopenedDocument.ToHtml());
HtmlRoundTripScore verified = HtmlRoundTripScorer.Compare(sourceHtml, exportedHtml, reload);
Console.WriteLine(verified.Dimensions["artifact-reload"]);
Version 2 scores top-level fidelity dimensions independently. A dimension absent from both inputs is omitted rather than counted as a perfect result. Artifact reload evidence is intentionally caller-supplied: the score is marked verified only when a native artifact was successfully reopened and its re-exported HTML was compared with the original source.
Capability-gallery JSON and Markdown manifests retain the score schema version, top-level dimensions, artifact kind, and reload-verification flag as durable review evidence.
Conversion profile and trust are separate decisions. A Document or HighFidelityPrint profile does not make external resources trusted. Leave Trust as Untrusted for user-supplied HTML; set it to Trusted only when the caller controls the document and resource locations.
Normalized HTML output is policy-aware: hyperlink and resource URLs are evaluated separately, URL-bearing attributes are resolved against the configured base URI, disallowed URLs are removed, boolean attributes are normalized, event-handler attributes are stripped by default, and non-document executable elements are skipped. External bytes are loaded only through a caller-supplied bounded resolver. Normalized output is intended for clean review, gallery proof, and downstream adapter input selection, not as a browser sandbox.
Image Sources
string source = HtmlImageSourceResolver.ResolveImageSource(
imageElement,
baseUri,
HtmlUrlPolicy.CreateOfficeIMOProfile());
Image Data URIs
if (HtmlImageDataUri.TryParse(source, out var dataUri) && dataUri.IsBase64) {
byte[] bytes = dataUri.DecodeBytes();
string extension = dataUri.FileExtension;
}
Use HtmlDataUri when the payload is textual. Its DecodeText() method honors a declared charset and uses UTF-8 only when the data URI does not declare one.
Content provenance
HtmlProvenance.Inspect(html) reports embedded <script type="application/c2pa"> carriers, external <link rel="c2pa-manifest"> references, and provenance inside supported embedded image data URIs. HtmlProvenance.Remove(html) removes only selected, structurally valid carriers by default. Inspection and removal never fetch external resources. Optional cryptographic C2PA verification remains in OfficeIMO.Security.
Concealed-content inspection and cleanup
HtmlContentSafety.Inspect(html) evaluates the bounded CSS cascade and reports hidden, transparent, tiny, zero-size, clipped, off-canvas, and low-contrast text together with comments, scripts/styles, templates, metadata, alternative text, ARIA labels, and hidden form values. HtmlContentSafety.RemoveSelected(...) removes only reviewed current findings—including exact Unicode ranges inside machine-only text nodes—and reinspects the serialized HTML. An empty file selection preserves the source bytes and encoding. No script runs and no external resource is fetched.
Semantic tables and image links
HtmlConversionDocument.SemanticDocument retains structurally nested ARIA table,
row, rowgroup, cell and header roles alongside native HTML tables. Semantic rows
expose SourceRowIndex, including positions occupied by empty authored rows.
CaptionRuns contains authored caption text and inline formatting; inferred table
titles do not manufacture caption runs. Image resources retain the nearest
policy-normalized enclosing hyperlink for editable adapters.
Generated capability summary
This table is generated from the package-neutral OfficeIMO operation catalog. The detailed source contracts remain authoritative for feature-level behavior and limitations.
| Operation | Supported | Partial | Preserved | Rejected | Unsupported | Not applicable |
|---|---|---|---|---|---|---|
| Create | 1 | 0 | 0 | 0 | 0 | 0 |
| Read | 1 | 0 | 0 | 0 | 0 | 0 |
| Edit | 1 | 0 | 0 | 0 | 0 | 0 |
| Preserve | 0 | 1 | 0 | 0 | 0 | 0 |
| Inspect | 2 | 0 | 0 | 0 | 0 | 0 |
| Validate | 1 | 0 | 0 | 0 | 0 | 0 |
| Remove | 1 | 0 | 0 | 0 | 0 | 0 |
| Convert | 1 | 0 | 0 | 0 | 0 | 0 |
| Export | 5 | 0 | 0 | 0 | 0 | 0 |
The complete rows for OfficeIMO.Html are published in the generated operation contract.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 is compatible. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.7.2
- AngleSharp (>= 1.8.3)
- AngleSharp.Css (>= 1.1.3)
- OfficeIMO.Core (>= 3.5.2)
- OfficeIMO.Html.AngleSharp (>= 3.5.2)
- OfficeIMO.Html.Core (>= 3.5.2)
- OfficeIMO.Pdf (>= 3.5.2)
-
.NETStandard 2.0
- AngleSharp (>= 1.8.3)
- AngleSharp.Css (>= 1.1.3)
- OfficeIMO.Core (>= 3.5.2)
- OfficeIMO.Html.AngleSharp (>= 3.5.2)
- OfficeIMO.Html.Core (>= 3.5.2)
- OfficeIMO.Pdf (>= 3.5.2)
-
net10.0
- AngleSharp (>= 1.8.3)
- AngleSharp.Css (>= 1.1.3)
- OfficeIMO.Core (>= 3.5.2)
- OfficeIMO.Html.AngleSharp (>= 3.5.2)
- OfficeIMO.Html.Core (>= 3.5.2)
- OfficeIMO.Pdf (>= 3.5.2)
-
net8.0
- AngleSharp (>= 1.8.3)
- AngleSharp.Css (>= 1.1.3)
- OfficeIMO.Core (>= 3.5.2)
- OfficeIMO.Html.AngleSharp (>= 3.5.2)
- OfficeIMO.Html.Core (>= 3.5.2)
- OfficeIMO.Pdf (>= 3.5.2)
NuGet packages (17)
Showing the top 5 NuGet packages that depend on OfficeIMO.Html:
| Package | Downloads |
|---|---|
|
OfficeIMO.Markdown.Html
HTML converter for OfficeIMO.Markdown - Convert HTML fragments or documents into OfficeIMO.Markdown documents and Markdown text. |
|
|
OfficeIMO.Html.Pdf
PDF-to-HTML semantic and positioned-review conversion for OfficeIMO. |
|
|
HtmlTinkerX
HTML, CSS, and JavaScript parsing, extraction, auditing, formatting, and browser automation for .NET and PowerShell. |
|
|
OfficeIMO.Word.Html
HTML converter for OfficeIMO.Word - Convert Word documents to/from HTML using AngleSharp |
|
|
OfficeIMO.Epub
Bounded EPUB 2/3 reading, authoring, editing and package preservation for OfficeIMO. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.5.2 | 54 | 10/24/2026 |
| 3.5.1 | 1,966 | 10/16/2026 |
| 3.4.5 | 5,199 | 10/10/2026 |
| 3.4.4 | 6,589 | 9/27/2026 |
| 3.4.3 | 12,296 | 9/12/2026 |
| 3.4.2 | 1,256 | 9/9/2026 |
| 3.4.1 | 962 | 9/7/2026 |
| 3.4.0 | 893 | 9/6/2026 |
| 3.3.0 | 889 | 9/2/2026 |
| 3.2.7 | 940 | 8/29/2026 |
| 3.2.6 | 4,428 | 8/22/2026 |
| 3.2.5 | 1,025 | 8/21/2026 |
| 3.2.4 | 1,096 | 8/19/2026 |
| 3.2.3 | 868 | 8/17/2026 |
| 3.2.2 | 26,935 | 8/13/2026 |
| 3.2.1 | 1,004 | 8/11/2026 |
| 3.2.0 | 9,984 | 8/7/2026 |
| 3.1.1 | 610 | 8/7/2026 |
| 3.1.0 | 636 | 8/6/2026 |
| 3.0.3 | 1,228 | 7/27/2026 |