Using a local .svg in a dash component

Hi! I want to be able to toggle between light and dark modes in my dash app, just as described in dbc themes. However, I want to be able to run my app on an offline machine. I’ve downloaded the stylesheets I need, and icons similar to those used in the example on the site referenced above (e.g. sun-fill), but I’m not sure about how to link the svg in the code. I’ve tried instantiating a dash.html.Img object like so:

sun = html.Img(src="../assets/sun.svg", className="my sun", style={"margin-right": "5px", "margin-left": "5px"}),

and the replacing the className value in the example’s Label to my variable’s className like so

dbc.Label(className="my sun", html_for="color-mode-switch"),

But this does not work. Could anyone help me out?

I don’t use DBC, but perhaps use src=“assets/sun.svg”?

Here’s what I use in DMC for my local (black & transparent) png icons for comparison:

dmc.Image(id="logo", src="assets/images/logo.png", className="invertible-image" )

I use a custom css class (invertible-image) to invert the coloring of the icons so they switch properly upon dark/light mode switch.

/* invert images in dark mode */
html[data-mantine-color-scheme='dark'] .invertible-image {
    -webkit-filter: invert(100%);
    filter: invert(100%);
}
/* invert images in light mode */
html[data-mantine-color-scheme='light'] .invertible-image {
    -webkit-filter: invert(0%);
    filter: invert(0%);
}
2 Likes

Thanks for your reply, @bweinberg, but the src path is not the issue. The actual switching between dark and light works well for me (I implemented it according to dbc color modes. It is only the rendering of the icons that I haven’t succeeded with.

The full implementation of the dark/light switch (gotten from dbc color modes) looks like this:

color_mode_switch =  html.Span(
    [
        dbc.Label(className="fa fa-moon"),
        dbc.Switch( id="switch", value=True, className="d-inline-block ms-1", persistence=True),
        dbc.Label(className="fa fa-sun", html_for="switch"),
    ]
)

I think I was on the wrong track with my use of the “className” argument in the original post. My latest attempt looked like this

sun = html.Img(src="../assets/sun-solid.svg")  # the asset folder is one level above the current file
moon = html.Img(src="../assets/moon-solid.svg")  

color_mode_switch =  html.Span(
    [
        dbc.Label(moon, style={"height": "1cm", 'width': '1cm'),  
        dbc.Switch(id="color-mode-switch", value=False, className="d-inline-block ms-1", persistence=True),
        dbc.Label(sun, style={"height": "1cm", 'width': '1cm'),
    ]
)

The “style” argument fixed it. The image must have been too big to render in the allocated space.

@AnnMarieW, do you know how to go about making the local icons respond to the color mode switch with dbc (like @bweinberg does with dmc)? (I found you through the dbc color modes site)

Hi @Ernie

Not sure exactly what you are looking for. That dbc switch doesn’t change the icons in the labels when switching from light to dark mode. The solution with css that @bweinberg is doing looks like it’s applying a filter in light and dark modes.

1 Like

Yea, my solution can invert the colors of images when a color switch is made (to make a dark image on a light background switch to a white icon on a dark background and vice versa). If you want to switch between two distinct svg images, you can write a callback to change what path string src is pointing to, or changing the children on the dbc.Label (sun to moon for instance).

2 Likes

I’m just trying to replicate the behaviour from the examples in bootstrap light/dark modes (where colors of the figures are inverted when using the switch), when running the code offline. The example only references one figure for each symbol, so I guess I won’t need 4 figures (2 versions of each icon) when doing this offline. I guess I need to do something similar to @bweinberg, the code just looked so unfamiliar to me. About time to learn some CSS, then. Thank you both!

Gotcha. I’m unfamiliar with how DBC does theming, so I can’t directly help finding the css solution. I would utilize your browser inspection tool to see what is changing during a light/dark mode switch. Also, look at utilizing some AI tools. VScode + Cline + Anthropic Sonnet 3.5 API has been working phenomenally for me, especially for building up the custom.css asset. Cursor and Aider are some other options.

1 Like

Can you post the .svg files you are using? I think I know a way to do this with a css variable, but I’d like to try it first :slight_smile:

1 Like

Sure! I cannot upload them as the .svg extension isn’t allowed, but here is the content of the files:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M361.5 1.2c5 2.1 8.6 6.6 9.6 11.9L391 121l107.9 19.8c5.3 1 9.8 4.6 11.9 9.6s1.5 10.7-1.6 15.2L446.9 256l62.3 90.3c3.1 4.5 3.7 10.2 1.6 15.2s-6.6 8.6-11.9 9.6L391 391 371.1 498.9c-1 5.3-4.6 9.8-9.6 11.9s-10.7 1.5-15.2-1.6L256 446.9l-90.3 62.3c-4.5 3.1-10.2 3.7-15.2 1.6s-8.6-6.6-9.6-11.9L121 391 13.1 371.1c-5.3-1-9.8-4.6-11.9-9.6s-1.5-10.7 1.6-15.2L65.1 256 2.8 165.7c-3.1-4.5-3.7-10.2-1.6-15.2s6.6-8.6 11.9-9.6L121 121 140.9 13.1c1-5.3 4.6-9.8 9.6-11.9s10.7-1.5 15.2 1.6L256 65.1 346.3 2.8c4.5-3.1 10.2-3.7 15.2-1.6zM160 256a96 96 0 1 1 192 0 96 96 0 1 1 -192 0zm224 0a128 128 0 1 0 -256 0 128 128 0 1 0 256 0z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M223.5 32C100 32 0 132.3 0 256S100 480 223.5 480c60.6 0 115.5-24.2 155.8-63.4c5-4.9 6.3-12.5 3.1-18.7s-10.1-9.7-17-8.5c-9.8 1.7-19.8 2.6-30.1 2.6c-96.9 0-175.5-78.8-175.5-176c0-65.8 36-123.1 89.3-153.3c6.1-3.5 9.2-10.5 7.7-17.3s-7.3-11.9-14.3-12.5c-6.3-.5-12.6-.8-19-.8z"/></svg>

Great, thanks for the advice! :grinning:

Update:
I’m using Pycharm, and tried using their AI Assistant for help. It suggested using a CSS class like you, @bweinberg, like so:

.inverted {
    filter: invert(1);
}

And tying that to the icons via the className argument in a Dash callback like so:

@app.callback(
    [Output("sun-icon", "className"), Output("moon-icon", "className")],
    Input("color-mode-switch", "value"),
)
def invert_icons(switch_value):
    if switch_value:
        return "", ""
    else:
        return "inverted", "inverted"  # apply the inverted class when the switch is False

This work! It also said it could be done without the CSS class, using inline CSS in the style argument of the Labels instead of the className argument, and modifying the style in the callback, but I went with the suggested way.

Hi @Ernie

Good that you found a solution! Instead of doing callbacks to update the className, you can do that using CSS:

sun = html.Img(src="assets/sun.svg",  className="dark-inverted")

Add this to the .css file in /assets

[data-bs-theme="dark"] {
  .dark-inverted {
     filter: invert(1);
  }
}

Note that you can also style things that only apply to light mode in a similar way using data-bs-theme="light"

Another option – if you would like to use any of the icons included in the dbc library off line – just copy the content of the file at the links and add it to a .css file in /assets

Find the links for your dbc version like this:

print(dbc.icons.FONT_AWESOME)
print(dbc.icons.BOOTSTRAP)

results:

https://use.fontawesome.com/releases/v6.3.0/css/all.css

https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css

3 Likes

That’s very helpful. Thank you, @AnnMarieW!

1 Like