Search code examples
pythoncssbootstrap-4plotly-dashdash-bootstrap-components

Dash Bootstrap Components: Replace primary color across components


I am currently writing a Dash application, mostly using Dash Bootstrap Components. I am quite happy with the layout, but want to adjust the primary color to match my companies color scheme. In the picture below, I basically want to replace all the blue stuff with a different color.

Additional challenge is that due to the hosting environment, I am unfortunately limited to a single big Python file - I cannot have additional .css files.

I am using BOOTSTRAP_STYLESHEET = [dbc.themes.SPACELAB]. I know that I can replace single components' colors by using, e.g. style={'background-color':COMPANY_MAIN_COLOR}. Is there a way to instead replace SPACELAB's primary color with a different one? Or at least, to replace each component's default instead of having to do it manually for each component?

enter image description here


Solution

  • If you could add a css file I would go with that approach. Then you could simply overwrite the primary styles.

    But since you indicated that isn't an option, you could create a wrapper function for your button that sets a default background color style:

    MWE

    from dash import Dash, html, dcc
    import dash_bootstrap_components as dbc
    
    
    def CustomButton(*args, **kwargs):
        default_color = "green"
        default_color_light = "lightgreen"
        default_color_dark = "darkgreen"
        kwargs.setdefault("style", {"background-color": default_color, "background-image": "-webkit-gradient(linear, left top, left bottom, from(lightgreen), to(darkgreen))"})
        return dbc.Button(*args, **kwargs)
    
    
    app = Dash(external_stylesheets=[dbc.themes.SPACELAB])
    app.layout = html.Div(
        [
            dbc.Button("Primary", color="primary", className="me-1"),
            CustomButton("Primary", color="primary", className="me-1")
        ]
    )
    
    if __name__ == "__main__":
        app.run_server()
    

    result

    This only sets default values so you can overwrite the color by setting the style property. If you don't want the gradient by default you can remove the background-image part from the setdefault call.

    Update

    Alternatively you could overwrite the styles with css by Customizing Dash's HTML Index Template.

    The SPACELAB styles define a --primary css color variable, but it annoyingly doesn't use this variable anywhere. Different elements also might change the color in different ways so I don't think there's an easy catch-all way to do this. But you can use the following approach and add styles to it until it is as you want it to be

    from dash import Dash, html, dcc
    import dash_bootstrap_components as dbc
    
    app = Dash(external_stylesheets=[dbc.themes.SPACELAB])
    app.index_string = """
    <!DOCTYPE html>
    <html>
       <head>
           {%metas%}
           <title>{%title%}</title>
           {%favicon%}
           {%css%}
           <style>
               .btn-primary {
                  background-image: linear-gradient(red, blue);
               }
               .custom-control-input:checked ~ .custom-control-label::before {
                  border-color: red;
                  background-color: red;
               }
           </style>
       </head>
       <body>
           {%app_entry%}
           <footer>
               {%config%}
               {%scripts%}
               {%renderer%}
           </footer>
       </body>
    </html>
    """
    
    app.layout = html.Div(
        [
            dbc.Button("Primary", color="primary", className="me-1"),
            dbc.Checklist(
                options=[
                    {"label": "Option 1", "value": 1},
                    {"label": "Option 2", "value": 2},
                ],
                value=[1],
                id="switches",
                switch=True,
            ),
        ],
    )
    
    if __name__ == "__main__":
        app.run_server()