Skip to content

Commit 43bc90f

Browse files
authored
Merge pull request #5596 from SharadhNaidu/fix-5591-responsive-html-height
Fix to_html responsive height by styling outer wrapper div
2 parents dc6c302 + 2333a91 commit 43bc90f

5 files changed

Lines changed: 52 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
1212
- Use presence of `COLAB_NOTEBOOK_ID` env var to enable Colab renderer instead of testing import of `google.colab` [[#5473](https://github.com/plotly/plotly.py/pull/5473)], with thanks to @kevineger for the contribution!
1313
- Update tests to be compatible with numpy 2.4 [[#5522](https://github.com/plotly/plotly.py/pull/5522)], with thanks to @thunze for the contribution!
1414
- Add default headers to be passed in to Kaleido v1.3.0 to avoid blocked Open Street Map tiles [#5588](https://github.com/plotly/plotly.py/pull/5588)]
15+
- Propagate the requested `default_height`/`default_width` to the outer wrapper div produced by `to_html` so that responsive (percentage) dimensions inherit from a sized parent container instead of collapsing to the plotly.js 450px fallback [[#5591](https://github.com/plotly/plotly.py/issues/5591)], with thanks to @SharadhNaidu for the contribution!
1516

1617
### Updated
1718
- The `__eq__` method for `graph_objects` classes now returns `NotImplemented` to give the other operand an opportunity to handle the comparison [[#5547](https://github.com/plotly/plotly.py/pull/5547)], with thanks to @RazerM for the contribution!

plotly/io/_html.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,11 +318,11 @@ def to_html(
318318
)
319319

320320
plotly_html_div = """\
321-
<div>\
321+
<div style="height:{height}; width:{width};">\
322322
{mathjax_script}\
323323
{load_plotlyjs}\
324324
<div id="{id}" class="plotly-graph-div" \
325-
style="height:{height}; width:{width};"></div>\
325+
style="height:100%; width:100%;"></div>\
326326
<script>\
327327
window.PLOTLYENV=window.PLOTLYENV || {{}};{base_url_line}\
328328
{script};\

tests/test_core/test_offline/test_offline.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ def test_div_output(self):
278278

279279
self.assertNotIn("<html>", html)
280280
self.assertNotIn("</html>", html)
281-
self.assertTrue(html.startswith("<div>") and html.endswith("</div>"))
281+
self.assertTrue(html.startswith("<div") and html.endswith("</div>"))
282282

283283
def test_config(self):
284284
config = dict(linkText="Plotly rocks!", showLink=True, editable=True)

tests/test_io/test_html.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,53 @@ def test_cdn_includes_integrity_attribute(fig1):
5353
assert match is not None, "CDN script tag with integrity attribute not found"
5454

5555

56+
def test_outer_wrapper_carries_requested_dimensions(fig1):
57+
"""
58+
Regression test for https://github.com/plotly/plotly.py/issues/5591.
59+
60+
The outer wrapper div produced by ``to_html`` must carry the requested
61+
height/width so that percentage values propagate from a parent container
62+
down to the figure element. Without this, a default of ``height='100%'``
63+
collapses to zero (because the wrapper has no height) and plotly.js falls
64+
back to its hardcoded 450px, breaking any responsive layout.
65+
"""
66+
html = pio.to_html(fig1, include_plotlyjs="cdn", full_html=False)
67+
68+
wrapper_match = re.match(r'<div style="([^"]+)">', html)
69+
assert wrapper_match is not None, (
70+
"Outer wrapper div is missing inline style; responsive parents cannot "
71+
"propagate dimensions to the figure."
72+
)
73+
wrapper_style = wrapper_match.group(1)
74+
assert "height:100%" in wrapper_style
75+
assert "width:100%" in wrapper_style
76+
77+
inner_match = re.search(
78+
r'<div id="[^"]+" class="plotly-graph-div" style="([^"]+)">',
79+
html,
80+
)
81+
assert inner_match is not None
82+
assert "height:100%" in inner_match.group(1)
83+
assert "width:100%" in inner_match.group(1)
84+
85+
86+
def test_outer_wrapper_respects_explicit_pixel_dimensions(fig1):
87+
"""Explicit pixel dimensions must reach the outer wrapper unchanged."""
88+
html = pio.to_html(
89+
fig1,
90+
include_plotlyjs="cdn",
91+
full_html=False,
92+
default_width=600,
93+
default_height=400,
94+
)
95+
96+
wrapper_match = re.match(r'<div style="([^"]+)">', html)
97+
assert wrapper_match is not None
98+
wrapper_style = wrapper_match.group(1)
99+
assert "height:400px" in wrapper_style
100+
assert "width:600px" in wrapper_style
101+
102+
56103
def test_cdn_integrity_hash_matches_bundled_content(fig1):
57104
"""Test that the SRI hash in CDN script tag matches the bundled plotly.js content"""
58105
html_output = pio.to_html(fig1, include_plotlyjs="cdn")

tests/test_io/test_renderers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ def test_repr_html(renderer):
307307
sri_hash = _generate_sri_hash(plotlyjs_content)
308308

309309
template = (
310-
"<div> <script>"
310+
'<div style="height:100%; width:100%;"> <script>'
311311
"window.PlotlyConfig = {MathJaxConfig: 'local'};</script>\n "
312312
'<script charset="utf-8" src="'
313313
+ plotly_cdn_url()

0 commit comments

Comments
 (0)