Some page objects going behind Navbar, and others come in front

I’m learning Dash.

I have a page that’s using CSS to create a sidebar, and a navbar. I have a separate CSS class to hold the page contents (each page fits to the right of the sidebar, and below the navbar.

It works pretty good, however when I scroll down on the page itself - some of the components on the page are hidden as the slide under the navbar, but other items appear on top of the navbar (see images.)

I can’t see any difference between the declarations of the components that are going under versus over.

app.py


app = Dash(__name__, use_pages=True)

app.title="Main Sidebar"

def navbar():
    return html.Div([
                html.P("LC/MS Data Exploration", 
                       style = {"position":"fixed", "bottom":"85%",
                                                          "left":"40%", 
                                                          "font-size":"64px"}), 
                
                dcc.Link("Home", href="/home", 
                         style = {"position":"fixed", "bottom":"85%", "left":"10%", 
                                  "font-size":"32px", "color":"White", "text-decoration":"None"
                                                        }),

                dcc.Link("Unknown Peaks", href="/UnknownPeaksDashboard", 
                         style = {"position":"fixed", "bottom":"85%", "left":"20%", 
                                  "font-size":"32px", "color":"White", "text-decoration":"None"
                                                        }),

                dcc.Store(id='resultset_names',     storage_type='session'),
                dcc.Store(id='resultset_ids',       storage_type='session'),
                dcc.Store(id="connection",          storage_type='session'),

                dcc.Input(id = "connection-host",     type = "text", value = "WIN-PJ3JNCTE9C8.lfs.agilent.com", placeholder = "Host", debounce = True,
                          style = {"position":"fixed", "bottom":"97%", "left":"85%", "width":"17rem"}),
                dcc.Input(id = "connection-port",     type = "text", value = "5433", placeholder = "Port", debounce = True, 
                          style = {"position":"fixed", "bottom":"95%", "left":"85%", "width":"17rem" }),
                dcc.Input(id = "connection-dbname",   type = "text", value = "datarepo", placeholder = "Database", debounce = True, 
                          style = {"position":"fixed", "bottom":"93%", "left":"85%", "width":"17rem" }),                          
                dcc.Input(id = "connection-user",     type = "text", value = "postgres", placeholder = "User", debounce = True, 
                          style = {"position":"fixed", "bottom":"91%", "left":"85%", "width":"17rem" }),                          
                dcc.Input(id = "connection-password", type = "password", value = "postgres", placeholder = "Password", debounce = True,
                          style = {"position":"fixed", "bottom":"89%", "left":"85%", "width":"17rem" }),                                                    
                html.Button('Connect', id='submit-connection-info', n_clicks=0,
                          style = {"position":"fixed", "bottom":"87%", "left":"85%"}),                                                    
    

            ], className = "navbar")
    
def sidebar():
    return html.Div([
                html.Div([
                    dcc.Location(id="url"), 
                    html.Div([
                        html.Div("Filter by date range"),
                        html.Div(id = "sidebar-date-picker-range"),

                        html.Hr(),
                        # Multiselect generated in callback so it updates on changes to connection
                        html.Div("Filter resultset names"),
                        dcc.Input(id = "resultset-name-filter",     
                                  type = "text", 
                                  value = "", # Use this value after demo
                                  placeholder = "REGEX search string", 
                                  debounce = True, 
),
                        html.P(""),
                        html.Div(id = "resultset-name-multiselect"), 
                        html.Div(id = 'message-below-resultset-multiselect'),

                    ],
                    className = "sidebar", # Css formatting saved in variable above
                    ), 
                ]),                 
                dash.page_container
])
app.layout = html.Div([
    navbar(),    
    sidebar(),
])

    
app.scripts.config.serve_locally = True

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

page


layout = html.Div([
                    html.H1(children='Unknown peaks dashboard'),
                    html.H3(children='''Dashboard with charts representing the relationship of 'Unknown' peaks (peaks that were found, but not defined as expected in a method.)'''),

                    dmc.Checkbox(id="update-df-on-change", 
                                 label="Always update data from SQL server on every filter change (will slow the page down)", 
                                 size="md", 
                                 checked=False),

                    html.P(""),
                    html.Hr(),

                    html.H2("Distribution of Unknown Peaks..."),
                    dcc.Loading(
                        id="loading-unknowns-heatmap",
                        children=[html.Div([html.Div(id="loading-unknowns-heatmap-output")])],
                        type="circle",
                    ),                                                

                    ##########################################################
                    # Full width for heat map
                    html.Div(id = 'special-message-above-unknowns-heatmap'),

                    dcc.RadioItems(
                        ["sum", "count", "avg", "min", "max"],
                        'sum',
                        id='unknowns-heatmap-bullets',
                        inline=True,
                    ),
                    
                    html.Div([
                        html.Div(id = "unknowns-heatmap-vertical-range-slider")
                        ], style={'width': '10%', 'display': 'inline-block'}, className="row"),

                    html.Div([
                        dcc.Graph(id='unknowns-heatmap'),
                        ], style={'width': '90%', 'display': 'inline-block', "maxHeight": "400px", "overflow": "scroll"}),
                    
                    html.Div([
                                html.P("Use slider to adjust bin size (Data points per minute of retention time.) Current selection:")
                             ], style={'width': '45%', 'display': 'inline-block'}, className="row"),

                    html.Div([
                                html.Div(id = "unknowns-heatmap-slider-output")
                             ], style={'width': '35%', 'display': 'inline-block'}, className="row"),
                    
                    html.Div([
                            dcc.Slider(1, 100, 1,
                                       value=1,
                                       id='unknowns-heatmap-slider', 
                                       marks= {i:f"{i}" for i in range(0,100,5)},
                            ),
                        ]),
                    
                    html.P(""),
                    html.Hr(),

                    (...snip...)

                ],
                className = "chartPages",
            )

style.css

.sidebar {
    position: fixed;
    overflow: scroll;
    top: 10rem;
    left: 0;
    bottom: 0;
    width: 20rem;
    padding: 2rem 1rem;
    background-color: #f8f9fa;
}

.navbar {
    position: fixed;
    top: 0;
    left: 0;
    bottom:85%;
    width: 100%;
    padding: 2rem 1rem;
    background-color: #0085D5;
    background-image: url(https://www.redacted.com//logo-white-white-2x.png);
	background-position: 2% 15%;;
    background-repeat: no-repeat;
    color: white;
}

.chartPages {
    margin-top: 7rem;
    margin-left: 22rem;
    margin-right: 2rem;
    padding: 2rem 1rem;
}

Page at first load (OK)


|
|
|

Start scrolling down on page

Hello @rightmirem,

Instead of doing all of this through css, have you considered loading these into a dbc grid?

https://dash-bootstrap-components.opensource.faculty.ai/docs/components/layout/

You could have the top nav take the full top row and then the other two areas would share a row inside of the columns.

1 Like

I had tried that, but for some reason they weren’t being aligned in columns or rows (they were just coming our as if I were using html.Div(Text) alone) - even when I cut and pasted the code from that example site you linked to.

HOWEVER, I still had some CSS on the page for the logo and background color and such. I wondered if the rows and columns were defined by CSS in the backend, and somehow they were screwing each other up.

If you are using dbc, make sure you are importing at least one stylesheet, otherwise the css from the layout will not get applied.

1 Like

OK. I figured it out.

The secret was adding a high z-index to the navbar CSS, so the navbar was positioned above everything else.

.navbar {
    position: fixed;
    top: 0;
    left: 0;
    bottom:85%;
    width: 100%;
    padding: 2rem 1rem;
    background-color: #0085D5;
    background-image: url(https://www.xxx.com/xxx/logo-white-white-2x.png);
	background-position: 2% 15%;;
    background-repeat: no-repeat;
    color: white;
    z-index:100;
}

Yes, that is another way to do it. :grin:

Although, as an aside to the columns, and rows…I did add a stylesheet, and they still work nowhere on the page. I am still using the style.css already discussed.

in app.py

external_stylesheets = [dbc.themes.BOOTSTRAP]
app = Dash(__name__, 
           use_pages=True, 
           external_stylesheets=external_stylesheets)

In UnknownPeaksDashboard.py

dash.register_page(__name__, path='/UnknownPeaksDashboard')

global conn

layout = html.Div([
                    html.H1(children='Unknown peaks dashboard'),
                    html.H3(children='''Dashboard with charts representing the relationship of 'Unknown' peaks (peaks that were found, but not defined as expected in a method.)'''),

                    (...snip...)

                    html.P(""),
                    html.Hr(),

                    ##########################################################
                    # Left side of page for unknwn counts versus Expected, Etc.
                    html.Div([
                        html.H2("Head-to-head comparisons"),     

                        dbc.Row([
                            dbc.Col(html.Div("One of three columns")),
                            dbc.Col(html.Div("One of three columns")),
            ,                dbc.Col(html.Div("One of three columns")),
                                ]
                            ),
                                                   
                        # Only selected options
                        # Will need to update the imported _get_injcompound_df if changed
                        dcc.Dropdown(
                            ["resultset_id", "resultset_name", "injection_id", "instrument_name"],
                            "resultset_name",
                            id='head-2-head-chart-yaxis-column'
                        ),
                        html.P([""]), #Spacer

                        (...snip...)
                        
                        ]),
                ],
                className = "chartPages",
            )

Hmmm, strange…

Try the example by itself:

import dash_bootstrap_components as dbc
from dash import html, Dash

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

app.layout = html.Div(
    [
        dbc.Row(dbc.Col(html.Div("A single column"))),
        dbc.Row(
            [
                dbc.Col(html.Div("One of three columns")),
                dbc.Col(html.Div("One of three columns")),
                dbc.Col(html.Div("One of three columns")),
            ]
        ),
    ]
)

app.run()