Fix to_html responsive height by styling outer wrapper div#5596
Fix to_html responsive height by styling outer wrapper div#5596SharadhNaidu wants to merge 3 commits into
Conversation
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
d9fef0e to
083b847
Compare
|
Did you consider removing the outer div as an alternative solution? |
The outer div produced by to_html now carries a style attribute so that requested dimensions propagate down to the figure element (see plotly#5591). Loosen the existing assertion accordingly.
|
Yeah, I did think about that — dropping the wrapper would also let the Happy to switch to the removal approach if you'd rather take that route — let me know. |
Link to issue
Closes #5591
Description of change
to_htmlwraps the figure inside an outer<div>that has no inline style. The inner figure div setsstyle="height:100%; width:100%;", but because the wrapper has no height, that100%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 avh/%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/plotly.js#5270). PR #5590 documented a regex-based workaround; this PR addresses the root cause.The fix moves the requested
default_height/default_widthonto the outer wrapper, and changes the inner figure div toheight:100%; width:100%;so it fills the wrapper:Behavior matrix
height='100%'), figure in container withheight:30vhdefault_height=400)height='100%'), no sized parentfull_html=Truestandalone pagePixel 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:test_outer_wrapper_carries_requested_dimensionsasserts the wrapper div has the percentage style and the inner figure div is set to100%of it.test_outer_wrapper_respects_explicit_pixel_dimensionsasserts pixel defaults flow through unchanged.Existing
test_html_deterministicand the CDN/integrity tests are unaffected because they assert content presence, not the wrapper element.Notes for review
to_htmloutput. If maintainers prefer to gate it behind an opt-in (e.g.responsive_layout=True), I am happy to refactor - just let me know.Guidelines