Side bar with icons - expands on hover

Hey everyone,

I wanted to share a minimal example of a cool side bar that @Sohibjon made. It shows just the icons, but when you hover over the sidebar, it expends to show the description and the link:

sidebar_expand_on_hover

import dash
import dash_bootstrap_components as dbc
from dash import html

app = dash.Dash(
    __name__,
    suppress_callback_exceptions=True,
    external_stylesheets=[dbc.themes.MATERIA, dbc.icons.FONT_AWESOME],
)


sidebar = html.Div(
    [
        html.Div(
            [
                html.H2("Auto ML", style={"color": "white"}),
            ],
            className="sidebar-header",
        ),
        html.Hr(),
        dbc.Nav(
            [
                dbc.NavLink(
                    [html.I(className="fas fa-home me-2"), html.Span("Dashboard")],
                    href="/",
                    active="exact",
                ),
                dbc.NavLink(
                    [
                        html.I(className="fas fa-calendar-alt me-2"),
                        html.Span("Projects"),
                    ],
                    href="/projects",
                    active="exact",
                ),
                dbc.NavLink(
                    [
                        html.I(className="fas fa-envelope-open-text me-2"),
                        html.Span("Datasets"),
                    ],
                    href="/datasets",
                    active="exact",
                ),
            ],
            vertical=True,
            pills=True,
        ),
    ],
    className="sidebar",
)

app.layout = html.Div(
    [
        sidebar,
        html.Div(
            [
                dash.page_container
            ],
            className="content",
        ),
    ]
)

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

Put this in a .css file in the assets folder:



/* This creates a skinny side bar fixed to the left of the page */
.sidebar {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: 5rem;
  padding: 2rem 1rem;
  background-color: #cbd3dd;
  z-index: 1050;
  transition: width 0.1s ease-in-out;
}

/* when the user hovers on the sidebar, expand it */
.sidebar:hover {
  width: 16rem;
}

/* make sure the contents of the navlink don't wrap when navbar collapses */
.sidebar .nav-link {
  width: 100%;
  overflow: hidden;
  white-space: nowrap;
}

/* fix the width of the icons */
.sidebar .nav-link i {
  width: 1rem;
}

/* hide the navlink labels by default */
.sidebar .nav-link span {
  visibility: hidden;
  opacity: 1;
  transition: opacity 0.1s ease-in-out;
}

/* when the sidebar is hovered, reveal the labels */
.sidebar:hover .nav-link span {
  visibility: visible;
  opacity: 1;
  color: black;
}

/* container for the sidebar header. make sure the contents don't wrap when
 * the sidebar is collapsed.
 */
.sidebar-header {
  display: flex;
  justify-content: left;
  align-items: center;
  overflow: hidden;
  white-space: nowrap;
}

/* position the header relative to the logo and hide by default */
.sidebar-header h2 {
  opacity: 0;
  margin-left: 1rem;
  margin-bottom: 0;
  transition: opacity 0.1s ease-in-out;
}

/* reveal the header when the sidebar is toggled */
.sidebar:hover .sidebar-header h2 {
  opacity: 1;
}

/* position the content relative to the collapsed sidebar */
.content {
  margin-left: 7rem;
  margin-right: 2rem;
  padding: 2rem 1rem;
}
7 Likes

Hey hey,
Wanted to add on to @Sohibjon @AnnMarieW awesome work. This example uses Mantine in case anyone is using it. Below is a working example of how to use a media query to make your side nav bar expand and contract at certain breakpoints in a similar fashion to the one above. Mantine has some standard breakpoints you can utilize using Mediaqueries.

This example is using two distinct mediaquery components that show at different breakpoints, an icon only side bar for smaller screens and the full navbar for larger screens.
Peek 2022-09-10 13-06

from dash import html, Dash, dcc
import dash_mantine_components as dmc

app = Dash(__name__,
           external_stylesheets=[
               'https://use.fontawesome.com/releases/v5.8.1/css/all.css'
           ]
           )

