Dash Bootstrap, theme switcher?

Hello,

I loaded a dark theme in .css via Dash Bootstrap Component and created my app around dbc layout and I would like to create a switch between dark and theme. Is there a way to load another .css and easily switch from one to another ?
I’m aware of dash_daq.DarkThemeProvider | Dash for Python Documentation | Plotly but it will for sure require a lot of work to adapt new classes and I would like to not do it if there is another solution.
I also tried GitHub - tcbegley/dash-bootstrap-css: Bootstrap CSS for use with Plotly Dash
But based on the example it seems like that the theme switch is just limited to button and not all the background (from my tries on the example files)

My layout is pretty simple and consist of imbrication of dbc.Row and dbc.Col, with different type of figures inside.

PS : I’m using python

Thank you

1 Like

Hi @Feitan

I’ve managed to do this with a clientside callback - see minimal example below. But I wouldn’t recommend this for production because there is an annoying flash when the stylesheet is updated. I use this just to try out different themes.

As you already know, many Dash components don’t respond to Bootstrap themes without some manual css or some other changes to the component definition. For example - if you run the code below, you will see that the dropdown menu items are hard to read in dark themes. This can be fixed by adding some custom css to the assets folder or you can use one of the stylesheets you mentioned from @tcbegley (It does more than just buttons).

If you are with a company, Dash Enterprise has a Design Kit that looks pretty cool and makes it really easy to switch themes. You can check it out here: Branded Starter App


CSS to fix the dropdown:

.VirtualizedSelectOption {
   background-color: white;
   color: black;
}

.VirtualizedSelectFocusedOption {
   background-color: lightgrey;
   color: black;
}

import dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output

import dash_bootstrap_components as dbc

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


themes_list = [
    "BOOTSTRAP",
    "CYBORG",
    "DARKLY",
    "SLATE",
    "SOLAR",
    "SUPERHERO",
    "CERULEAN",
    "COSMO",
    "FLATLY",
    "JOURNAL",
    "LITERA",
    "LUMEN",
    "LUX",
    "MATERIA",
    "MINTY",
    "PULSE",
    "SANDSTONE",
    "SIMPLEX",
    "SKETCHY",
    "SPACELAB",
    "UNITED",
    "YETI",
]


dropdown = dcc.Dropdown(
    id="themes",
    options=[{"label": str(i), "value": i} for i in themes_list],
    value="BOOTSTRAP",
    clearable=False,
)

buttons = html.Div(
    [
        dbc.Button("Primary", color="primary", className="mr-1"),
        dbc.Button("Secondary", color="secondary", className="mr-1"),
        dbc.Button("Success", color="success", className="mr-1"),
        dbc.Button("Warning", color="warning", className="mr-1"),
        dbc.Button("Danger", color="danger", className="mr-1"),
        dbc.Button("Info", color="info", className="mr-1"),
        dbc.Button("Light", color="light", className="mr-1"),
        dbc.Button("Dark", color="dark", className="mr-1"),
        dbc.Button("Link", color="link"),
    ]
)

alerts = html.Div(
    [
        dbc.Alert("This is a primary alert", color="primary"),
        dbc.Alert("This is a secondary alert", color="secondary"),
        dbc.Alert("This is a success alert! Well done!", color="success"),
        dbc.Alert("This is a warning alert... be careful...", color="warning"),
    ]
)

"""
===============================================================================
Layout
"""
app.layout = dbc.Container(
    dbc.Row(
        [
            dbc.Col(["Select Theme", dropdown], width=3),
            dbc.Col([buttons, alerts]),
            html.Div(id="blank_output"),
        ],
    ),
    className="m-4",
    fluid=True,
)


app.clientside_callback(
    """
    function(theme) {
        var stylesheet = document.querySelector('link[rel=stylesheet][href^="https://stackpath"]')
        var name = theme.toLowerCase()
        if (name === 'bootstrap') {
            var link = 'https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css'
          } else {
            var link = "https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/" + name + "/bootstrap.min.css"
        }
        stylesheet.href = link
    }
    """,
    Output("blank_output", "children"),
    Input("themes", "value"),
)


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

Thank you very much @AnnMarieW, it works great !