Sticky columns / layout

Hi all, I appreciate the help of this community, so thank you in advance.
I made a little demo (which took me hours, because I didn’t use a bootstrap template apparently :smiling_face_with_tear:).
I basically have an app with two columns, 1 on the left with filters and 1 next to it with a bunch of graphs. I want to have the first column ‘sticky’.

The basic dashboard you can see here:

import dash
import dash_bootstrap_components as dbc
from dash import html, dcc
import plotly.graph_objects as go

offset_column_1 = 0
offset_column_2 = 0
size_column_1 = 3
size_column_2 = 9

dbc_card = dbc.Card(
    dbc.CardBody(
        dbc.Col(
            [
                dcc.Graph(
                    figure=go.Figure(),
                ),
                dbc.Collapse(
                    dbc.Card(
                        dbc.CardBody(
                            [
                                dbc.Button(
                                    children="Hide",
                                    color="primary",
                                ),
                                html.H5(
                                    children="Hi all",
                                ),
                            ]
                        )
                    ),
                    is_open=True,
                ),
            ]
        ),
    ), className = "mb-4"
)

##### dash app #####

app = dash.Dash(
    __name__,
    external_stylesheets=[dbc.themes.MINTY],
)

app.layout = dbc.Container(
    dbc.Row(
        [
            dbc.Col(
                html.Div(
                    [
                        dbc.Row(
                            html.Div(
                                dcc.Dropdown(),
                                className="mb-3",
                            ),
                        ),
                        dbc.Row(
                            html.Div(
                                dcc.Dropdown(),
                                className="mb-3",
                            ),
                        ),
                    ]
                ),
                # style={"position": "fixed"},
                className = "mt-4",
                width={"size": size_column_1, "offset": f"{offset_column_1}"},
            ),

            dbc.Col(
                html.Div(
                    [
                        dbc.Row(
                            [
                                dbc.Col(
                                    dbc_card,
                                    width={"size": size_column_2},
                                )
                            ]
                        ),
                        dbc.Row(
                            [
                                dbc.Col(
                                    dbc_card,
                                    width={"size": size_column_2},
                                )
                            ]
                        ),
                        dbc.Row(
                            [
                                dbc.Col(
                                    dbc_card,
                                    width={"size": size_column_2},
                                )
                            ]
                        ),
                    ]
                ),
                # style = {'position': 'absolute'},
                className = "mt-4",
                width={
                    "size": size_column_2,
                    'offset': f"{offset_column_2}"
                       },
            ),
        ]
    ),
    fluid=True,
)


if __name__ == "__main__":
    app.run_server(debug=True, port=8000)

Couple of questions about this:

  1. How can I fill the white space on the right? I think this is what ‘fluid’ is doing. However, there is a lot of space left to fill. Making it wider than 9 columns will give a horizontal scrollbar (although it doesn’t make it wider than the screen).
  2. I want to offset the first column a bit. Offsetting by 1 column is a bit much however. Why can’t I use the ‘ml-4’ classname for the column or filters here? This doesn’t seem to do anything. I’m generally confused when bootstrap comments do work or not.

Now I would like to make the first column ‘sticky’, so the filters will stay in place. I have managed to do it like this:

import dash
import dash_bootstrap_components as dbc
from dash import html, dcc
import plotly.graph_objects as go

offset_column_1 = 1
offset_column_2 = 4
size_column_1 = 3
size_column_2 = 8

dbc_card = dbc.Card(
    dbc.CardBody(
        dbc.Col(
            [
                dcc.Graph(
                    figure=go.Figure(),
                ),
                dbc.Collapse(
                    dbc.Card(
                        dbc.CardBody(
                            [
                                dbc.Button(
                                    children="Hide",
                                    color="primary",
                                ),
                                html.H5(
                                    children="Hi all",
                                ),
                            ]
                        )
                    ),
                    is_open=True,
                ),
            ]
        ),
    ), className = "mb-4"
)

##### dash app #####

app = dash.Dash(
    __name__,
    external_stylesheets=[dbc.themes.MINTY],
)

