Plotly-Dash中如何实现折叠一个div时另一div相对占满全屏
问题背景
在plotly-dash框架下开发时,页面放置了两个横向相邻的div(内部承载Graph图表组件),期望实现点击后折叠其中一个div、另一个div自动占满100%容器空间达到全屏展示的效果。目前使用collapse折叠组件实现显隐逻辑时,折叠操作后剩余的div无法自动撑满容器,存在留白问题,需要可落地的实现方案。
效果参考:

实现方案
优先使用CSS布局+Dash回调动态控制样式的方案实现,不需要额外引入复杂组件,兼容性最好:
- 核心思路:放弃collapse组件默认的
display: none显隐逻辑,改用弹性/网格布局做宽度自适应,通过回调动态修改两个div的宽度占比,配合过渡动画实现顺滑的折叠效果。 - 具体实现步骤:
- 外层容器设置为弹性布局,宽度占满父级:
style={"display": "flex", "width": "100%"} - 两个图表div默认宽度各设为50%,添加内边距保证排版间距
- 给折叠操作按钮绑定回调,根据点击状态动态修改两个div的宽度:折叠某侧时将该侧宽度设为0、隐藏溢出内容,另一侧宽度设为100%
- 给Graph组件开启响应式配置
config={"responsive": True},保证容器尺寸变化时图表自动重绘适配
- 外层容器设置为弹性布局,宽度占满父级:
核心参考代码:
import dash from dash import dcc, html, Input, Output app = dash.Dash(__name__) app.layout = html.Div([ # 操作按钮区 html.Div([ html.Button("折叠/展开左侧图表", id="toggle-left", n_clicks=0), html.Button("折叠/展开右侧图表", id="toggle-right", n_clicks=0) ], style={"marginBottom": "12px"}), # 图表外层容器 html.Div( id="graph-container", style={"display": "flex", "width": "100%", "height": "85vh", "gap": "12px"}, children=[ html.Div(id="left-panel", style={"width": "50%", "transition": "width 0.3s ease"}, children=[ dcc.Graph(id="left-chart", config={"responsive": True}) # 自行替换图表figure配置 ]), html.Div(id="right-panel", style={"width": "50%", "transition": "width 0.3s ease"}, children=[ dcc.Graph(id="right-chart", config={"responsive": True}) # 自行替换图表figure配置 ]) ] ) ]) @app.callback( [Output("left-panel", "style"), Output("right-panel", "style")], [Input("toggle-left", "n_clicks"), Input("toggle-right", "n_clicks")] ) def update_panel_width(left_click, right_click): base_style = {"transition": "width 0.3s ease", "overflow": "hidden"} # 判断触发源 trigger = dash.callback_context.triggered[0]["prop_id"].split(".")[0] if trigger == "toggle-left" and left_click % 2 == 1: return [{**base_style, "width": 0}, {**base_style, "width": "100%"}] if trigger == "toggle-right" and right_click % 2 == 1: return [{**base_style, "width": "100%"}, {**base_style, "width": 0}] # 默认状态各占一半 return [{**base_style, "width": "50%"}, {**base_style, "width": "50%"}] if __name__ == "__main__": app.run_server(debug=True)
- 可选替代方案:如果习惯用网格布局,可将外层容器改为
display: grid,默认gridTemplateColumns: "1fr 1fr",折叠时动态修改为"1fr 0"或"0 1fr",实现逻辑和弹性布局完全一致。
注意:不要给图表容器设置固定像素宽度,所有宽度使用百分比或弹性单位;被折叠的容器必须加overflow: hidden,避免内部内容溢出影响布局。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

