The HTML produced by `to_html` wraps the figure in an outer `<div>` with
no inline style. The inner figure div sets `height:100%`, but because
the wrapper has no height, that 100% resolves to zero and plotly.js
falls back to its hardcoded 450px. The result is that the documented
default of `default_height='100%'` cannot inherit from a sized parent
container, so figures embedded in responsive layouts (Jinja templates,
Dash containers with `vh`/`%` heights, etc.) silently render at 450px.
Move the requested dimensions onto the wrapper and let the inner figure
div fill it. Pixel defaults still produce a fixed-size figure; percentage
defaults now propagate from the parent container as the docstring claims.
Closes plotly#5591
Link to issue
Closes #5591
Description of change
to_html wraps the figure inside an outer <div> that has no inline style. The inner figure div sets style="height:100%; width:100%;", but because the wrapper has no height, that 100% resolves to zero, and plotly.js then falls back to its hardcoded 450px default.
The result: the documented default of default_height='100%' cannot inherit from a sized parent container. Any figure placed inside a Jinja template, a Dash container with a vh/% height, or any responsive layout silently renders at 450px instead of filling its parent. This is the underlying cause of #5591 (and the long-standing plotly.js#5270). PR #5590 documented a regex-based workaround; this PR addresses the root cause.
The fix moves the requested default_height/default_width onto the outer wrapper, and changes the inner figure div to height:100%; width:100%; so it fills the wrapper:
Behavior matrix
Pixel defaults and standalone-document use cases are byte-for-byte equivalent in observable layout. The only behavioral change is that percentage defaults now actually inherit from a sized parent, which matches the docstring.
Testing strategy
Two regression tests added in tests/test_io/test_html.py:
Existing test_html_deterministic and the CDN/integrity tests are unaffected because they assert content presence, not the wrapper element.
Notes for review
Guidelines