Displaying a hidden div changes the layout

Hello! I’m running into a problem in Dash where Plotly figures display in an unexpected way when a hidden div that contains a figure is changed from hidden to visible (using Bootstrap classes). I’m not sure if this is being caused by Dash, Bootstrap, or user error, so any help is greatly appreciated. Examples below. The only difference in the two examples is that the Case 2 the “main-div” starts as a hidden div with class “d-none” and the callback removes that class. In Case 2, the plotly figure expands out of its parent div and overlaps with the neighbouring div.

(I ran into this problem using dash-bootstrap-components but I’ve removed the dbc objects to simplify the example)

Thanks!

Case 1: Visible div, expected behaviour

# -*- coding: utf-8 -*-
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate


external_stylesheets=[dbc.themes.BOOTSTRAP]

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div(className="container",children=[
    html.Div(className="row",children=[
        dbc.Button("Push me", id="mybutton")    
    ]),

    
    html.Div(id='main-div',className='row',children=[
        html.Div(className='col-4',children=[
            dcc.Graph(
                id='example-graph',
                figure={
                    'data': [
                        {'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': 'SF'},
                        {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': u'Montréal'},
                    ],
                    'layout': {
                        'title': 'Dash Data Visualization'
                    }
                }
            )
        ]),
        html.Div(className="col-4 border",children="This is the second column")
    ])
])


@app.callback(Output('main-div','className'),
              [Input('mybutton','n_clicks')]
              )
def mycallback(n_clicks):
    if n_clicks is None:
        raise PreventUpdate
    return "row"


if __name__ == '__main__':
    app.run_server(debug=True,host='0.0.0.0',port=8051)


Case 2: Show hidden div, unexpected behaviour

# -*- coding: utf-8 -*-
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate


external_stylesheets=[dbc.themes.BOOTSTRAP]

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div(className="container",children=[
    html.Div(className="row",children=[
        dbc.Button("Push me", id="mybutton")    
    ]),

    
    html.Div(id='main-div',className='row d-none',children=[
        html.Div(className='col-4',children=[
            dcc.Graph(
                id='example-graph',
                figure={
                    'data': [
                        {'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': 'SF'},
                        {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': u'Montréal'},
                    ],
                    'layout': {
                        'title': 'Dash Data Visualization'
                    }
                }
            )
        ]),
        html.Div(className="col-4 border",children="This is the second column")
    ])
])


@app.callback(Output('main-div','className'),
              [Input('mybutton','n_clicks')]
              )
def mycallback(n_clicks):
    if n_clicks is None:
        raise PreventUpdate
    return "row"


if __name__ == '__main__':
    app.run_server(debug=True,host='0.0.0.0',port=8051)

I’ve found a workaround:

Set the Div as visible in the layout, but have a callback that changes it to hidden on initial page load.

I’d still be interested in figuring out what’s causing this if anyone has any ideas.