Cannot see all of scrollable sidebar menu

I have a sidebar menu in my app. As I have added quite a few items, I noticed that I cannot scroll to see all of the menu. The following min dash program displays this issue at least for me. Click the menu button to get the sidebar menu to display. If you see the “first” and “last” menu items, decrease the height of the browser so that the scroll bar appears in the sidebar. For me, the scrollbar does not allow me to see the last 2 menu items when I scroll all of the way down. Any suggestions?

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
sidebar menu.
"""
from dash import callback, Dash, dcc, html, Input, Output, State
import dash_bootstrap_components as dbc

app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP], suppress_callback_exceptions=True,
           meta_tags=[{'name': 'viewport', 'content': 'width=device-width, initial-scale=1.0'}])

left_nav = [dbc.Nav([dbc.NavLink('first', id='first',
                                 href=app.get_relative_path('/first'), active='exact'),
                     dbc.NavLink('Last -23', id='last-23',
                                 href=app.get_relative_path('/last-23'), active='exact'),
                     dbc.NavLink('Last -22', id='last-22', href=app.get_relative_path('/last-22'),
                                 active='exact'),
                     dbc.NavLink('Last -21', id='last-21', href=app.get_relative_path('/last-21'),
                                 active='exact'),
                     dbc.NavLink('Last -20', id='last-20', href=app.get_relative_path('/last-20'),
                                 active='exact'),
                     dbc.NavLink('Last -19', id='last-19', href=app.get_relative_path('/last-19'),
                                 active='exact'),
                     dbc.NavLink('Last -18', id='last-18', href=app.get_relative_path('/last-18'),
                                 active='exact'),
                     dbc.NavLink('Last -17', id='last-17', href=app.get_relative_path('/last-17'),
                                 active='exact'),
                     dbc.NavLink('Last -16', id='last-16', href=app.get_relative_path('/last-16'),
                                 active='exact'),
                     dbc.NavLink('Last -15', id='last-15', href=app.get_relative_path('/last-15'),
                                 active='exact'),
                     dbc.NavLink('Last -14', id='last-14', href=app.get_relative_path('/last-14'),
                                 active='exact'),
                     dbc.NavLink('Last -13', id='last-13', href=app.get_relative_path('/last-13'),
                                 active='exact'),
                     html.Hr(),
                     dbc.NavLink('Last -12', id='last-12', href=app.get_relative_path('/last-12'),
                                 active='exact'),
                     dbc.NavLink('Last -11', id='last-11', href=app.get_relative_path('/last-11'),
                                 active='exact'),
                     dbc.NavLink('Last -10', id='last-10', href=app.get_relative_path('/last-10'),
                                 active='exact'),
                     dbc.NavLink('Last -9', id='last-9', href=app.get_relative_path('/last-9'),
                                 active='exact'),
                     dbc.NavLink('Last -8', id='last-8', href=app.get_relative_path('/last-8'),
                                 active='exact'),
                     dbc.NavLink('Last -7', id='last-7', href=app.get_relative_path('/last-7'),
                                 active='exact'),
                     html.Hr(),
                     dbc.NavLink('Last -6', id='last-6', href=app.get_relative_path('/last-6'),
                                 active='exact'),
                     dbc.NavLink('Last -5', id='last-5', href=app.get_relative_path('/last-5'),
                                 active='exact'),
                     dbc.NavLink('Last -4', id='last-4', href=app.get_relative_path('/last-4'),
                                 active='exact'),
                     dbc.NavLink('Last -3', id='last-3', href=app.get_relative_path('/last-3'),
                                 active='exact'),
                     dbc.NavLink('Last -2', id='last-2', href=app.get_relative_path('/last-2'),
                                 active='exact'),
                     html.Hr(),
                     dbc.NavLink('Last -1', id='last-1', href=app.get_relative_path('/last-1'),
                                 active='exact'),
                     dbc.NavLink('Last', id='last', href=app.get_relative_path('/last'),
                                 active='exact')],
                    vertical=True,
                    pills=True,
                    id='left-nav')]

sidebar = dbc.Card([dbc.CardBody([dbc.Row(dbc.Col([html.H2('My App', className='display-4'),
                                                   html.Hr(),
                                                   html.P('Traverse through pages as necessary', className='lead'),
                                                   html.Nav(left_nav, id='left-nav-container')],
                                                   className='h-100 overflow-scroll'),
                                          className='vh-100')
                                          ]

                                  )],
                   color='light',
                   style={'height': '100vh',
                          'width': '16rem',
                          'position': 'fixed',
                          # 'padding': '2rem 1rem',
                          'background-color': '#f8f9fa'})

content = dbc.Card([dbc.CardBody([dbc.Row([dbc.Col(dbc.Button("Menu", id='open-menu', size='sm', n_clicks=0),
                                                       width={'size': 1}),
                                           dbc.Col(html.H2('My App', className='card-title'),
                                                   width='auto'),
                                           ],
                                          justify='between'),
                                  html.Hr(),
                                  html.Div(id='page-content', style={'padding': '0rem'}),
                                  html.Div(id='toast-container', style={'position': 'fixed', 'zindex': 1050,
                                                                        'top': 10, 'right': 10, 'width': 350})])])

app.layout = dbc.Container([dcc.Location(id='url'),
                            dbc.Offcanvas(sidebar, id="off-canvas-sidebar", is_open=False),
                            content], fluid=True)

@callback(Output('off-canvas-sidebar', 'is_open'),
          Input('open-menu', 'n_clicks'),
          State('off-canvas-sidebar', 'is_open'))
def toggle_menu(n_clicks, is_open):
    """Toggle the menu."""
    if n_clicks:
        is_open = not is_open
    return is_open

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

I think this is due to lot’s of hard height specs in your layout.

try removing the h-100 in the className

1 Like

For some reason, if I take out the h-100, I get no scrollbar at all and thus only see part of the menu selections.

@AIMPED did you try what you suggested? It does not work for me. I also tried several other things none of which worked. The only thing I found to work is to add some dummy navlinks to the bottom of the menu in order to see all of the real ones.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
sidebar menu.
"""
from dash import callback, Dash, dcc, html, Input, Output, State
import dash_bootstrap_components as dbc

