You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Plotly-Dash中如何实现折叠一个div时另一div相对占满全屏

问题背景

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

实现方案

优先使用CSS布局+Dash回调动态控制样式的方案实现,不需要额外引入复杂组件,兼容性最好:

  • 核心思路:放弃collapse组件默认的display: none显隐逻辑,改用弹性/网格布局做宽度自适应,通过回调动态修改两个div的宽度占比,配合过渡动画实现顺滑的折叠效果。
  • 具体实现步骤:
    1. 外层容器设置为弹性布局,宽度占满父级:style={"display": "flex", "width": "100%"}
    2. 两个图表div默认宽度各设为50%,添加内边距保证排版间距
    3. 给折叠操作按钮绑定回调,根据点击状态动态修改两个div的宽度:折叠某侧时将该侧宽度设为0、隐藏溢出内容,另一侧宽度设为100%
    4. 给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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 13:09:10