app.layout = dbc.Container(
    dbc.Row(
        [
            dbc.Col(
                html.Div(
                    [
                        dbc.Row(
                            html.Div(
                                dcc.Dropdown(),
                                className="mb-3", # ml-4 doesn't work
                            ),
                        ),
                        dbc.Row(
                            html.Div(
                                dcc.Dropdown(),
                                className="mb-3",
                            ),
                        ),
                    ]
                ),
                style={"position": "fixed"},
                className = "mt-4", # ml-4 doesn't work
                width={"size": size_column_1, "offset": f"{offset_column_1}"},
            ),

            dbc.Col(
                html.Div(
                    [
                        dbc.Row(
                            [
                                dbc.Col(
                                    dbc_card,
                                    width={"size": size_column_2},
                                )
                            ]
                        ),
                        dbc.Row(
                            [
                                dbc.Col(
                                    dbc_card,
                                    width={"size": size_column_2},
                                )
                            ]
                        ),
                        dbc.Row(
                            [
                                dbc.Col(
                                    dbc_card,
                                    width={"size": size_column_2},
                                )
                            ]
                        ),
                    ]
                ),
                # style = {'position': 'absolute'},
                className = "mt-4",
                width={
                    "size": size_column_2,
                    'offset': f"{offset_column_2}"
                       },
            ),
        ]
    ),
    fluid=True,
)


if __name__ == "__main__":
    app.run_server(debug=True, port=8000)

There are a couple of problems:

  1. position ‘sticky’ doesn’t seem to do anything. I have changed this to ‘fixed’, which will make the second column jump over the first.
  2. This can be fixed again by letting the second column offset. But this seems a bit ‘hacky’ and not the right way to do it.
  3. Doing something with the position of column 2 also doesn’t seem to do anything.

So I’m generally curious if this is the right way to do it! And I will be greatly helped with filling up the space on the right.

Thanks!

Hello @JordyS,

Thanks for the description. Is this what you are after:

import dash
import dash_bootstrap_components as dbc
from dash import html, dcc
import plotly.graph_objects as go

offset_column_1 = 1
offset_column_2 = 4
size_column_1 = 4
size_column_2 = 8

dbc_card = dbc.Card(
    dbc.CardBody(
        dbc.Col(
            [
                dcc.Graph(
                    figure=go.Figure(),
                ),
                dbc.Collapse(
                    dbc.Card(
                        dbc.CardBody(
                            [
                                dbc.Button(
                                    children="Hide",
                                    color="primary",
                                ),
                                html.H5(
                                    children="Hi all",
                                ),
                            ]
                        )
                    ),
                    is_open=True,
                ),
            ]
        ),
    ), className = "mb-4"
)

##### dash app #####

app = dash.Dash(
    __name__,
    external_stylesheets=[dbc.themes.MINTY],
)

app.layout = dbc.Container(
    dbc.Row(
        [
            dbc.Col(
                html.Div(
                    [
                        dbc.Row(
                            html.Div(
                                dcc.Dropdown(),
                            ),
                            className="mb-3 mx-auto w-75"

                        ),
                        dbc.Row(
                            html.Div(
                                dcc.Dropdown(),
                            ),
                            className="mb-3 mx-auto w-75"
                        ),
                    ],
                ),
                className = "mt-4", # ml-4 doesn't work
                width={"size": size_column_1},
            ),

            dbc.Col(
                html.Div(
                    [
                        dbc.Row(
                            [
                                dbc.Col(
                                    dbc_card,
                                )
                            ]
                        ),
                        dbc.Row(
                            [
                                dbc.Col(
                                    dbc_card,
                                )
                            ]
                        ),
                        dbc.Row(
                            [
                                dbc.Col(
                                    dbc_card,
                                )
                            ]
                        ),
                    ]
                ),
                style={"overflowX":'auto', "overflowY":'auto', 'height':'100%'},
                className = "mt-4 fixed-top",
                width={
                    "size": size_column_2,
                    'offset': f"{offset_column_2}"
                       },
            ),
        ]
    ),
    fluid=True,
)


if __name__ == "__main__":
    app.run_server(debug=True, port=8000)