app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP], suppress_callback_exceptions=True,
           meta_tags=[{'name': 'viewport', 'content': 'width=device-width, initial-scale=1.0'}])

left_nav = [dbc.Nav([dbc.NavLink('first', id='first',
                                 href=app.get_relative_path('/first'), active='exact'),
                     dbc.NavLink('Last -23', id='last-23',
                                 href=app.get_relative_path('/last-23'), active='exact'),
                     dbc.NavLink('Last -22', id='last-22', href=app.get_relative_path('/last-22'),
                                 active='exact'),
                     dbc.NavLink('Last -21', id='last-21', href=app.get_relative_path('/last-21'),
                                 active='exact'),
                     dbc.NavLink('Last -20', id='last-20', href=app.get_relative_path('/last-20'),
                                 active='exact'),
                     dbc.NavLink('Last -19', id='last-19', href=app.get_relative_path('/last-19'),
                                 active='exact'),
                     dbc.NavLink('Last -18', id='last-18', href=app.get_relative_path('/last-18'),
                                 active='exact'),
                     dbc.NavLink('Last -17', id='last-17', href=app.get_relative_path('/last-17'),
                                 active='exact'),
                     dbc.NavLink('Last -16', id='last-16', href=app.get_relative_path('/last-16'),
                                 active='exact'),
                     dbc.NavLink('Last -15', id='last-15', href=app.get_relative_path('/last-15'),
                                 active='exact'),
                     dbc.NavLink('Last -14', id='last-14', href=app.get_relative_path('/last-14'),
                                 active='exact'),
                     dbc.NavLink('Last -13', id='last-13', href=app.get_relative_path('/last-13'),
                                 active='exact'),
                     html.Hr(),
                     dbc.NavLink('Last -12', id='last-12', href=app.get_relative_path('/last-12'),
                                 active='exact'),
                     dbc.NavLink('Last -11', id='last-11', href=app.get_relative_path('/last-11'),
                                 active='exact'),
                     dbc.NavLink('Last -10', id='last-10', href=app.get_relative_path('/last-10'),
                                 active='exact'),
                     dbc.NavLink('Last -9', id='last-9', href=app.get_relative_path('/last-9'),
                                 active='exact'),
                     dbc.NavLink('Last -8', id='last-8', href=app.get_relative_path('/last-8'),
                                 active='exact'),
                     dbc.NavLink('Last -7', id='last-7', href=app.get_relative_path('/last-7'),
                                 active='exact'),
                     html.Hr(),
                     dbc.NavLink('Last -6', id='last-6', href=app.get_relative_path('/last-6'),
                                 active='exact'),
                     dbc.NavLink('Last -5', id='last-5', href=app.get_relative_path('/last-5'),
                                 active='exact'),
                     dbc.NavLink('Last -4', id='last-4', href=app.get_relative_path('/last-4'),
                                 active='exact'),
                     dbc.NavLink('Last -3', id='last-3', href=app.get_relative_path('/last-3'),
                                 active='exact'),
                     dbc.NavLink('Last -2', id='last-2', href=app.get_relative_path('/last-2'),
                                 active='exact'),
                     html.Hr(),
                     dbc.NavLink('Last -1', id='last-1', href=app.get_relative_path('/last-1'),
                                 active='exact'),
                     dbc.NavLink('Last', id='last', href=app.get_relative_path('/last'),
                                 active='exact'),
                                              dbc.NavLink(''),
                     dbc.NavLink(''),
                     dbc.NavLink(''),
                     dbc.NavLink(''),
                     dbc.NavLink(''),
                     ],
                    vertical=True,
                    pills=True,
                    id='left-nav')]

