# DOM Layout Shim documentation
## Agent navigation
Prefer these static text resources over the interactive HTML pages. All links
are relative to this file on the documentation site.
- [Agent guide](./index.md): concise API usage and limitations (this content).
- [Full guide](./guide.md): the complete authored guide.
- [Examples](./examples.md): compatibility summaries, setup code, and JSON reports.
- [CSS support](./css-support-status.md): compact property/topic index; follow a
topic link for its exact support claims, conditions, limitations, and parity.
- [Changelog](./changelog.md): released changes and pending Upcoming entries.
DOM Layout Shim provides deterministic layout and hit testing for DOM-like test
harnesses.
`scrollWidth` and `scrollHeight` report the padding-box size or its scrollable
content extent, whichever is larger, rounded to integer CSS pixels. For example,
a 100×60 container with `overflow:auto` and a 240×180 child reports scroll sizes
of 240×180 instead of zero. Borders are excluded; nested clipped overflow does
not enlarge the outer container, and scrolling does not shrink the reported
size. The engine's existing synthetic `html`/`body`, inline-display, native-control,
and transform-containing-block limitations still apply.
Repeated reads reuse the layout snapshot and its hit-test ordering. Scroll-only
changes reuse computed layout and update viewport geometry, sticky positioning,
and clipping. Editing one stylesheet preserves the parsed data for other sheets;
viewport changes re-evaluate media queries without reparsing unchanged CSS.
Inline declaration parsing, selector expansion, and built-in text measurements
use adaptive bounded caches: recently evicted inputs being reused trigger growth
from 512 up to 4,096 entries; unique inputs alone do not. Active layout passes
retain their selector expansions even
when a stylesheet exceeds the shared cache, avoiding repeated parsing for
large CSS-in-JS stylesheets. Injected `textMeasurer` implementations are not memoized;
scroll-only reads reuse the layout already computed from their measurements.
DOM mutations are checked synchronously when geometry is read. Hosts with
non-patchable CSSOM or scroll APIs retain conservative validation paths.
## CSS support data
- Compatibility explorer: ./css-support-status.html
- Package changelog: ./changelog.html
- Complete normalized inventory: ./data/css-support.json
- CSS property-to-record index: ./data/css-property-index.json
- JSON Schema: ./data/css-support.schema.json
The inventory separates implementation support from Chromium parity. Do not
interpret unverified behavior as unsupported, or accepted-inert declarations as
layout support. Aggregate record statuses are derived from their claims.
Each record identifies its authoring source under `support/css/`. Claims may
include syntax, conditions, parity fixtures, limitations, known mismatches, and
implementation quirks. Every topic is divided into named, behavior-specific
claims so evidence and limitations apply to an explicit scope. Backticked CSS
syntax, DOM APIs, and other identifiers in claim prose are inline code. The
explorer can preview parity fixture source from generated same-origin assets and
links separately to the corresponding GitHub source.
## Native-control geometry
Unstyled native controls use the deterministic `portable` profile by default.
Select it explicitly with `nativeControls: { profile: 'portable' }` when the
test target should be visible in configuration. Profiles do not inspect or
follow the runtime host.
`nativeControls.overrides` merges individual metrics on top of the selected
profile. For example, `{ overrides: { textInput: { width: 220 } } }` changes
only the text-input width and retains its profile height. Consumers can replace
every field in every group to define fully custom intrinsic geometry. The
public `NativeControlMetrics` and `NativeControlOverrides` types describe all
groups and fields.
Profiles model deterministic outer geometry. They do not emulate operating-
system painting, internal widget behavior, or native picker UI.
## User-agent styles
The deterministic `portable` user-agent style profile is enabled by default.
Configure `userAgentStyles: { profile: 'none' }` to omit its presentation
defaults. `userAgentStyles.overrides` accepts CSS at the user-agent origin, so
normal document and inline declarations beat normal user-agent rules. For example,
`{ profile: 'portable', overrides: 'p { margin: 0 }' }` specializes the
baseline without copying it into every test.
Structural HTML behavior is not profile styling: hidden inputs remain
non-rendered with the `none` profile. Native-control intrinsic
metrics remain independently configurable through `nativeControls`.
The engine currently treats `html` and `body` as its synthetic viewport
containing block, so their own margins, padding, and geometry are not modeled
by user-agent overrides.
Inline attributes and stylesheets share CSS declaration parsing and cascade
priority. A stylesheet `width: 100px !important` beats normal inline
`width: 200px`; an important inline declaration beats important author rules.
Font-relative dimensions resolve after font size: both `width: 2em; font-size:
30px` and the reversed declaration order produce a 60px width. Generated
`::before` and `::after` content also resolves custom properties through this
cascade, including variables declared on the pseudo-element itself.
Portable presentation defaults and HTML sizing hints also enter this cascade.
Normal user-agent rules yield to HTML hints such as ``, and
normal author CSS can override those hints. Important user-agent rules retain
priority over important author rules. A paragraph with `font-size: 2em` inside
a 30px parent now resolves to 60px, rather than using the portable paragraph
font size as its inheritance base.
For non-replaced text containers, authored `display: inline` uses the same
wrapped fragments as native phrasing elements. For example,
`