app.layout = html.Div([
    dmc.MediaQuery([dmc.Navbar(
        fixed=True,
        width={"base": 250},
        height="100%",
        style={"top": 0},
        children=[
            dmc.Group(
                direction="column",
                grow=True,
                spacing="xl",
                children=[
                    dmc.List(
                        center=True,
                        children=[
                            dmc.ListItem(
                                dcc.Link('Home', href='/'),
                                icon=[
                                    html.I(className='fas fa-home fa-fw fa-lg')],
                                class_name='nav-list-items'),

                            dmc.ListItem(
                                dcc.Link('Data', href='/analytics'),
                                icon=[
                                    html.I(className='fas fa-chart-bar fa-fw fa-lg')],
                                class_name='nav-list-items'),

                            dmc.ListItem(
                                dcc.Link('Map', href='/map'),
                                icon=[
                                    html.I(className='fas fa-map fa-fw fa-lg')],
                                class_name='nav-list-items'),

                            dmc.ListItem(
                                dcc.Link('More Maps',
                                         href='/distro'),
                                icon=[
                                    html.I(className='fas fa-map-marker fa-fw fa-lg')],
                                class_name='nav-list-items'),
                        ])
                ])
        ])], smallerThan="md", styles={'display': 'none'}),
    dmc.MediaQuery([dmc.Navbar(
        fixed=True,
        width={"base": 60},
        height="100%",
        style={"top": 0},
        children=[
            dmc.List(
                center=True,
                children=[
                    dmc.ListItem(
                        dcc.Link(
                            html.I(className='fas fa-home fa-fw fa-lg'), href='/'),
                        class_name='nav-list-items'
                    ),
                    dmc.ListItem(
                        dcc.Link(
                            html.I(className='fas fa-chart-bar fa-fw fa-lg'), href='/'),
                        class_name='nav-list-items'
                    ),
                    dmc.ListItem(
                        dcc.Link(
                            html.I(className='fas fa-map fa-fw fa-lg'), href='/'),
                        class_name='nav-list-items'
                    ),
                    dmc.ListItem(
                        dcc.Link(
                            html.I(className='fas fa-map-marker fa-fw fa-lg'), href='/'),
                        class_name='nav-list-items'
                    )
                ])
        ])], largerThan="md", styles={'display': 'none'})
])

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

Inside your style.css file add:

body, .mantine-Header-root {
    background-color: #f2f4f6 !important;
} 

 .mantine-Navbar-root {
    background-color: #1f2937!important;
}

.mantine-Anchor-root {
    color: #fff!important;
}
.nav-list-items {
    padding: 1rem;
    color: #fff!important;
    text-decoration: none;
    list-style: none;
}

.nav-list-items:hover {
    color: #f2f4f6!important;
    background-color: #374151!important;
}

.mantine-Navbar-root a:-webkit-any-link{
    text-decoration: none;
    color: #f2f4f6 !important;
}

.mantine-Navbar-root ::marker{
    display: none;
}
7 Likes

@tphil10 This looks awesome :star_struck:
Thanks for sharing :slight_smile:

Hi @tphil10,

Thanks for sharing the Mantine example. I do use Mantine components a lot. However, I copied the code you shared and ran the script, it didn’t work like the GIP picture you showed🥲

Do I miss something or anything I should do?

@IvanLiu Hmm well that’s not good. What about it isn’t working? Is it throwing any errors?

Hi @tphil10 ,

Thanks for reply. The code worked fine and it didn’t show any error. However, the layout was so different from yours.:sweat_smile:

It looks like this:

Oh! Haha you are right, my apologies. I updated the css file to include the background color and such for those components. See if that works better.

2 Likes

Hello~

It looks better! Many thanks! Well… :sweat_smile: My sidebar doesn’t expand on hover. Do I miss something?

test

By the way, if I want to add graphs or cards on the right side of the page. Will you suggest create another Div element inside the app layout or shall I use like Container or Grid? Or is there any better way?

Thank you!