sidebar = dbc.Card([dbc.CardBody([dbc.Row(dbc.Col([html.H2('My App', className='display-4'),
                                                   html.Hr(),
                                                   html.P('Traverse through pages as necessary', className='lead'),
                                                   html.Nav(left_nav, id='left-nav-container')],
                                                  # className='overflow-scroll'
                                                  className='h-100 overflow-scroll'),
                                          className='vh-100')
                                          ]

                                  )],
                   color='light',
                   style={'height': '100vh',
                          'width': '16rem',
                          'position': 'fixed',
                          # 'padding': '2rem 1rem',
                          'background-color': '#f8f9fa'})

content = dbc.Card([dbc.CardBody([dbc.Row([dbc.Col(dbc.Button("Menu", id='open-menu', size='sm', n_clicks=0),
                                                       width={'size': 1}),
                                           dbc.Col(html.H2('My App', className='card-title'),
                                                   width='auto'),
                                           ],
                                          justify='between'),
                                  html.Hr(),
                                  html.Div(id='page-content', style={'padding': '0rem'}),
                                  html.Div(id='toast-container', style={'position': 'fixed', 'zindex': 1050,
                                                                        'top': 10, 'right': 10, 'width': 350})])])

app.layout = dbc.Container([dcc.Location(id='url'),
                            dbc.Offcanvas(sidebar, id="off-canvas-sidebar", is_open=False),
                            content], fluid=True)

@callback(Output('off-canvas-sidebar', 'is_open'),
          Input('open-menu', 'n_clicks'),
          State('off-canvas-sidebar', 'is_open'))
def toggle_menu(n_clicks, is_open):
    """Toggle the menu."""
    if n_clicks:
        is_open = not is_open
    return is_open

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

HI Brent, I think you could do something as below to make it work.

  • Change from html.Nav(left_nav, id='left-nav-container') to html.Div(left_nav, id='left-nav-container')
  • Remove 'height': '100vh' and 'position': 'fixed' in Card style.

I think with this below code, it will work as your expectation:

from dash import callback, Dash, dcc, html, Input, Output, State
import dash_bootstrap_components as dbc

app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP], suppress_callback_exceptions=True,
           meta_tags=[{'name': 'viewport', 'content': 'width=device-width, initial-scale=1.0'}])

