Dash Bootstrap: Problems with layout of columns

Last week I learned about Dash and I immediately got interested in developing a small tool to perform and help visualize some technical computations in my organization. Because of its technical nature, this app will have many input fields and buttons. I learned about Dash Bootstrap Components and it seems to me that this should make it a lot easier to organize all of this into a tidy grid.

The problem is that the column positioning does not seem to work for me. I read the guide at the following location Layout - dbc docs, which makes the positioning seem really easy. As long as the widths do not sum up above 12, the columns should nicely space out and not wrap onto the next line (regardless of screen size). Unfortunately I get some unexpected behavior (I demonstrate two examples of odd behavior in the image and script below).

1: In the row on the top-right, the last column wraps to the next line (in most cases, sometimes it doesn’t). 2: In the row on the bot-right, the last columns ends up on top of the middle column.

Please note that I am not explicitly loading the .css in this script. I am working offline. The workaround I used is to download the .css that would otherwise have been loaded and put it in a ‘assets’ folder. I tried multiple of the Dash Bootstrap Component .css files (here I use bootstrap-grid.min.css, which otherwise would have been loaded using a call to external_stylesheets with dbc.themes.GRID), but the problem is always the same. These two problems may be dependent on screen size (even though I don’t think they should as long as the widths add up to 12 or less).

I have browsed for a solution for quite a while and tested a lot, but no success. If someone with more experience than I have would be able to help me I would be very grateful. Thanks!

Small self-contained portion of my script

import dash
import dash_bootstrap_components as dbc
import dash_html_components as html
import dash_core_components as dcc

#Developing offline, therefore I have to use a local .css from dash boostrap which I placed in the ./assets/ folder.
#For convenience, I have added the stylesheet code line below, even though I don't have it in my local script 
dash.Dash(external_stylesheets=[dbc.themes.GRID])
num_reservoirs_max = 9

#distance
distance_unit_list_m                = ["m", "meter"]
distance_unit_list_ft               = ["ft", "foot", 'feet']
standard_distance_unit_m            = "m"
standard_distance_unit_ft           = "ft"

#density
density_unit_list_gcm3              = ["g/cm3", "gcc"]
density_unit_list_kgm3              = ["kg/m3"]
standard_density_unit_gcm3          = "g/cm3"
standard_density_unit_kgm3          = "kg/m3"

standard_distance_units             = [standard_distance_unit_m, standard_distance_unit_ft]
standard_density_units              = [standard_density_unit_gcm3,standard_density_unit_kgm3]

app = dash.Dash(__name__, prevent_initial_callbacks=True) 
app.layout = html.Div([
                        dbc.Row([
                            dbc.Col(
                                    dbc.Row([
                                            dbc.Col(html.Div("Number of reservoirs to compute 4D"), width=6, align="center"),
                                            dbc.Col(dcc.Dropdown(id="num_reservoirs",
                                                                 options=[dict(label=(i+1), value=(i+1)) for i in range(num_reservoirs_max)],
                                                                 value=1, clearable=False
                                                    )                                                            
                                            ,align="center"),
                                            dbc.Col(html.Button('Submit', id='submit_num_reservoirs'), width=3, align="center")
                                    ]),
                            width=3, style={"border-right":"2px black solid"}),
                            dbc.Col([
                                    dbc.Row([
                                            dbc.Col(html.Div("Water depth (used to compute total pressure)"), width=5),
                                            dbc.Col(dcc.Input(id="water_depth", type="number")),
                                            dbc.Col(dcc.Dropdown(id="water_depth_units",
                                                                 options=[dict(label=unit, value=unit) for unit in standard_distance_units],
                                                                 value=standard_distance_unit_m, 
                                                                 clearable=False,
                                                                 style={'width': '100%'}
                                                    )
                                            , width=2)
                                    ], align='center'),
                                    dbc.Row([
                                            dbc.Col(html.Div("Overburden bulk density (used to compute total pressure)"), width=5),
                                            dbc.Col(dcc.Input(id="overburden_bulk_rho", type="number"), width=2),
                                            dbc.Col(dcc.Dropdown(id="overburden_bulk_rho_units",
                                                                 options=[dict(label=unit, value=unit) for unit in standard_density_units],
                                                                 value=standard_density_unit_kgm3,
                                                                 clearable=False,                                                                                        
                                                                 style={'width': '100%'}
                                                    )
                                            , width=3)
                                    ], align='center')
                            ]
                            ,width=3, style={"border-right":"2px black solid"}), 
                        ], style={"border-bottom":"2px black solid"})    
            ])