left_nav = [dbc.Nav([dbc.NavLink('first', id='first',
                                 href=app.get_relative_path('/first'), active='exact'),
                     dbc.NavLink('Last -23', id='last-23',
                                 href=app.get_relative_path('/last-23'), active='exact'),
                     dbc.NavLink('Last -22', id='last-22', href=app.get_relative_path('/last-22'),
                                 active='exact'),
                     dbc.NavLink('Last -21', id='last-21', href=app.get_relative_path('/last-21'),
                                 active='exact'),
                     dbc.NavLink('Last -20', id='last-20', href=app.get_relative_path('/last-20'),
                                 active='exact'),
                     dbc.NavLink('Last -19', id='last-19', href=app.get_relative_path('/last-19'),
                                 active='exact'),
                     dbc.NavLink('Last -18', id='last-18', href=app.get_relative_path('/last-18'),
                                 active='exact'),
                     dbc.NavLink('Last -17', id='last-17', href=app.get_relative_path('/last-17'),
                                 active='exact'),
                     dbc.NavLink('Last -16', id='last-16', href=app.get_relative_path('/last-16'),
                                 active='exact'),
                     dbc.NavLink('Last -15', id='last-15', href=app.get_relative_path('/last-15'),
                                 active='exact'),
                     dbc.NavLink('Last -14', id='last-14', href=app.get_relative_path('/last-14'),
                                 active='exact'),
                     dbc.NavLink('Last -13', id='last-13', href=app.get_relative_path('/last-13'),
                                 active='exact'),
                     html.Hr(),
                     dbc.NavLink('Last -12', id='last-12', href=app.get_relative_path('/last-12'),
                                 active='exact'),
                     dbc.NavLink('Last -11', id='last-11', href=app.get_relative_path('/last-11'),
                                 active='exact'),
                     dbc.NavLink('Last -10', id='last-10', href=app.get_relative_path('/last-10'),
                                 active='exact'),
                     dbc.NavLink('Last -9', id='last-9', href=app.get_relative_path('/last-9'),
                                 active='exact'),
                     dbc.NavLink('Last -8', id='last-8', href=app.get_relative_path('/last-8'),
                                 active='exact'),
                     dbc.NavLink('Last -7', id='last-7', href=app.get_relative_path('/last-7'),
                                 active='exact'),
                     html.Hr(),
                     dbc.NavLink('Last -6', id='last-6', href=app.get_relative_path('/last-6'),
                                 active='exact'),
                     dbc.NavLink('Last -5', id='last-5', href=app.get_relative_path('/last-5'),
                                 active='exact'),
                     dbc.NavLink('Last -4', id='last-4', href=app.get_relative_path('/last-4'),
                                 active='exact'),
                     dbc.NavLink('Last -3', id='last-3', href=app.get_relative_path('/last-3'),
                                 active='exact'),
                     dbc.NavLink('Last -2', id='last-2', href=app.get_relative_path('/last-2'),
                                 active='exact'),
                     html.Hr(),
                     dbc.NavLink('Last -1', id='last-1', href=app.get_relative_path('/last-1'),
                                 active='exact'),
                     dbc.NavLink('Last', id='last', href=app.get_relative_path('/last'),
                                 active='exact')
                     ],
                    vertical=True,
                    pills=True)]
sidebar = dbc.Card([
    dbc.CardBody([
        dbc.Row(
            dbc.Col([
                html.H2('My App', className='display-4'),
                html.Hr(),
                html.P('Traverse through pages as necessary', className='lead'),
                html.Div(left_nav, id='left-nav-container')
            ])
        )
    ])
], style={'background-color': '#f8f9fa'})
content = dbc.Card([dbc.CardBody([dbc.Row([dbc.Col(dbc.Button("Menu", id='open-menu', size='sm', n_clicks=0),
                                                       width={'size': 1}),
                                           dbc.Col(html.H2('My App', className='card-title'),
                                                   width='auto'),
                                           ],
                                          justify='between'),
                                  html.Hr(),
                                  html.Div(id='page-content', style={'padding': '0rem'}),
                                  html.Div(id='toast-container', style={'position': 'fixed', 'zindex': 1050,
                                                                        'top': 10, 'right': 10, 'width': 350})])])

app.layout = dbc.Container([dcc.Location(id='url'),
                            dbc.Offcanvas(sidebar, id="off-canvas-sidebar", is_open=False, scrollable=False),
                            content], fluid=True)

@callback(Output('off-canvas-sidebar', 'is_open'),
          Input('open-menu', 'n_clicks'),
          State('off-canvas-sidebar', 'is_open'))
def toggle_menu(n_clicks, is_open):
    """Toggle the menu."""
    if n_clicks:
        is_open = not is_open
    return is_open

if __name__ == '__main__':
    app.run_server(debug=False, threaded=False, use_reloader=False)

Thank you.

I was able to get what I wanted by looking at your code. In addition to what you mentioned in your note, I had to remove most of the style statements.