if __name__ == '__main__':
    app.run_server(debug=True, dev_tools_hot_reload=False)

I think the problem is just that the columns are really narrow which is squashing the content. In particular you have a column with width 3, and then inside that column another row with columns of width 3. That’s equivalent to saying the column should take up 1/16th of the width of the screen, which isn’t very much. You might need to rethink your layout to make sure that the columns are large enough to contain their content.

BTW, you should make sure there’s at least one dbc.Container in your layout to make sure the rows work properly. Should be an easy fix, just replace the outer html.Div.

app.layout = dbc.Container(..., fluid=True)

Thank you for the quick reply! This is very helpful. I wasn’t aware of the need to have a container object. Unfortunately, simply adding it didn’t solve the problems I was experiencing.

You may be right that the nesting could cause the inner cols to become small in some cases. Based on your suggestion I started rethinking strategies for making the layout more predictable. I’m thinking the ‘input’ and the ‘dropdown’ could have fixed widths and should be locked at the end of the row. Then the text column would be at the start of the row and would expand to fill available space (potentially wrapping the text within the col if it hits the ‘input’ and ‘dropdown’ at the end of the row. That sounds more robust to resizing of the screen and smaller screens in general

The simplified script still doesn’t behave the way as I was expecting. The ‘input’ and ‘dropdown’ do not appear to the far right of the row container (red line to show where right border is), despite the order=12 and order=“last”. I am thinking that I am somehow fundamentally misunderstanding how dash bootstrap works.

I simplified my test script below. Would you be able to give me a pointer of why this is not working the way I thought it would as illustrated in the figure? Thanks a lot!

import dash
import dash_bootstrap_components as dbc
import dash_html_components as html
import dash_core_components as dcc

#Developing offline, therefore I have to use a local .css from dash boostrap which I placed in the ./assets/ folder.
#For convenience, I have added the stylesheet code line below, even though I don't have it in my local script 
dash.Dash(external_stylesheets=[dbc.themes.GRID])

app = dash.Dash(__name__, prevent_initial_callbacks=True) #Prevent initial callbacks before loading .las?
app.layout = dbc.Container([
                        dbc.Row([
                            dbc.Col([
                                    dbc.Row([
                                            dbc.Col(html.Div("Water depth (used to compute total pressure)"),width={"size": "auto", "order": 1}),
                                            dbc.Col(dcc.Input(id="water_depth", type="number", style={'width':'60px'}),width={"size": "auto", "order": 12}),
                                            dbc.Col(dcc.Dropdown(id="water_depth_units",
                                                                 options=[dict(label=unit, value=unit) for unit in ["m", "ft"]],
                                                                 value="m", 
                                                                 clearable=False,
                                                                 style={'width': '60px'}
                                                    )
                                            ,width={"size": "auto", "order": "last"})
                                    ], align='center', style={"border-right":"2px red solid"}),
                            ]
                            ,width=12, style={"border-right":"2px black solid"}), 
                        ], style={"border-bottom":"2px black solid"})    
            ],fluid=True)

if __name__ == '__main__':
    app.run_server(debug=True, dev_tools_hot_reload=False)

My apologies if a topic bump after a couple of days is frowned upon, but I am still very much interested in learning why DBC behaves so unexpectedly for me.

The solution to the problem I show in the first post is explained here: python - Dash Bootstrap: Problems with layout of columns - Stack Overflow

I still don’t understand why in my second post, the columns don’t go to the end of the row (towards the red line)

You’re setting width="auto" on the columns which means the columns are only going to be as wide as is required to contain their contents. If you want the columns to expand to fill the available space you should set width=True instead.